.gitignore | 2 .mailmap | 1 code-coverage/pom.xml | 2 modules/cli-tests/pom.xml | 2 modules/common/ant-bundle/pom.xml | 2 modules/common/cassandra-ccm/cassandra-ccm-arquillian/pom.xml | 2 modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml | 2 modules/common/cassandra-ccm/cassandra-ccm-testng/pom.xml | 2 modules/common/cassandra-ccm/pom.xml | 2 modules/common/cassandra-installer/pom.xml | 2 modules/common/cassandra-jmx/pom.xml | 2 modules/common/cassandra-schema/pom.xml | 2 modules/common/cassandra-util/pom.xml | 2 modules/common/drift/pom.xml | 2 modules/common/filetemplate-bundle/pom.xml | 2 modules/common/jboss-as-dmr-client/pom.xml | 2 modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java | 23 modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/LoggingJBossASClient.java | 4 modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java | 109 modules/common/jboss-as/pom.xml | 2 modules/common/pom.xml | 2 modules/core/arquillian-integration/archive/pom.xml | 2 modules/core/arquillian-integration/container/pom.xml | 2 modules/core/arquillian-integration/pom.xml | 37 modules/core/arquillian-integration/suite-extension/pom.xml | 2 modules/core/arquillian-integration/test-agent-plugin/pom.xml | 2 modules/core/client-api/pom.xml | 2 modules/core/comm-api/pom.xml | 2 modules/core/dbutils/pom.xml | 2 modules/core/domain/pom.xml | 2 modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java | 31 modules/core/gui/pom.xml | 2 modules/core/native-system/pom.xml | 2 modules/core/plugin-api/pom.xml | 2 modules/core/plugin-container-itest/pom.xml | 2 modules/core/plugin-container/pom.xml | 2 modules/core/plugin-test-api/pom.xml | 131 modules/core/plugin-test-util/pom.xml | 2 modules/core/plugin-validator/pom.xml | 2 modules/core/plugindoc/pom.xml | 2 modules/core/pom.xml | 42 modules/core/util/pom.xml | 2 modules/enterprise/agent/pom.xml | 2 modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 38 modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateDownload.java | 32 modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateVersion.java | 33 modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java | 212 modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java | 3 modules/enterprise/agentupdate/pom.xml | 4 modules/enterprise/binding/pom.xml | 4 modules/enterprise/comm/pom.xml | 2 modules/enterprise/gui/content_http-war/pom.xml | 2 modules/enterprise/gui/coregui/pom.xml | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java | 1 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractD3GraphListView.java | 4 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java | 383 + modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/MetricNvd3BarChartGraph.java | 8 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphIE8Impl.java | 4 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java | 34 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/D3GroupGraphListView.java | 3 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java | 277 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java | 6 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java | 4 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/D3GraphListView.java | 3 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/MetricD3GraphView.java | 34 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java | 23 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/type/ResourceTypePluginTreeDataSource.java | 16 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 9 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ko.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties | 3 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties | 3 modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html | 18 modules/enterprise/gui/coregui/src/main/webapp/css/charts.css | 7 modules/enterprise/gui/coregui/src/main/webapp/css/nv.d3.css | 128 modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js | 2855 ++++++++-- modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js | 32 modules/enterprise/gui/pom.xml | 2 modules/enterprise/gui/portal-war/pom.xml | 2 modules/enterprise/gui/remoting-war/pom.xml | 2 modules/enterprise/gui/rest-examples-war/pom.xml | 2 modules/enterprise/gui/rest-war/pom.xml | 2 modules/enterprise/pom.xml | 2 modules/enterprise/remoting/cli/pom.xml | 2 modules/enterprise/remoting/client-api/pom.xml | 2 modules/enterprise/remoting/client-deps/pom.xml | 2 modules/enterprise/remoting/pom.xml | 2 modules/enterprise/scripting/api/pom.xml | 4 modules/enterprise/scripting/javascript/pom.xml | 4 modules/enterprise/scripting/pom.xml | 4 modules/enterprise/scripting/python/pom.xml | 4 modules/enterprise/server/appserver/pom.xml | 2 modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh | 3 modules/enterprise/server/appserver/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf | 9 modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc | 11 modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml | 30 modules/enterprise/server/client-api/pom.xml | 4 modules/enterprise/server/ear/pom.xml | 2 modules/enterprise/server/installer/pom.xml | 2 modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java | 30 modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerService.java | 17 modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java | 75 modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java | 250 modules/enterprise/server/itests-2/pom.xml | 2 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/client/security/test/ScriptingAPIServerTest.java | 4 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/auth/test/SubjectManagerBeanTest.java | 33 modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java | 5 modules/enterprise/server/jar/pom.xml | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java | 54 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java | 5 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java | 43 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java | 88 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java | 16 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/BadArgumentException.java | 5 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java | 26 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java | 185 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ParameterMissingException.java | 3 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ReportsHandlerBean.java | 20 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java | 27 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/SetCallerInterceptor.java | 7 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/StatusHandlerBean.java | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java | 57 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java | 24 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java | 10 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/helper/ConfigurationHelper.java | 432 + modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java | 756 ++ modules/enterprise/server/plugins/alert-cli/pom.xml | 4 modules/enterprise/server/plugins/alert-email/pom.xml | 4 modules/enterprise/server/plugins/alert-irc/pom.xml | 4 modules/enterprise/server/plugins/alert-log4j/pom.xml | 4 modules/enterprise/server/plugins/alert-microblog/pom.xml | 4 modules/enterprise/server/plugins/alert-mobicents/pom.xml | 4 modules/enterprise/server/plugins/alert-operations/pom.xml | 4 modules/enterprise/server/plugins/alert-roles/pom.xml | 4 modules/enterprise/server/plugins/alert-snmp/pom.xml | 4 modules/enterprise/server/plugins/alert-subject/pom.xml | 4 modules/enterprise/server/plugins/alertdef-rhq/pom.xml | 4 modules/enterprise/server/plugins/ant-bundle/pom.xml | 2 modules/enterprise/server/plugins/cobbler/pom.xml | 4 modules/enterprise/server/plugins/disk/pom.xml | 2 modules/enterprise/server/plugins/drift-rhq/pom.xml | 2 modules/enterprise/server/plugins/filetemplate-bundle/pom.xml | 2 modules/enterprise/server/plugins/jboss-software/pom.xml | 2 modules/enterprise/server/plugins/packagetype-cli/pom.xml | 4 modules/enterprise/server/plugins/pom.xml | 2 modules/enterprise/server/plugins/url/pom.xml | 2 modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml | 2 modules/enterprise/server/plugins/yum/pom.xml | 2 modules/enterprise/server/pom.xml | 2 modules/enterprise/server/safe-invoker/pom.xml | 2 modules/enterprise/server/sars/pom.xml | 2 modules/enterprise/server/sars/services-sar/pom.xml | 2 modules/enterprise/server/server-control/pom.xml | 2 modules/enterprise/server/server-metrics/pom.xml | 2 modules/enterprise/server/startup-subsystem/pom.xml | 2 modules/enterprise/server/xml-schemas/pom.xml | 2 modules/helpers/bundleGen/pom.xml | 4 modules/helpers/jeeGen/pom.xml | 2 modules/helpers/perftest-support/pom.xml | 4 modules/helpers/pom.xml | 2 modules/helpers/rest-docs-generator/pom.xml | 2 modules/helpers/rtfilter-subsystem/pom.xml | 2 modules/helpers/rtfilter/pom.xml | 2 modules/integration-tests/apache-plugin-test/pom.xml | 2 modules/integration-tests/jndi-access/jndi-access-test/pom.xml | 2 modules/integration-tests/jndi-access/pom.xml | 2 modules/integration-tests/jndi-access/remote-server/pom.xml | 2 modules/integration-tests/pom.xml | 2 modules/integration-tests/rest-api/pom.xml | 2 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java | 22 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java | 67 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java | 188 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java | 118 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java | 2 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/AlertDefinition.java | 21 modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Resource.java | 9 modules/plugins/aliases/pom.xml | 2 modules/plugins/ant-bundle/pom.xml | 2 modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java | 17 modules/plugins/apache/pom.xml | 2 modules/plugins/augeas/pom.xml | 2 modules/plugins/byteman/pom.xml | 2 modules/plugins/cassandra/pom.xml | 2 modules/plugins/cobbler/pom.xml | 2 modules/plugins/cron/pom.xml | 2 modules/plugins/database/pom.xml | 2 modules/plugins/filetemplate-bundle/pom.xml | 2 modules/plugins/grub/pom.xml | 2 modules/plugins/hadoop/pom.xml | 2 modules/plugins/hibernate/pom.xml | 2 modules/plugins/hosts/pom.xml | 2 modules/plugins/hudson/pom.xml | 4 modules/plugins/iis/pom.xml | 2 modules/plugins/irc/pom.xml | 2 modules/plugins/jboss-as-5/pom.xml | 50 modules/plugins/jboss-as-7/pom.xml | 57 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java | 13 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 3 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 35 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java | 36 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java | 10 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java | 8 modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 16 modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java | 14 modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java | 74 modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java | 239 modules/plugins/jboss-as/pom.xml | 2 modules/plugins/jboss-cache-v3/pom.xml | 2 modules/plugins/jboss-cache/pom.xml | 2 modules/plugins/jmx/pom.xml | 2 modules/plugins/kickstart/pom.xml | 2 modules/plugins/mod-cluster/pom.xml | 2 modules/plugins/mysql/pom.xml | 2 modules/plugins/netservices/pom.xml | 2 modules/plugins/noop/pom.xml | 2 modules/plugins/oracle/pom.xml | 2 modules/plugins/pattern-generator/pom.xml | 2 modules/plugins/perftest/pom.xml | 2 modules/plugins/platform/pom.xml | 2 modules/plugins/pom.xml | 2 modules/plugins/postfix/pom.xml | 2 modules/plugins/postgres/pom.xml | 2 modules/plugins/rhq-agent/pom.xml | 2 modules/plugins/rhq-server/pom.xml | 2 modules/plugins/samba/pom.xml | 2 modules/plugins/script/pom.xml | 2 modules/plugins/script2/pom.xml | 2 modules/plugins/snmptrapd/pom.xml | 2 modules/plugins/sshd/pom.xml | 2 modules/plugins/sudoers/pom.xml | 2 modules/plugins/tomcat/pom.xml | 2 modules/plugins/twitter/pom.xml | 2 modules/plugins/validate-all-plugins/pom.xml | 2 modules/plugins/virt/pom.xml | 2 modules/pom.xml | 2 modules/test-utils/pom.xml | 2 pom.xml | 2 245 files changed, 6290 insertions(+), 1863 deletions(-)
New commits: commit 7e570be5b32b3547d3e3861ff24c4527d224ee36 Merge: 4f431e5 01d875b Author: John Sanda jsanda@redhat.com Date: Fri May 10 14:30:53 2013 -0400
Merge branch 'master' into feature/cassandra-backend
Conflicts: modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-autoinstall.sh modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc modules/plugins/cassandra/pom.xml
diff --cc modules/common/cassandra-ccm/cassandra-ccm-arquillian/pom.xml index a140bef,0000000..ce6b7ac mode 100644,000000..100644 --- a/modules/common/cassandra-ccm/cassandra-ccm-arquillian/pom.xml +++ b/modules/common/cassandra-ccm/cassandra-ccm-arquillian/pom.xml @@@ -1,33 -1,0 +1,33 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-cassandra-ccm</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-ccm-arquiliian</artifactId> + <name>RHQ Cassandra CCM Arquillian</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-schema</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.container</groupId> + <artifactId>arquillian-container-test-impl-base</artifactId> + </dependency> + </dependencies> +</project> diff --cc modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml index a83600f,0000000..74a0775 mode 100644,000000..100644 --- a/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml +++ b/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml @@@ -1,327 -1,0 +1,327 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-cassandra-ccm</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-ccm-core</artifactId> + <name>RHQ Cassandra CCM Core</name> + + <properties> + <local.repo>${settings.localRepository}</local.repo> + <cassandra.jna.version>3.5.1</cassandra.jna.version> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-plugin-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-jmx</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <groupId>com.sun</groupId> + <artifactId>rt</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.apache.cassandra</groupId> + <artifactId>cassandra-thrift</artifactId> + <version>${cassandra.version}</version> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>com.datastax.cassandra</groupId> + <artifactId>cassandra-driver-core</artifactId> + <version>${cassandra.driver.version}</version> + </dependency> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna</artifactId> + <version>${cassandra.jna.version}</version> + </dependency> + + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>platform</artifactId> + <version>${cassandra.jna.version}</version> + </dependency> + + <dependency> + <groupId>com.googlecode.java-diff-utils</groupId> + <artifactId>diffutils</artifactId> + <version>1.2.1</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + <resource> + <directory>src/main/bundle</directory> + <filtering>false</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <configuration> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <excludes> + <exclude>src/main/resources/cassandra/conf/cassandra-env.sh</exclude> + </excludes> + </resource> + <!--<resource>--> + <!--<directory>src/main/cassandra/cql</directory>--> + <!--</resource>--> + </resources> + <delimiters> + <delimiter>${*}</delimiter> + </delimiters> + <escapeString>[escape]</escapeString> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <!-- + This execution is a place holder or stub to do some pre-processing before + packaging up the bundle. See the snappy-mac-workaround profile below for more + details. + --> + <id>setup-pkg</id> + </execution> + <execution> + <id>get-cassandra</id> + <phase>generate-resources</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <property name="cassandra.download.dir" + value="${project.build.directory}/cassandra-download"/> + <mkdir dir="${cassandra.download.dir}"/> + <mkdir dir="${settings.localRepository}/org/apache/cassandra/apache-cassandra/${cassandra.version}"/> + <get src="http://repo1.maven.org/maven2/org/apache/cassandra/apache-cassandra/$%7Bcass..." + dest="${settings.localRepository}/org/apache/cassandra/apache-cassandra/${cassandra.version}/apache-cassandra-${cassandra.version}-bin.tar.gz" + skipexisting="true" + verbose="true"/> + <gunzip src="${settings.localRepository}/org/apache/cassandra/apache-cassandra/${cassandra.version}/apache-cassandra-${cassandra.version}-bin.tar.gz" + dest="${cassandra.download.dir}"/> + <untar src="${cassandra.download.dir}/apache-cassandra-${cassandra.version}-bin.tar" + dest="${cassandra.download.dir}"/> + <move file="${cassandra.download.dir}/apache-cassandra-${cassandra.version}" + tofile="${project.build.outputDirectory}/cassandra-${cassandra.version}"/> + <delete dir="${cassandra.download.dir}"/> + </target> + </configuration> + </execution> + <execution> + <id>create-cassandra-pkg</id> + <phase>prepare-package</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <property name="cassandra.dir" + value="${project.build.outputDirectory}/cassandra-${cassandra.version}"/> + <property name="cassandra.distro.filename" value="cassandra.zip"/> + <property name="cassandra.distro.zip" + value="${project.build.outputDirectory}/${cassandra.distro.filename}"/> + <copy file="${settings.localRepository}/net/java/dev/jna/platform/${cassandra.jna.version}/platform-${cassandra.jna.version}.jar" + todir="${cassandra.dir}/lib"/> + <copy file="${settings.localRepository}/net/java/dev/jna/jna/${cassandra.jna.version}/jna-${cassandra.jna.version}.jar" + todir="${cassandra.dir}/lib"/> + <move file="${project.build.outputDirectory}/cassandra/conf" todir="${cassandra.dir}"/> + <delete dir="${cassandra.dir}/javadoc"/> + <zip basedir="${cassandra.dir}" destfile="${cassandra.distro.zip}"/> + <delete dir="${cassandra.dir}"/> + <delete file="${project.build.outputDirectory}/deploy.xml"/> + <!--<delete dir="${project.build.outputDirectory}/cassandra"/>--> + </target> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludes> + <exclude>**/*ITest.java</exclude> + </excludes> + </configuration> + </plugin> + <plugin> + <artifactId>maven-failsafe-plugin</artifactId> + <version>2.13</version> + <executions> + <execution> + <id>integration-test</id> + <goals> + <goal>integration-test</goal> + </goals> + <configuration> + <includes> + <include>**/*ITest.java</include> + </includes> + <systemPropertyVariables> + <rhq.storage.deploy-dir>${project.build.directory}/rhq-storage</rhq.storage.deploy-dir> + </systemPropertyVariables> + </configuration> + </execution> + <execution> + <id>verify</id> + <goals> + <goal>verify</goal> + </goals> + <configuration> + <testFailureIgnore>false</testFailureIgnore> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>dev</id> + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/${rhq.earLibDir}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}"/> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + </plugins> + </build> + </profile> + + <!-- + Cassandra uses the snappy-java compression library, and it uses a native library that + is packaged in the snappy-java JAR. Running on Mac OS X with Java 7 will result in, + + NoClassDefFoundError Could not initialize class org.xerial.snappy.Snappy + + due to the file name extension that the Java 7 JVM looks for on Mac OS X. This issue + was logged and fixed under https://github.com/xerial/snappy-java/issues/6. Cassandra + however does not yet bundle a newer version of snappy-java. This profile is activated + when running on Mac OS X and replaces the packaged version of snappy-java with a newer + version so that snappy compression can still be used during development. Note that + this is **not** an issue when running on Java 6. + + - jsanda 10/03/2012 + --> + <profile> + <id>snappy-mac-workaround</id> + <activation> + <os> + <family>Mac</family> + </os> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <inherited>false</inherited> + <dependencies> + <dependency> + <groupId>org.xerial.snappy</groupId> + <artifactId>snappy-java</artifactId> + <version>1.1.0-M3</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>setup-pkg-mac</id> + <phase>process-resources</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <target> + <property name="cassandra.dir" + value="${project.build.outputDirectory}/cassandra-${cassandra.version}"/> + <property name="cassandra.lib.dir" value="${cassandra.dir}/lib"/> + <property name="snappy.jar.original" value="${cassandra.lib.dir}/snappy-java-1.0.4.1.jar"/> + <property name="snappy.jar.updated" + value="${local.repo}/org/xerial/snappy/snappy-java/${cassandra.driver.snappy.version}/snappy-java-${cassandra.driver.snappy.version}.jar"/> + <delete file="${snappy.jar.original}"/> + <copy file="${snappy.jar.updated}" todir="${cassandra.lib.dir}"/> + </target> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --cc modules/common/cassandra-ccm/cassandra-ccm-testng/pom.xml index 7d62c1e,0000000..93b578d mode 100644,000000..100644 --- a/modules/common/cassandra-ccm/cassandra-ccm-testng/pom.xml +++ b/modules/common/cassandra-ccm/cassandra-ccm-testng/pom.xml @@@ -1,34 -1,0 +1,34 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-cassandra-ccm</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-ccm-testng</artifactId> + <name>RHQ Cassandra CCM TestNG</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-schema</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>${testng.version}</version> + </dependency> + </dependencies> +</project> diff --cc modules/common/cassandra-ccm/pom.xml index e2c3db7,0000000..c9db0f6 mode 100644,000000..100644 --- a/modules/common/cassandra-ccm/pom.xml +++ b/modules/common/cassandra-ccm/pom.xml @@@ -1,22 -1,0 +1,22 @@@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + <parent> + <artifactId>rhq-common-parent</artifactId> + <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>rhq-cassandra-ccm</artifactId> + <name>RHQ Cassandra CCM Parent</name> + <packaging>pom</packaging> + + <modules> + <module>cassandra-ccm-core</module> + <module>cassandra-ccm-testng</module> + <module>cassandra-ccm-arquillian</module> + <module>cassandra-ccm-maven-plugin</module> + </modules> +</project> diff --cc modules/common/cassandra-installer/pom.xml index 7919a29,0000000..1263c75 mode 100644,000000..100644 --- a/modules/common/cassandra-installer/pom.xml +++ b/modules/common/cassandra-installer/pom.xml @@@ -1,162 -1,0 +1,162 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-installer</artifactId> + <name>RHQ Cassandra Installer</name> + + <properties> + <moduleName>org.rhq.${project.artifactId}</moduleName> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-exec</artifactId> + <version>1.1</version> + </dependency> + + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.1</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptors> + <descriptor>src/main/scripts/module-assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>module-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-deps</id> + <phase>prepare-package</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}/dependencies</outputDirectory> + <artifactItems> + <artifactItem> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + </artifactItem> + <artifactItem> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-util</artifactId> + <version>${project.version}</version> + </artifactItem> + <artifactItem> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-jmx</artifactId> + <version>${project.version}</version> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/modules/org/rhq/rhq-cassandra-installer/main</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --cc modules/common/cassandra-jmx/pom.xml index 26fb831,0000000..3c957c9 mode 100644,000000..100644 --- a/modules/common/cassandra-jmx/pom.xml +++ b/modules/common/cassandra-jmx/pom.xml @@@ -1,28 -1,0 +1,28 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-jmx</artifactId> + <name>RHQ Cassandra JMX Utility</name> + + <properties> + <moduleName>org.rhq.${project.artifactId}</moduleName> + </properties> + + <dependencies> + <dependency> + <groupId>com.sun</groupId> + <artifactId>rt</artifactId> + <version>1.6.0</version> + <scope>system</scope> + <systemPath>${java.home}/lib/rt.jar</systemPath> + </dependency> + </dependencies> +</project> diff --cc modules/common/cassandra-schema/pom.xml index 4651a7e,0000000..e4f735d mode 100644,000000..100644 --- a/modules/common/cassandra-schema/pom.xml +++ b/modules/common/cassandra-schema/pom.xml @@@ -1,87 -1,0 +1,87 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-schema</artifactId> + <name>RHQ Cassandra Schema</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-util</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.datastax.cassandra</groupId> + <artifactId>cassandra-driver-core</artifactId> + <version>${cassandra.driver.version}</version> + </dependency> + </dependencies> + + <profiles> + <profile> + <id>dev</id> + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/${rhq.earLibDir}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}"/> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --cc modules/common/cassandra-util/pom.xml index fc67140,0000000..8e48608 mode 100644,000000..100644 --- a/modules/common/cassandra-util/pom.xml +++ b/modules/common/cassandra-util/pom.xml @@@ -1,75 -1,0 +1,75 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <artifactId>rhq-cassandra-util</artifactId> + <name>RHQ Cassandra Util</name> + + <dependencies> + <dependency> + <groupId>com.datastax.cassandra</groupId> + <artifactId>cassandra-driver-core</artifactId> + <version>${cassandra.driver.version}</version> + </dependency> + </dependencies> + + <profiles> + <profile> + <id>dev</id> + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/${rhq.earLibDir}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}"/> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --cc modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml index c6ac637,05619cb..fe809be --- a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml @@@ -742,74 -621,23 +743,54 @@@ rhq.casandra.native-transport-max-threa <copy todir="${project.build.outputDirectory}" verbose="true"> <fileset dir="src/main/dev-resources" /> </copy> + <loadproperties> + <zipentry zipfile="${settings.localRepository}/org/rhq/rhq-cassandra-ccm-core/${project.version}/rhq-cassandra-ccm-core-${project.version}.jar" + name="cassandra.properties"/> + </loadproperties> <echo>Putting a developer setting in rhq-server.properties to turn on/off strict agent update version checking</echo> - <echo file="${project.build.outputDirectory}/bin/rhq-server.properties" append="true">rhq.server.agent-update.nonstrict-version-check=true</echo> - <echo>Add auto-installer to rhq-server scripts so developers don't have to run the installer in a separate step</echo> - <replace file="${project.build.outputDirectory}/bin/rhq-server.sh"> - <replacefilter> - <replacetoken># START SERVER</replacetoken> - <replacevalue><![CDATA[export RHQ_SERVER_HOME; ${RHQ_SERVER_HOME}/bin/rhq-autoinstall.sh &]]></replacevalue> - </replacefilter> - </replace> - <replace file="${project.build.outputDirectory}/bin/rhq-server.bat"> - <replacefilter> - <replacetoken>rem START SERVER</replacetoken> - <replacevalue><![CDATA[start /B %RHQ_SERVER_HOME%\bin\rhq-autoinstall.bat < nul > nul]]></replacevalue> - </replacefilter> - </replace> + <echo file="${project.build.outputDirectory}/bin/rhq-server.properties" append="true"> +rhq.server.agent-update.nonstrict-version-check=true + +# Accepts a value of true or false and specifies whether or not the cluster is embedded. +# Note that if this property is set to false, the other, remaining cluster configuration +# properties that are set will be ignored as they are only used with embedded clusters. +rhq.cassandra.cluster.is-embedded=${rhq.cassandra.cluster.is-embedded} + +# The directory in which cluster nodes will be installed. +rhq.cassandra.cluster.dir=${rhq.cassandra.cluster.dir} + +# Used for both the min and max heap sizes for the Cassandra JVM. Defaults to 512 MB. When +# you change this property you should also change the rhq.cassandra.heap.new.size property +# accordingly. +# rhq.cassandra.max.heap.size= + +# Heap new size refers to the size of the young generation. Defaults to 128 MB. When +# you change this property you should also change the rhq.cassandra.max.heap.size property +# accordingly. Note that this value must be smaller than rhq.cassandra.max.heap.size. +# rhq.cassandra.heap.new.size= + +# The number of nodes in the cluster. This specifies how many nodes to install +# and configure. The top level or base directory for each node will be nodeN +# where N is the node number. +rhq.cassandra.cluster.num-nodes=${rhq.cassandra.cluster.num-nodes} + +# The log4j logging level to use on each node. +rhq.cassandra.logging.level=${rhq.cassandra.logging.level} +</echo> + +<echo file="${project.build.outputDirectory}/bin/rhq-storage.properties" append="true"># storage installer options for dev deployment +hostname=127.0.0.1 +commitlog=${rhq.dev.data.dir}/storage/commit_log +data=${rhq.dev.data.dir}/storage/data +saved-caches=${rhq.dev.data.dir}/storage/saved_caches +heap-size=256M +heap-new-size=64M +</echo> + +<echo file="${project.build.outputDirectory}/bin/rhqctl.properties" append="true">rhqctl.install.storage-config=bin/rhq-storage.properties</echo> + </target>
- <!-- This is so we can work around all the issues due to https://issues.jboss.org/browse/AS7-6120 - so once that is fixed, we don't have to run the installer "reconfig" automatically on startup of the server. - Note that if we predeploy (i.e. are doing a dev build), rather than jump through more hoops for this, - just assume the developer knows that if they change rhq-server.properties, they have to reconfig the server. - We don't do anything in this target if we are building a dev build. --> - <target name="add-auto-reconfig" unless="predeploy"> - <echo>Add auto-reconfig to rhq-server scripts so users don't have to when changing rhq-server.properties</echo> - <replace file="${project.build.outputDirectory}/bin/rhq-server.sh"> - <replacefilter> - <replacetoken># START SERVER</replacetoken> - <replacevalue><![CDATA[export RHQ_SERVER_HOME; ${RHQ_SERVER_HOME}/bin/rhq-installer.sh --reconfig &]]></replacevalue> - </replacefilter> - </replace> - <replace file="${project.build.outputDirectory}/bin/rhq-server.bat"> - <replacefilter> - <replacetoken>rem START SERVER</replacetoken> - <replacevalue><![CDATA[start /B %RHQ_SERVER_HOME%\bin\rhq-installer.bat --reconfig < nul > nul]]></replacevalue> - </replacefilter> - </replace> - </target> <target name="prepare-release" description="If this is a release build, make sure it is properly prepared." depends="initialize, diff --cc modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java index 336aafb,6689de5..9bd0f2c --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java @@@ -20,13 -20,7 +20,11 @@@
package org.rhq.enterprise.server.test;
+import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + import javax.ejb.Singleton; - import javax.ejb.TransactionAttribute; - import javax.ejb.TransactionAttributeType;
import org.rhq.enterprise.server.core.StartupBean; import org.rhq.enterprise.server.naming.NamingHack; diff --cc modules/enterprise/server/plugins/alertdef-rhq/pom.xml index 842aabf,0000000..edf7ba4 mode 100644,000000..100644 --- a/modules/enterprise/server/plugins/alertdef-rhq/pom.xml +++ b/modules/enterprise/server/plugins/alertdef-rhq/pom.xml @@@ -1,132 -1,0 +1,132 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq</groupId> + <artifactId>serverplugin-alertdef-rhq</artifactId> + <packaging>jar</packaging> + + <name>RHQ Alert Definition Server Plugin</name> + <description>Server side plugin providing RHQ Alert Definition Injection</description> + + <dependencies> + + <!-- Internal Deps --> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-domain</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-core-client-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>${jacoco.unit-test.args} -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/${rhq.serverPluginDir}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy-jar-meta-inf</id> + <phase>package</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating META-INF dir in ${deployment.file}...</echo> + <unjar src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.outputDirectory}"> + <patternset> + <include name="META-INF/**" /> + </patternset> + </unjar> + <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true"> + </jar> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + </profiles> + - </project> ++</project> diff --cc modules/enterprise/server/server-control/pom.xml index 11c1f92,0000000..33d1bd8 mode 100644,000000..100644 --- a/modules/enterprise/server/server-control/pom.xml +++ b/modules/enterprise/server/server-control/pom.xml @@@ -1,158 -1,0 +1,158 @@@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + <relativePath>../../../../pom.xml</relativePath> + </parent> + + <artifactId>rhq-server-control</artifactId> + <name>RHQ Server Control</name> + <packaging>jar</packaging> + + <properties> + <moduleName>org.rhq.${project.artifactId}</moduleName> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-util</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.2</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-exec</artifactId> + <version>1.1</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>1.6</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptors> + <descriptor>src/main/scripts/module-assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>module-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-deps</id> + <phase>prepare-package</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}/dependencies</outputDirectory> + <artifactItems> + <artifactItem> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-util</artifactId> + <version>${project.version}</version> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/modules/org/rhq/rhq-server-control/main</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> + +</project> diff --cc modules/enterprise/server/server-metrics/pom.xml index 42f6216,0000000..c1b73d8 mode 100644,000000..100644 --- a/modules/enterprise/server/server-metrics/pom.xml +++ b/modules/enterprise/server/server-metrics/pom.xml @@@ -1,319 -1,0 +1,319 @@@ +<!-- + ~ /* + ~ * 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, version 2, as + ~ * published by the Free Software Foundation, and/or the GNU Lesser + ~ * General Public License, version 2.1, also as published by the Free + ~ * Software Foundation. + ~ * + ~ * This program is distributed in the hope that it will be useful, + ~ * but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ~ * GNU General Public License and the GNU Lesser General Public License + ~ * for more details. + ~ * + ~ * You should have received a copy of the GNU General Public License + ~ * and the GNU Lesser General Public License along with this program; + ~ * if not, write to the Free Software Foundation, Inc., + ~ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ~ */ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> ++ <version>4.8.0-SNAPSHOT</version> + <relativePath>../../../../pom.xml</relativePath> + </parent> + + <artifactId>rhq-server-metrics</artifactId> + <name>RHQ Server Metrics</name> + + <properties> + <skipClusterShutdown>false</skipClusterShutdown> + <clusterDir>${project.build.directory}/cassandra</clusterDir> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-core</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <groupId>org.apache.cassandra</groupId> + <artifactId>cassandra-clientutil</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-cassandra-ccm-testng</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-core-domain</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>test-utils</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-nop</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.hibernate.javax.persistence</groupId> + <artifactId>hibernate-jpa-2.0-api</artifactId> + </dependency> + + <dependency> + <groupId>com.datastax.cassandra</groupId> + <artifactId>cassandra-driver-core</artifactId> + <version>${cassandra.driver.version}</version> + </dependency> + + <!--<dependency>--> + <!--<groupId>org.apache.cassandra</groupId>--> + <!--<artifactId>cassandra-all</artifactId>--> + <!--<version>${cassandra.version}</version>--> + <!--<exclusions>--> + <!--<exclusion>--> + <!--<groupId>org.slf4j</groupId>--> + <!--<artifactId>slf4j-log4j12</artifactId>--> + <!--</exclusion>--> + <!--<exclusion>--> + <!--<groupId>org.slf4j</groupId>--> + <!--<artifactId>slf4j-api</artifactId>--> + <!--</exclusion>--> + <!--<exclusion>--> + <!--<groupId>log4j</groupId>--> + <!--<artifactId>log4j</artifactId>--> + <!--</exclusion>--> + <!--</exclusions>--> + <!--</dependency>--> + + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>1.7.1</version> + </dependency> + + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <dependency> + <groupId>postgresql</groupId> + <artifactId>postgresql</artifactId> + <!-- NOTE: version defined in root pom dependencyManagement section --> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-entitymanager</artifactId> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-testng</artifactId> + <version>${powermock.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>${powermock.version}</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <rhq.cassandra.cluster.skip-shutdown>${skipClusterShutdown}</rhq.cassandra.cluster.skip-shutdown> + <rhq.cassandra.cluster.dir>${rhq.cassandra.cluster.dir}</rhq.cassandra.cluster.dir> + </systemPropertyVariables> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + <archive> + <manifest> + <mainClass>org.rhq.server.metrics.migrator.DataMigratorRunner</mainClass> + <addClasspath>true</addClasspath> + </manifest> + </archive> + </configuration> + <executions> + <execution> + <id>package-jar-with-dependencies</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <attach>false</attach> + <finalName>migrator-executable/data-migrator-${project.version}</finalName> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <!-- + Temporarily commenting out dev profile. The data migrator self-executing JAR was + getting deployed to the EAR and causing the EAR deployment to fail. I think the + assembly might need to be moved outside of the dev profile. + --> + <profile> + <id>dev</id> + <properties> + <rhq.rootDir>../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/${rhq.earLibDir}</rhq.deploymentDir> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>deploy</id> + <phase>package</phase> + <configuration> + <target> + <mkdir dir="${rhq.deploymentDir}"/> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <target> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar"/> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}"/> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <id>oracle</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + + <dependencies> + <!-- Oracle JDBC driver - required only if you want to run the tests, or dbsetup, against Oracle. + Add a top level dependency if this profile is active to allow for db-required tests in any module. + The driver can not be packaged for OpenSource distributions due to licensing issues, and as such, + this profile should not be active by default. --> + <dependency> + <groupId>com.oracle</groupId> + <artifactId>ojdbc6</artifactId> + <version>${ojdbc6.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + <archive> + <manifest> + <mainClass>org.rhq.server.metrics.migrator.DataMigratorRunner</mainClass> + <addClasspath>true</addClasspath> + </manifest> + </archive> + </configuration> + <executions> + <execution> + <id>package-jar-with-dependencies</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <attach>false</attach> + <finalName>migrator-executable/data-migrator-oracle-${project.version}</finalName> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project>
commit 01d875b284d842df2ac4f099598b5f2a5f320bf2 Author: Heiko W. Rupp hwr@redhat.com Date: Fri May 10 16:34:51 2013 +0200
Provide the old method signature as fallback in case other plugins that inherit from this one, still need it.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java index 9eb63f9..48fbf1f 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java @@ -53,12 +53,23 @@ public enum JBossProductType { }
/** + * Determine the product type of a JBoss install. This implies an api version of 1.x which + * is a JBossAS 7.x + * @param homeDir the JBoss product installation directory (e.g. /opt/jboss-as-7.1.1.Final) + * @return the product type + * @deprecated "Use the version with the apiVersion" + */ + @Deprecated + public static JBossProductType determineJBossProductType(File homeDir) { + return determineJBossProductType(homeDir,"1.0"); + } + + /** * Determines the product type of a JBoss product installation. * - * * @param homeDir the JBoss product installation directory (e.g. /opt/jboss-as-7.1.1.Final) * - * @param apiVersion + * @param apiVersion Api version of the domain api. * @return the product type */ public static JBossProductType determineJBossProductType(File homeDir, String apiVersion) {
commit 3bba88c36f7d4a91ac5ac824c0e5b7fd43c3dd0b Author: Heiko W. Rupp hwr@redhat.com Date: Fri May 10 14:39:21 2013 +0200
BZ 961787 - try to determine AS/WFLY via domain api version before falling back to directory names, as this is more reliable.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java index 9a4d5bd..cc13406 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java @@ -193,7 +193,8 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent serverPluginConfig.setHostname(managementHostPort.host); serverPluginConfig.setPort(managementHostPort.port); pluginConfig.setSimpleValue("realm", hostConfig.getManagementSecurityRealm()); - JBossProductType productType = JBossProductType.determineJBossProductType(homeDir); + String apiVersion = hostConfig.getDomainApiVersion(); + JBossProductType productType = JBossProductType.determineJBossProductType(homeDir, apiVersion); serverPluginConfig.setProductType(productType); pluginConfig.setSimpleValue("hostXmlFileName", getHostXmlFileName(commandLine));
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java index 9edfb2f..9eb63f9 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JBossProductType.java @@ -37,7 +37,7 @@ public enum JBossProductType { JPP("JPP", "JBoss EAP 6", "JBoss Portal Platform 6", "Portal Platform"), // EWP("EWP", "JBoss EWP 6", "JBoss Enterprise Web Platform 6", "EWP"), SOA("SOA-P", "JBoss SOA-P 6", "JBoss Enterprise SOA Platform (ESB)", "SOAP"), - WILDFLY8("WildFly","WildFly 8" ,"WildFly Appliction Server 8" , "WildFly"); + WILDFLY8("WildFly","WildFly 8" ,"WildFly Application Server 8" , "WildFly");
public final String SHORT_NAME; public final String NAME; @@ -55,13 +55,28 @@ public enum JBossProductType { /** * Determines the product type of a JBoss product installation. * + * * @param homeDir the JBoss product installation directory (e.g. /opt/jboss-as-7.1.1.Final) * + * @param apiVersion * @return the product type */ - public static JBossProductType determineJBossProductType(File homeDir) { + public static JBossProductType determineJBossProductType(File homeDir, String apiVersion) { try { - return determineJBossProductTypeViaProductConfFile(homeDir); + JBossProductType jBossProductType = determineJBossProductTypeViaProductConfFile(homeDir); + if (jBossProductType==null) { + // Wildfly and The Server Formerly Known AS JBossAS share the same absence of a slot + // and thus have no product type. So we need to check differently + // AS 7.0/1 use a domain api version of 1.x, while WildFly uses version 2.0+ + // like 2.0 in "urn:jboss:domain:2.0" from <server xmlns="..." > element in standalone.xml + if (apiVersion.startsWith("1")) { + jBossProductType = JBossProductType.AS; + } else { + // We should later check for newer WildFly versions to differentiate them + jBossProductType = JBossProductType.WILDFLY8; + } + } + return jBossProductType; } catch (Exception e) { // TODO: Log an error. return determineJBossProductTypeViaHomeDirName(homeDir); @@ -109,9 +124,7 @@ public enum JBossProductType { throw new RuntimeException("Unknown product type: " + slot); } } else { - // Wildfly and The Server Formerly Known AS JBossAS share the same absence of a slot - // so we need another way to distinguish them - productType = determineJBossProductTypeViaHomeDirName(homeDir); + productType = null; }
return productType; diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java index a8909ff..329246e 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java @@ -233,6 +233,14 @@ public class HostConfiguration { return securityPropertyFile; }
+ public String getDomainApiVersion() { + + String version = document.getFirstChild().getAttributes().getNamedItem("xmlns").getTextContent(); + + version = version.substring(version.lastIndexOf(':')+1); + return version; + } + /** * Run the passed xpathExpression on the prepopulated hostXml document and * return the target element or attribute as a String.
commit 8868d16074902e9996f00cce8db697d02fce21ad Author: Heiko W. Rupp hwr@redhat.com Date: Fri May 10 12:18:26 2013 +0200
BZ 960959 apply inventory status filtering with COMMITTED as default for searches.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java index 138ca40..2dde3a4 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java @@ -52,7 +52,7 @@ public abstract class Criteria implements Serializable, BaseCriteria { * Use this to get the global fields for this Criteria field type. Don't use inspection as the field names * for this abstract base class do not conform (for legacy reasons) to the prefix convention help by the * subclasses. - * + * * @return The set of global fields for this Criteria field type. Meaning, usable by all subclasses. */ public List<String> getGlobalFields() { @@ -76,7 +76,7 @@ public abstract class Criteria implements Serializable, BaseCriteria { * private NonBindingOverrideFilter filterResourceOnly; // requires overrides - finds only those associated with a resource * ... * filterOverrides.put("resourceTypeOnly", "resourceType IS NOT NULL"); // notice no ? parameter - * + * * Note: Typically a null value is analogous to OFF. */ public enum NonBindingOverrideFilter { @@ -87,12 +87,12 @@ public abstract class Criteria implements Serializable, BaseCriteria { * Apply a restriction to reduce the cost of the {@link Criteria}-based query generation and execution routines. */ public enum Restriction { - /** + /** * This returns an empty {@link PageList} result whose {@link PageList#getTotalSize()} method otherwise * contains the correct value. */ COUNT_ONLY, - /** + /** * This will return the {@link PageList} result whose {@link PageList#isUnbounded()} returned true, meaning * that the value contained within {@link PageList#getTotalSize()} is invalid / undefined. */ @@ -121,10 +121,10 @@ public abstract class Criteria implements Serializable, BaseCriteria {
// All Criteria support sorting on ID protected PageOrdering sortId; - + // All Criteria support filtering on ID protected Integer filterId; - + // All Criteria support filtering on IDs protected List<Integer> filterIds;
@@ -176,7 +176,7 @@ public abstract class Criteria implements Serializable, BaseCriteria { addSortField("id"); this.sortId = sortId; } - + public void addFilterId(Integer filterId) { this.filterId = filterId; } @@ -189,6 +189,13 @@ public abstract class Criteria implements Serializable, BaseCriteria { orderingFieldNames.add("sort" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1)); }
+ /** + * Sets the paging constraints to return items [pageNumber * pageSize , ((pageNumber+1) * pageSize) -1 ]. + * For this to work correctly, you also need to set the sort + * criteria (do not rely on implicit id-sorting to work correctly. + * @param pageNumber The page to fetch. This is 0-based. + * @param pageSize The number of items to return. + */ public void setPaging(int pageNumber, int pageSize) { this.pageNumber = pageNumber; this.pageSize = pageSize; @@ -196,7 +203,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
/** * If the pageControl is set, then this criteria object will completely ignore any - * calls made to setPaging(pageNumber, pageSize) as well as addSortField(fieldName), + * calls made to setPaging(pageNumber, pageSize) as well as addSortField(fieldName), * which is useful from a server-side calling context where the PageControl object * will already have been created for you by the extensions at the JSF layer. */ @@ -248,7 +255,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
/** * If set to true, string-based filters will use exact string matches; - * Default is 'false', which means we'll fuzzy match + * Default is 'false', which means we'll fuzzy match */ public void setStrict(boolean strict) { this.strict = strict; @@ -262,9 +269,9 @@ public abstract class Criteria implements Serializable, BaseCriteria { * By default, two queries will be generated for this Criteria: one which fetches the requested page/subset of * entity results, and one which fetches the total cardinality of the result set. If you wish to only retrieve one * of those pieces of data, you can do so by setting a restriction on the query generation and execution routines. - * + * * The restriction, once set, can be removed by passing NULL to this method. - * + * * @see Restriction */ public void setRestriction(Restriction restriction) { @@ -325,7 +332,7 @@ public abstract class Criteria implements Serializable, BaseCriteria { * Somewhat analogous to JPA's Query.getSingleResult. Wrap a CriteriaQuery result with this method when * expecting a single result from the fetch. If the result set has only one entry it is returned. Otherwise * a RuntimeException is thrown, indicating whether no results, or multiple results were found. - * + * * @param result * @return * @throws RuntimeException In not exactly one result is found. The message will include either the String diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java index 7a198bd..0038099 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java @@ -52,8 +52,6 @@ import org.infinispan.Cache; import org.infinispan.manager.CacheContainer;
import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.Configuration; -import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.measurement.DataType; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementSchedule; @@ -349,6 +347,7 @@ public class AbstractRestBean { rwt.setTypeName(resourceType.getName()); rwt.setTypeId(resourceType.getId()); rwt.setPluginName(resourceType.getPlugin()); + rwt.setStatus(res.getInventoryStatus().name()); Resource parent = res.getParentResource(); if (parent != null) { rwt.setParentId(parent.getId()); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/BadArgumentException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/BadArgumentException.java index cea84c2..3879f73 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/BadArgumentException.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/BadArgumentException.java @@ -23,7 +23,10 @@ import javax.ejb.ApplicationException; /** * Exception if arguments are bad. * Don't use java.lang.IllegalArgumentException, as this is no - * Application Exception and gets wrapped + * Application Exception and gets wrapped. + * + * The ExceptionMapper translates this into a 406 repsonse code + * * @author Heiko W. Rupp */ @ApplicationException(rollback = false, inherited = true) diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java index 3e1d195..288e9f7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java @@ -177,14 +177,28 @@ public class ResourceHandlerBean extends AbstractRestBean {
@GET @GZIP @Path("/") + @ApiError(code = 406, reason = "The passed inventory status was invalid") @ApiOperation(value = "Search for resources by the given search string, possibly limited by category and paged", responseClass = "ResourceWithType") - public Response getResourcesByQuery(@ApiParam("String to search in the resource name") @QueryParam("q") String q, + public Response getResourcesByQuery(@ApiParam("Limit results to param in the resource name") @QueryParam("q") String q, @ApiParam("Limit to category (PLATFORM, SERVER, SERVICE") @QueryParam("category") String category, @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize, - @ApiParam("Page for paging") @QueryParam("page") Integer page, + @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page, + @ApiParam(value = "Limit to Inventory status of the resources", allowableValues = "ALL, NEW, IGNORED, COMMITTED, DELETED, UNINVENTORIED") + @DefaultValue("COMMITTED") @QueryParam("status") String status, @Context HttpHeaders headers, @Context UriInfo uriInfo) { + ResourceCriteria criteria = new ResourceCriteria(); + if (!status.toLowerCase().equals("all")) { + try { + criteria.addFilterInventoryStatus(InventoryStatus.valueOf(status.toUpperCase())); + } catch (IllegalArgumentException iae) { + throw new BadArgumentException("status","Value " + status + " is not in the list of allowed values: ALL, NEW, IGNORED, COMMITTED, DELETED, UNINVENTORIED" ); + } + } else { + // JavaDoc says to explicitly set to null in order to get all Status + criteria.addFilterInventoryStatus(null); + } if (q!=null) { criteria.addFilterName(q); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java index 6b9aace..703e897 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java @@ -52,6 +52,7 @@ public class ResourceWithType { Integer typeId; String pluginName; Integer parentId; + String status; List<Link> links = new ArrayList<Link>(); private String ancestry;
@@ -126,6 +127,15 @@ public class ResourceWithType { this.parentId = parentId; }
+ @ApiProperty(value = "Inventory status of the resource.",allowableValues = "NEW, IGNORED, COMMITTED, DELETED, UNINVENTORIED" ) + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + @XmlElementRef public List<Link> getLinks() { return links; diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java index c71bbd8..3efd807 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java @@ -113,7 +113,6 @@ public class ResourcesTest extends AbstractBase { @Test public void testGetPlatformUILink() {
- Response response = given() .header(acceptJson) .pathParam("id", _platformId) @@ -145,6 +144,74 @@ public class ResourcesTest extends AbstractBase { }
@Test + public void testResourceQueryAllStatus() throws Exception { + String json = get("/resource/platforms.json").asString(); + String platformName = JsonPath.with(json).get("[0].resourceName"); + + given() + .header("Accept", "application/json") + .with() + .queryParam("q", platformName) + .queryParam("status","all") + .queryParam("category", "platform") + .expect() + .statusCode(200) + .body("links.self", notNullValue()) + .when() + .get("/resource"); + } + + @Test + public void testResourceQueryCommittedStatus() throws Exception { + String json = get("/resource/platforms.json").asString(); + String platformName = JsonPath.with(json).get("[0].resourceName"); + + given() + .header("Accept", "application/json") + .with() + .queryParam("q", platformName) + .queryParam("status","committed") + .queryParam("category", "platform") + .expect() + .statusCode(200) + .body("links.self", notNullValue()) + .when() + .get("/resource"); + } + + @Test + public void testResourceQueryNewStatus() throws Exception { + + // Unfortunately we can not assume that there are + // any resources in other states than COMMITTED + given() + .header("Accept", "application/json") + .with() + .queryParam("status","NeW") + .expect() + .statusCode(200) + .when() + .get("/resource"); + } + + @Test + public void testResourceQueryBadStatus() throws Exception { + String json = get("/resource/platforms.json").asString(); + String platformName = JsonPath.with(json).get("[0].resourceName"); + + given() + .header("Accept", "application/json") + .with() + .queryParam("q", platformName) + .queryParam("status","Frobnitz") + .queryParam("category", "platform") + .expect() + .statusCode(406) + .when() + .get("/resource"); + } + + @Test public void testResourceQueryCategory() throws Exception {
with() diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Resource.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Resource.java index 6cbcea0..f060101 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Resource.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Resource.java @@ -33,6 +33,7 @@ public class Resource { String typeName; String pluginName; Integer parentId; + String status; int typeId; List<Map> links; String ancestry; @@ -103,4 +104,12 @@ public class Resource { public void setAncestry(String ancestry) { this.ancestry = ancestry; } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } }
commit c12f45a0dac01b601ce05fc7046042b83e51b184 Author: Heiko W. Rupp hwr@redhat.com Date: Fri May 10 11:15:25 2013 +0200
Make this test use the RHQ server, so that no external EAP needs to be set up.
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java index 5532b13..7e3f45a 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java @@ -176,7 +176,7 @@ public class ContentTest extends AbstractBase { List<Map<String,Object>> resources = given() .header(acceptJson) - .queryParam("q","EAP (127.0.0.1:9990)") // TODO fragile -- better search for it? + .queryParam("q","EAP (127.0.0.1:6990)") // TODO Can we identify the RHQ server itself better? .queryParam("category","SERVER") .expect() .statusCode(200) @@ -188,6 +188,7 @@ public class ContentTest extends AbstractBase { assert resources.size()>0;
int as7Id = Integer.valueOf((String)resources.get(0).get("resourceId")); + int createdResourceId=-1;
// create child of eap6 as deployment try { @@ -223,25 +224,33 @@ public class ContentTest extends AbstractBase { int status = response.getStatusCode(); String location = response.getHeader("Location");
- System.out.println("Location " + location + "\n\n"); + System.out.println("\nLocation " + location + "\n\n"); assert location!=null;
// We need to check what we got. A 302 means the deploy is still // in progress, so we need to wait a little longer while (status==302) {
- status = + response = given() .header(acceptJson) .log().everything() .expect() - .statusCode(isOneOf(200,201,302)) + .statusCode(isOneOf(200, 201, 302)) .log().everything() .when() - .get(location) - .getStatusCode(); + .get(location); + + status = response.getStatusCode(); }
+ createdResourceId = response.jsonPath().getInt("resourceId"); + + System.out.println("\n Deploy is done, resource Id = " + createdResourceId + " \n"); + System.out.flush(); + + assert createdResourceId != -1; + } finally {
// Remove the uploaded content @@ -254,47 +263,23 @@ public class ContentTest extends AbstractBase { .when() .delete("/content/{handle}");
+ System.out.println("\n Content removed \n"); + System.out.flush(); + + + // We need to wait here a little, as the machinery is not used to + // quick create-delete-cycles + Thread.sleep(20*1000L);
- // try to remove the created resource - Response response = given() - .queryParam("q", "test-simple.war") .header(acceptJson) + .queryParam("physical", "true") // Also remove target on the EAP instance + .pathParam("id",createdResourceId) + .log().everything() .expect() .log().everything() .when() - .get("/resource"); - - List links = response.body().jsonPath().getList("links"); - - System.out.println(links); - assert links!=null; - - if (links.size()>0) { - - String link = null; - @SuppressWarnings("unchecked") - List<Map<String,Map<String,String>>> listOfMaps = (List<Map<String, Map<String, String>>>) links.get(0); - - for (Map<String,Map<String,String>> map : listOfMaps) { - if (map.containsKey("self")) { - link = map.get("self").get("href"); - break; - } - } - - assert link != null; - - System.out.println("Link: " + link); - - given() - .header(acceptJson) - .queryParam("physical","true") // Also remove target on the EAP instance - .expect() - .log().everything() - .when() - .delete(link); - } + .delete("/resource/{id}");
}
commit 80e9f520ab6dfa5fa42357aa7fa5dbfdeb98d631 Author: John Mazzitelli mazz@redhat.com Date: Thu May 9 21:50:21 2013 -0400
BZ 951382 - if keystore/truststore is left undefined in agent config, we'll explicitly set the pref for the user using the "conf/" location
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java index d959552..6e1a95a 100644 --- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java @@ -2313,6 +2313,9 @@ public class AgentMain { * @throws Exception if any error causes the startup to fail */ private void startCommServices(BootstrapLatchCommandListener listener) throws Exception { + // BZ 951382 - if any locations for keystore/truststore are not configured, set our own defaults to the conf/ directory + assignDefaultLocationToKeystoreTruststoreFiles(); + // create our client sender so we can send commands to our server // do this before we create our auto-discovery listener and start the server-side services // since it will be needed by the listener very quickly if the server is already online @@ -2348,6 +2351,41 @@ public class AgentMain { return; }
+ private void assignDefaultLocationToKeystoreTruststoreFiles() { + File confDir = new File("conf"); + if (!confDir.exists()) { + return; // conf/ doesn't exist (perhaps we are running in a test?) - do nothing and just fallback to the standard defaults + } + + String prefNamesFileNames[][] = { + { ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_FILE, + ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_KEYSTORE_FILE_NAME }, + { ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_TRUSTSTORE_FILE, + ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_TRUSTSTORE_FILE_NAME }, + { AgentConfigurationConstants.CLIENT_SENDER_SECURITY_KEYSTORE_FILE, + AgentConfigurationConstants.DEFAULT_CLIENT_SENDER_SECURITY_KEYSTORE_FILE_NAME }, + { AgentConfigurationConstants.CLIENT_SENDER_SECURITY_TRUSTSTORE_FILE, + AgentConfigurationConstants.DEFAULT_CLIENT_SENDER_SECURITY_TRUSTSTORE_FILE_NAME } }; + + Preferences prefs = m_configuration.getPreferences(); + for (String[] prefNameFileName : prefNamesFileNames) { + String value = prefs.get(prefNameFileName[0], null); + if (value == null) { + value = new File(confDir, prefNameFileName[1]).getAbsolutePath(); + prefs.put(prefNameFileName[0], value); + LOG.debug(AgentI18NResourceKeys.CERT_FILE_LOCATION, prefNameFileName[0], value); + } + } + + try { + prefs.flush(); + } catch (Exception e) { + LOG.warn(AgentI18NResourceKeys.CANNOT_STORE_PREFERENCES, "keystore/truststore files", e); + } + + return; + } + private boolean isAutoDiscoveryEnabled() { return m_autoDiscoveryListener != null; } diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java index 10761ff..21a39a9 100644 --- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/i18n/AgentI18NResourceKeys.java @@ -28,6 +28,9 @@ import mazz.i18n.annotation.I18NResourceBundle; */ @I18NResourceBundle(baseName = "agent-messages", defaultLocale = "en") public interface AgentI18NResourceKeys { + @I18NMessage("Explicitly setting file location [{0}] to [{1}]") + String CERT_FILE_LOCATION = "AgentConfiguration.cert-file-location"; + @I18NMessage("The configured server alias [{0}] cannot be resolved - will use localhost address. Cause: {1}") String SERVER_ALIAS_UNKNOWN = "AgentConfiguration.server-alias-unknown";
commit 7c4577c895a469b5ddce6aa91eb6935eb5cf6cc9 Author: John Mazzitelli mazz@redhat.com Date: Wed May 8 22:23:58 2013 -0400
BZ 535800 - can't use default protocol because it is automatically initialized and cached, not allowing us to use a customized one add a main() for quick testing
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java index 6097ebe..16a4544 100644 --- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java @@ -23,7 +23,6 @@ import java.io.File; import java.io.FileInputStream; import java.net.URL; import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier; @@ -62,29 +61,13 @@ public class SecureConnector { private final String truststoreAlgorithm;
/** - * The {@link #openSecureConnection(URL) secure connections} built by this object will not - * authenticate the server endpoint, but they will use the default secure socket protocol to - * encrypt the connection traffic (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>). - * - * @throws NoSuchAlgorithmException if the default secure connection protocol cannot be determined - */ - public SecureConnector() throws NoSuchAlgorithmException { - this(null, null, null, null, null); - } - - /** * The {@link #openSecureConnection(URL) secure connections} built by this object will * not authenticate the server endpoint, but they will use the given secure socket protocol * to encrypt the connection traffic. * - * @param secureSocketProtocol the secure socket protocol to use; if <code>null</code>, then - * the JVM's default secure socket protocol will be used - * (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>) - * - * @throws NoSuchAlgorithmException if <code>secureSocketProtocol</code> is <code>null</code>, and - * the default secure connection protocol cannot be determined + * @param secureSocketProtocol the secure socket protocol to use (e.g. "TLS") */ - public SecureConnector(String secureSocketProtocol) throws NoSuchAlgorithmException { + public SecureConnector(String secureSocketProtocol) { this(secureSocketProtocol, null, null, null, null); }
@@ -97,28 +80,22 @@ public class SecureConnector { * truststore parameters are ignored and the secure connections built by this object will * not authenticate the server endpoint. * - * @param secureSocketProtocol the secure socket protocol to use; if <code>null</code>, then - * the JVM's default secure socket protocol will be used - * (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>) + * @param secureSocketProtocol the secure socket protocol to use (e.g. "TLS") * @param truststoreFile the truststore file containing authorized certificates - * @param truststorePassword the password to the truststore file - * @param truststoreType the type of the truststore file; if <code>null</code>, then the JVM's + * @param truststorePassword the password to the truststore file (if a file is given, this must not be <code>null</code>) + * @param truststoreType the type of the truststore file (e.g. "JKS"); if <code>null</code>, then the JVM's * default type is used (see <code>java.security.KeyStore.getDefaultType()</code>) - * @param truststoreAlgorithm the standard name of the trust management algorithm; if <code>null</code>, - * then the JVM's default algorithm is used (see + * @param truststoreAlgorithm the standard name of the trust management algorithm (e.g. "SunX509"); + * if <code>null</code>, then the JVM's default algorithm is used (see * <code>javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()</code>) - * - * @throws NoSuchAlgorithmException if <code>secureSocketProtocol</code> is <code>null</code>, and - * the default secure connection protocol cannot be determined */ public SecureConnector(String secureSocketProtocol, File truststoreFile, String truststorePassword, - String truststoreType, String truststoreAlgorithm) throws NoSuchAlgorithmException { + String truststoreType, String truststoreAlgorithm) {
if (secureSocketProtocol == null) { - this.secureSocketProtocol = SSLContext.getDefault().getProtocol(); - } else { - this.secureSocketProtocol = secureSocketProtocol; + throw new IllegalArgumentException("secure socket protocol cannot be null"); } + this.secureSocketProtocol = secureSocketProtocol;
if (truststoreFile == null) { // no truststore file was provided, we don't need to know any truststore parameters @@ -129,17 +106,21 @@ public class SecureConnector { } else { // the truststore file is provided, make sure we have non-null truststore parameters, using defaults if need be this.truststoreFile = truststoreFile; + + if (truststorePassword == null) { + throw new IllegalArgumentException("truststorePassword cannot be null"); + } this.truststorePassword = truststorePassword;
if (truststoreType == null) { truststoreType = KeyStore.getDefaultType(); } - this.truststoreType = (truststoreType != null) ? truststoreType : "JKS"; + this.truststoreType = truststoreType;
if (truststoreAlgorithm == null) { truststoreAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); } - this.truststoreAlgorithm = (truststoreAlgorithm != null) ? truststoreAlgorithm : "SunX509"; + this.truststoreAlgorithm = truststoreAlgorithm; }
return; @@ -216,4 +197,16 @@ public class SecureConnector { return true; } }; + + public static void main(String[] args) throws Exception { + HttpsURLConnection conn = new SecureConnector("TLS").openSecureConnection(new URL(args[0])); + java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream(); + java.io.InputStream input = new java.io.BufferedInputStream(conn.getInputStream(), 32768); + byte[] buffer = new byte[32768]; + for (int bytesRead = input.read(buffer); bytesRead != -1; bytesRead = input.read(buffer)) { + out.write(buffer, 0, bytesRead); + } + out.flush(); + System.out.println(out.toString()); + } } \ No newline at end of file
commit 2c6438cd554b64aa97f2b83d1d5fe7f005d9f68f Author: John Mazzitelli mazz@redhat.com Date: Wed May 8 16:43:36 2013 -0400
BZ 535800 - allow the agent to download the agent update binary over the configured SSL channel
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateDownload.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateDownload.java index 9edad7f..ccd46db 100644 --- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateDownload.java +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateDownload.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,8 @@ import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL;
+import javax.net.ssl.HttpsURLConnection; + import mazz.i18n.Logger;
import org.rhq.core.util.MessageDigestGenerator; @@ -153,7 +155,13 @@ public class AgentUpdateDownload { // we only support http/s url = getDownloadUrl(); LOG.info(AgentI18NResourceKeys.UPDATE_DOWNLOAD_RETRIEVAL, info, url); - conn = (HttpURLConnection) url.openConnection(); + + if (url.getProtocol().equals("https")) { + conn = openSecureConnection(url); + } else { + conn = (HttpURLConnection) url.openConnection(); // we only support http(s), so this cast is OK + } + inStream = conn.getInputStream();
// put the update content in the local file system @@ -277,4 +285,24 @@ public class AgentUpdateDownload { return false; } } + + private HttpsURLConnection openSecureConnection(URL url) throws Exception { + AgentConfiguration config = this.agent.getConfiguration(); + String secureSocketProtocol = config.getClientSenderSecuritySocketProtocol(); + SecureConnector secureConnector; + if (config.isClientSenderSecurityServerAuthMode()) { + File file = new File(config.getClientSenderSecurityTruststoreFile()); + if (!file.isAbsolute()) { + file = new File(this.agent.getAgentHomeDirectory(), file.getPath()); + } + String password = config.getClientSenderSecurityTruststorePassword(); + String type = config.getClientSenderSecurityTruststoreType(); + String algorithm = config.getClientSenderSecurityTruststoreAlgorithm(); + secureConnector = new SecureConnector(secureSocketProtocol, file, password, type, algorithm); + } else { + secureConnector = new SecureConnector(secureSocketProtocol); + } + + return secureConnector.openSecureConnection(url); + } } diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateVersion.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateVersion.java index b429fa8..6ef123a 100644 --- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateVersion.java +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentUpdateVersion.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -18,11 +18,14 @@ */ package org.rhq.enterprise.agent;
+import java.io.File; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Properties;
+import javax.net.ssl.HttpsURLConnection; + import mazz.i18n.Logger;
import org.rhq.core.util.exception.ThrowableUtil; @@ -100,7 +103,13 @@ public class AgentUpdateVersion { // we only support http/s url = getVersionUrl(); LOG.debug(AgentI18NResourceKeys.UPDATE_VERSION_RETRIEVAL, url); - conn = (HttpURLConnection) url.openConnection(); + + if (url.getProtocol().equals("https")) { + conn = openSecureConnection(url); + } else { + conn = (HttpURLConnection) url.openConnection(); // we only support http(s), so this cast is OK + } + versionProps = new Properties(); inStream = conn.getInputStream(); versionProps.load(inStream); @@ -142,4 +151,24 @@ public class AgentUpdateVersion {
return; } + + private HttpsURLConnection openSecureConnection(URL url) throws Exception { + AgentConfiguration config = this.agent.getConfiguration(); + String secureSocketProtocol = config.getClientSenderSecuritySocketProtocol(); + SecureConnector secureConnector; + if (config.isClientSenderSecurityServerAuthMode()) { + File file = new File(config.getClientSenderSecurityTruststoreFile()); + if (!file.isAbsolute()) { + file = new File(this.agent.getAgentHomeDirectory(), file.getPath()); + } + String password = config.getClientSenderSecurityTruststorePassword(); + String type = config.getClientSenderSecurityTruststoreType(); + String algorithm = config.getClientSenderSecurityTruststoreAlgorithm(); + secureConnector = new SecureConnector(secureSocketProtocol, file, password, type, algorithm); + } else { + secureConnector = new SecureConnector(secureSocketProtocol); + } + + return secureConnector.openSecureConnection(url); + } } diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java new file mode 100644 index 0000000..6097ebe --- /dev/null +++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/SecureConnector.java @@ -0,0 +1,219 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2013 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.enterprise.agent; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URL; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +/** + * If you need to make a connection to an external HTTP server using the https protocol, + * use this class to build the connection. You can specify which trusted certificates can be used + * to verify and authenticate the remote server via truststore file parameters passed into the constructor. + * In other words, you don't have to rely on the global system properties javax.net.ssl.keyStore and + * javax.net.ssl.trustStore to make your connection. + * + * This is useful if some other object running in your JVM requires + * javax.net.ssl.keyStore/javax.net.ssl.trustStore set to something other than what you want to use. + * Since those system properties can only be set once during the lifetime of the JVM, it is not possible + * to change them at runtime and expect the change to take effect. Besides, even if you could change them, + * this could then effect the other objects that do need those properties set to particular values. + * + * This object has the ability to make an encrypted call without requiring a truststore to exist (that is, + * you can encrypt the call but you will not have the server endpoint verified and authenticated). This + * can be useful if you aren't concerned with authenticating the endpoint but do want to encrypt the + * traffic. + * + * @author John Mazzitelli + */ +public class SecureConnector { + private final String secureSocketProtocol; + private final File truststoreFile; + private final String truststorePassword; + private final String truststoreType; + private final String truststoreAlgorithm; + + /** + * The {@link #openSecureConnection(URL) secure connections} built by this object will not + * authenticate the server endpoint, but they will use the default secure socket protocol to + * encrypt the connection traffic (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>). + * + * @throws NoSuchAlgorithmException if the default secure connection protocol cannot be determined + */ + public SecureConnector() throws NoSuchAlgorithmException { + this(null, null, null, null, null); + } + + /** + * The {@link #openSecureConnection(URL) secure connections} built by this object will + * not authenticate the server endpoint, but they will use the given secure socket protocol + * to encrypt the connection traffic. + * + * @param secureSocketProtocol the secure socket protocol to use; if <code>null</code>, then + * the JVM's default secure socket protocol will be used + * (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>) + * + * @throws NoSuchAlgorithmException if <code>secureSocketProtocol</code> is <code>null</code>, and + * the default secure connection protocol cannot be determined + */ + public SecureConnector(String secureSocketProtocol) throws NoSuchAlgorithmException { + this(secureSocketProtocol, null, null, null, null); + } + + /** + * The {@link #openSecureConnection(URL) secure connections} built by this object will + * authenticate the server endpoint using the given truststore file and its related parameters. + * The connection will use the given secure socket protocol to encrypt the connection traffic. + * + * Note that if the given <code>truststoreFile</code> is <code>null</code>, the other + * truststore parameters are ignored and the secure connections built by this object will + * not authenticate the server endpoint. + * + * @param secureSocketProtocol the secure socket protocol to use; if <code>null</code>, then + * the JVM's default secure socket protocol will be used + * (see <code>javax.net.ssl.SSLContext.getDefault().getProtocol()</code>) + * @param truststoreFile the truststore file containing authorized certificates + * @param truststorePassword the password to the truststore file + * @param truststoreType the type of the truststore file; if <code>null</code>, then the JVM's + * default type is used (see <code>java.security.KeyStore.getDefaultType()</code>) + * @param truststoreAlgorithm the standard name of the trust management algorithm; if <code>null</code>, + * then the JVM's default algorithm is used (see + * <code>javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()</code>) + * + * @throws NoSuchAlgorithmException if <code>secureSocketProtocol</code> is <code>null</code>, and + * the default secure connection protocol cannot be determined + */ + public SecureConnector(String secureSocketProtocol, File truststoreFile, String truststorePassword, + String truststoreType, String truststoreAlgorithm) throws NoSuchAlgorithmException { + + if (secureSocketProtocol == null) { + this.secureSocketProtocol = SSLContext.getDefault().getProtocol(); + } else { + this.secureSocketProtocol = secureSocketProtocol; + } + + if (truststoreFile == null) { + // no truststore file was provided, we don't need to know any truststore parameters + this.truststoreFile = null; + this.truststorePassword = null; + this.truststoreType = null; + this.truststoreAlgorithm = null; + } else { + // the truststore file is provided, make sure we have non-null truststore parameters, using defaults if need be + this.truststoreFile = truststoreFile; + this.truststorePassword = truststorePassword; + + if (truststoreType == null) { + truststoreType = KeyStore.getDefaultType(); + } + this.truststoreType = (truststoreType != null) ? truststoreType : "JKS"; + + if (truststoreAlgorithm == null) { + truststoreAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); + } + this.truststoreAlgorithm = (truststoreAlgorithm != null) ? truststoreAlgorithm : "SunX509"; + } + + return; + } + + public HttpsURLConnection openSecureConnection(URL url) throws Exception { + // we assume the URL is https - if it is not, its an error so just let the cast throw exception + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + + TrustManager[] trustManagers; + SSLContext sslContext = SSLContext.getInstance(getSecureSocketProtocol()); + + if (getTruststoreFile() == null) { + // we are configured to not care about authenticating the server, just encrypt but don't worry about certificates + trustManagers = new TrustManager[] { NO_OP_TRUST_MANAGER }; + connection.setHostnameVerifier(NO_OP_HOSTNAME_VERIFIER); + } else { + // We need to configure our SSL connection with the agent's truststore so we can authenticate the server. + // First, create a KeyStore, but load it with our truststore entries. + KeyStore keyStore = KeyStore.getInstance(getTruststoreType()); + keyStore.load(new FileInputStream(getTruststoreFile()), getTruststorePassword().toCharArray()); + // now create a truststore manager instance and initialize it with our KeyStore we created with all our truststore entries + TrustManagerFactory tmf = TrustManagerFactory.getInstance(getTruststoreAlgorithm()); + tmf.init(keyStore); + trustManagers = tmf.getTrustManagers(); + } + + sslContext.init(null, trustManagers, null); + connection.setSSLSocketFactory(sslContext.getSocketFactory()); + + return connection; + } + + public String getSecureSocketProtocol() { + return this.secureSocketProtocol; + } + + public File getTruststoreFile() { + return this.truststoreFile; + } + + public String getTruststorePassword() { + return this.truststorePassword; + } + + public String getTruststoreType() { + return this.truststoreType; + } + + public String getTruststoreAlgorithm() { + return this.truststoreAlgorithm; + } + + private static TrustManager NO_OP_TRUST_MANAGER = new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { + return; + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { + return; + } + }; + + private static HostnameVerifier NO_OP_HOSTNAME_VERIFIER = new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }; +} \ No newline at end of file
commit 8091c631ae4cebe9a19825f3c107753590bec922 Author: Mike Thompson mithomps@redhat.com Date: Wed May 8 10:15:23 2013 -0700
[BZ 960646] - RFE Redesigned Availability Chart - i18n.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java index f0db5a2..fbce610 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java @@ -124,11 +124,13 @@ public class AvailabilityOverUnderGraphType { global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartDateLabel()(), global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartTimeLabel()(), global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverStartLabel()(), - global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverEndLabel()(), global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverBarLabel()(), global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverAvailabilityLabel()(), global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverTimeFormat()(), - global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverDateFormat()() + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverDateFormat()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getAvailChartTitleLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getAvailChartUpLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getAvailChartDownLabel()() );
@@ -264,7 +266,7 @@ public class AvailabilityOverUnderGraphType { .style("font-family", "Arial, Verdana, sans-serif;") .style("font-weight", "bold") .attr("fill", "#003168") - .text("Availability"); + .text(availChartContext.chartTitle);
svg.append("text") .attr("class", "upLabel") @@ -274,7 +276,7 @@ public class AvailabilityOverUnderGraphType { .style("font-size", "9px") .attr("fill", "#50505a") .style("text-anchor", "end") - .text("UP"); + .text(availChartContext.chartUpLabel);
svg.append("text") .attr("class", "downLabel") @@ -284,7 +286,7 @@ public class AvailabilityOverUnderGraphType { .style("font-size", "9px") .attr("fill", "#50505a") .style("text-anchor", "end") - .text("DOWN"); + .text(availChartContext.chartDownLabel);
}
@@ -355,8 +357,16 @@ public class AvailabilityOverUnderGraphType { return MSG.chart_hover_start_label(); }
- public String getChartHoverEndLabel() { - return MSG.chart_hover_end_label(); + public String getAvailChartDownLabel() { + return MSG.avail_chart_down_label(); + } + + public String getAvailChartUpLabel() { + return MSG.avail_chart_up_label(); + } + + public String getAvailChartTitleLabel() { + return MSG.avail_chart_title_label(); }
public String getChartHoverBarLabel() { 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 0c5af20..00a68ef 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 @@ -6,6 +6,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +avail_chart_down_label = DOWN +avail_chart_title_label = Availability +avail_chart_up_label = UP chart_date_label = Date chart_down_label = Down chart_hover_availability_label = Availability 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 42405aa..a27fb3c 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 @@ -29,6 +29,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start 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 8185e7f..5415ed0 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 @@ -9,6 +9,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start 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 c15e129..8f47413 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 @@ -9,6 +9,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ko.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ko.properties index 8105460..5d19d06 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ko.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ko.properties @@ -7,6 +7,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start 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 d50a54e..743c4b5 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 @@ -6,6 +6,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start 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 fb45e35..772c4e4 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 @@ -6,6 +6,9 @@ ## http://rhq-project.org/display/RHQ/Working+with+the+Resource+Bundles ## #################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start 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 e929386..03dfa4e 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 @@ -6,6 +6,9 @@ # https://docs.jboss.org/author/display/RHQ/Working+with+the+Resource+Bundles # ################################### +##avail_chart_down_label = DOWN +##avail_chart_title_label = Availability +##avail_chart_up_label = UP ##chart_date_label = Date ##chart_down_label = Down ##chart_time_label = Start diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js index 081a9a2..3b35252 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js +++ b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js @@ -48,7 +48,7 @@ var ChartContext = function (chartId, chartHeight, metricsData, xAxisLabel, char this.chartSelection = this.chartHandle + " svg";
}, -AvailChartContext = function (chartId, availData, dateLabel, timeLabel, hoverStartLabel, hoverEndLabel, hoverBarLabel, availabilityLabel, chartHoverTimeFormat, chartHoverDateFormat) { +AvailChartContext = function (chartId, availData, dateLabel, timeLabel, hoverStartLabel, hoverBarLabel, availabilityLabel, chartHoverTimeFormat, chartHoverDateFormat, chartTitle, chartUpLabel, chartDownLabel) { "use strict"; if (!(this instanceof AvailChartContext)) { throw new Error("AvailChartContext function cannot be called as a function.") @@ -60,10 +60,12 @@ AvailChartContext = function (chartId, availData, dateLabel, timeLabel, hoverSta this.dateLabel = dateLabel; this.timeLabel = timeLabel; this.hoverStartLabel = hoverStartLabel; - this.hoverEndLabel = hoverEndLabel; this.hoverBarLabel = hoverBarLabel; this.hoverBarAvailabilityLabel = availabilityLabel; this.chartHoverTimeFormat = chartHoverTimeFormat; this.chartHoverDateFormat = chartHoverDateFormat; + this.chartTitle = chartTitle; + this.chartDownLabel = chartDownLabel; + this.chartUpLabel = chartUpLabel;
};
commit 59df0f08367521576187063a6bbafaa6ba0be9c2 Author: Mike Thompson mithomps@redhat.com Date: Wed May 8 08:45:18 2013 -0700
Make x-axis more readable on Safari, IE. These browsers even though they are using the same SVG fonts, render wider fonts showing up as labels running into one another. Reduced the clutter on the x-axis for increased readability.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java index e38df39..f0db5a2 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java @@ -162,7 +162,7 @@ public class AvailabilityOverUnderGraphType {
xAxis = $wnd.d3.svg.axis() .scale(timeScale) - .ticks(12) + .ticks(8) .tickSize(13, 0, 0) .orient("bottom"),
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java index bf08615..4d71192 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java @@ -129,13 +129,8 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { else { console.log("Using Large Charts Profile"); // we use the width already defined above - if(isIEBrowserGreaterThanOrEqualTo(9)){ - xTicks = 8; - xTickSubDivide = 5; - }else { - xTicks = 12; - xTickSubDivide = 5; - } + xTicks = 8; + xTickSubDivide = 5; chartData = chartContext.data; }
commit c8bbd8b0c5dcfa51a2d653a95bc83d73d80178be Author: Mike Thompson mithomps@redhat.com Date: Wed May 8 08:30:08 2013 -0700
[BZ 960521] Globally uncaught exception on clicking on resource name link on IE9.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java index 4e6a0ce..e38df39 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java @@ -215,7 +215,7 @@ public class AvailabilityOverUnderGraphType { } else { // should not ever happen, but... - console.warn("AvailabilityType not valid."); + console.log("AvailabilityType not valid."); return "#000"; //black } }, @@ -318,13 +318,11 @@ public class AvailabilityOverUnderGraphType {
return { // Public API - draw: function (chartContext) { + draw: function (availChartContext) { "use strict"; - console.info("AvailabilityChart"); - //console.time("availabilityChart"); + console.log("AvailabilityChart"); drawBars(availChartContext); createHovers(); - //console.timeEnd("availabilityChart"); } }; // end public closure
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java index 15f400d..bf08615 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java @@ -38,7 +38,7 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { */ @Override public native void drawJsniChart() /*-{ - //console.log("Draw Stacked Bar jsni chart"); + console.log("Draw Stacked Bar jsni chart"); var global = this,
// create a chartContext object (from rhq.js) with the data required to render to a chart @@ -120,14 +120,14 @@ public class StackedBarMetricGraphImpl extends AbstractGraph {
// if window is too small server up small chart if (useSmallCharts()) { - //console.log("Using Small Charts Profile for width: "+getChartWidth()); + console.log("Using Small Charts Profile for width: "+getChartWidth()); width = 250; xTicks = 3; xTickSubDivide = 2; chartData = chartContext.data.slice(chartContext.data.length - numberOfBarsForSmallGraph, chartContext.data.length - 1); } else { - //console.log("Using Large Charts Profile"); + console.log("Using Large Charts Profile"); // we use the width already defined above if(isIEBrowserGreaterThanOrEqualTo(9)){ xTicks = 8; @@ -613,8 +613,7 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { "use strict"; // Guard condition that can occur when a portlet has not been configured yet if (chartContext.data.length > 0) { - //console.info("Creating Chart: "+ chartContext.chartSelection + " --> "+ chartContext.chartTitle); - //console.time("chart"); + console.log("Creating Chart: "+ chartContext.chartSelection + " --> "+ chartContext.chartTitle);
determineScale(); createHeader(chartContext.chartTitle); @@ -624,11 +623,10 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { createXandYAxes(); createAvgLines(); if (oobMax > 0) { - //console.info("OOB Data Exists!"); + console.log("OOB Data Exists!"); createOOBLines(); } createHovers(chartContext); - //console.timeEnd("chart"); } } }; // end public closure diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js index 27c4cc0..081a9a2 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js +++ b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js @@ -2,29 +2,9 @@ * Charting Javascript Functions. */
-// Avoid `console` errors in browsers that lack a console. -(function() { - var method; - var noop = function () {}; - var methods = [ - 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', - 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', - 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', - 'timeStamp', 'trace', 'warn' - ]; - var length = methods.length; - var console = (window.console = window.console || {}); - - while (length--) { - method = methods[length]; - - // Only stub undefined methods. - if (!console[method]) { - console[method] = noop; - } - } -} ()); - +// Handle browsers not supporting console object +if (!window.console) window.console = {}; +if (!window.console.log) window.console.log = function () { };
/** * ChartContext Constructor Object
commit db8f9686b96e2e3c44e61162b1a0d2d388fc59e9 Author: Heiko W. Rupp hwr@redhat.com Date: Wed May 8 13:48:42 2013 +0200
BZ 960529 - check for non-existing resources when obtaining availability
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java index 4e00625..3e1d195 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java @@ -338,6 +338,10 @@ public class ResourceHandlerBean extends AbstractRestBean { @ApiParam(value="Start time", defaultValue = "30 days ago") @QueryParam("start") long start, @ApiParam(value="End time", defaultValue = "Now") @QueryParam("end") long end, @Context HttpHeaders headers) { + + // Vaildate it the resource exists + fetchResource(resourceId); + if (end==0) end = System.currentTimeMillis();
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java index 1dee0f1..c71bbd8 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java @@ -499,6 +499,22 @@ public class ResourcesTest extends AbstractBase { }
@Test + public void testCreateChildForUnknownParent() throws Exception { + + given() + .body("{"value":"CPU"}") // Type of new resource + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .pathParam("name", "test") + .queryParam("plugin", "Platforms") + .queryParam("parentId", 321) + .expect() + .statusCode(404) + .log().ifError() + .when().post("/resource/{name}"); + } + + @Test public void testAlertsForResource() throws Exception { given() .header("Accept", "application/json") @@ -521,6 +537,17 @@ public class ResourcesTest extends AbstractBase { }
@Test + public void testSchedulesForUnknownResource() throws Exception { + given() + .header("Accept", "application/json") + .pathParam("id", 123) + .expect() + .statusCode(404) + .when() + .get("/resource/{id}/schedules"); + } + + @Test public void testAvailabilityForResourceJson() throws Exception { given() .header(acceptJson) @@ -532,6 +559,17 @@ public class ResourcesTest extends AbstractBase { }
@Test + public void testAvailabilityForUnknownResource() throws Exception { + given() + .header(acceptJson) + .pathParam("id", 532) + .expect() + .statusCode(404) + .when() + .get("/resource/{id}/availability"); + } + + @Test public void testAvailabilityForResourceXml() throws Exception { given() .header(acceptXml) @@ -554,6 +592,17 @@ public class ResourcesTest extends AbstractBase { }
@Test + public void testAvailabilityHistoryForUnknownResource() throws Exception { + given() + .header(acceptJson) + .pathParam("id", -42) + .expect() + .statusCode(404) + .when() + .get("/resource/{id}/availability/history"); + } + + @Test public void testAvailabilityHistoryForResourceXml() throws Exception { given() .header(acceptXml)
commit 17c3db8f19d0b70a6f0d910450523c245cd6f8b9 Author: Heiko W. Rupp hwr@redhat.com Date: Wed May 8 09:17:48 2013 +0200
Code cleanup and improvements for the REST-api
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java index 2746823..7a198bd 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java @@ -81,21 +81,21 @@ import org.rhq.enterprise.server.rest.domain.ResourceWithType; @SuppressWarnings("unchecked") public class AbstractRestBean {
- Log log = LogFactory.getLog(getClass().getName()); + protected Log log = LogFactory.getLog(getClass().getName());
- static private final CacheKey META_KEY = new CacheKey("rhq.rest.resourceMeta", 0); + private static final CacheKey META_KEY = new CacheKey("rhq.rest.resourceMeta", 0);
@javax.annotation.Resource( name = "ISPN") - protected CacheContainer container; + private CacheContainer container; protected Cache<CacheKey, Object> cache;
/** Subject of the caller that gets injected via {@link SetCallerInterceptor} */ protected Subject caller;
@EJB - ResourceManagerLocal resMgr; + protected ResourceManagerLocal resMgr; @EJB - ResourceGroupManagerLocal resourceGroupManager; + protected ResourceGroupManagerLocal resourceGroupManager;
@PostConstruct public void start() { @@ -116,15 +116,15 @@ public class AbstractRestBean { freemarker.template.Configuration config = new freemarker.template.Configuration();
// XXX fall-over to ClassTL after failure in FTL seems not to work - // FileTemplateLoader ftl = new FileTemplateLoader(new File("src/main/resources")); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "/rest_templates/"); TemplateLoader[] loaders = new TemplateLoader[] { ctl }; MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
config.setTemplateLoader(mtl);
- if (!templateName.endsWith(".ftl")) + if (!templateName.endsWith(".ftl")) { templateName = templateName + ".ftl"; + } Template template = config.getTemplate(templateName);
StringWriter out = new StringWriter(); @@ -171,8 +171,9 @@ public class AbstractRestBean {
CacheValue value = (CacheValue) cache.get(key);
+ boolean debugEnabled = log.isDebugEnabled(); if (null != value) { - if (log.isDebugEnabled()) { + if (debugEnabled) { log.debug("Cache Hit for " + key); }
@@ -180,12 +181,12 @@ public class AbstractRestBean { o = value.getValue();
} else { - if (log.isDebugEnabled()) { + if (debugEnabled) { log.debug("Cache Hit ignored, caller " + caller.toString() + " not found"); } } } else { - if (log.isDebugEnabled()) { + if (debugEnabled) { log.debug("Cache Miss for " + key); } } @@ -351,8 +352,9 @@ public class AbstractRestBean { Resource parent = res.getParentResource(); if (parent != null) { rwt.setParentId(parent.getId()); - } else + } else { rwt.setParentId(0); + }
rwt.setAncestry(res.getAncestry());
@@ -429,8 +431,9 @@ public class AbstractRestBean { protected ResourceGroup fetchGroup(int groupId, boolean requireCompatible) { ResourceGroup resourceGroup; resourceGroup = resourceGroupManager.getResourceGroup(caller, groupId); - if (resourceGroup == null) + if (resourceGroup == null) { throw new StuffNotFoundException("Group with id " + groupId); + } if (requireCompatible) { if (resourceGroup.getGroupCategory() != GroupCategory.COMPATIBLE) { throw new BadArgumentException("Group with id " + groupId,"it is no compatible group"); @@ -445,8 +448,9 @@ public class AbstractRestBean { gr.setId(group.getId()); gr.setCategory(group.getGroupCategory()); gr.setRecursive(group.isRecursive()); - if (group.getGroupDefinition()!=null) + if (group.getGroupDefinition()!=null) { gr.setDynaGroupDefinitionId(group.getGroupDefinition().getId()); + } gr.setExplicitCount(group.getExplicitResources().size()); gr.setImplicitCount(group.getImplicitResources().size()); UriBuilder uriBuilder = uriInfo.getBaseUriBuilder(); @@ -526,16 +530,6 @@ public class AbstractRestBean { return ms; }
- Configuration mapToConfiguration(Map<String,Object> in) { - Configuration config = new Configuration(); - for (Map.Entry<String,Object> entry : in.entrySet()) { - config.put(new PropertySimple(entry.getKey(),entry.getValue())); // TODO honor more types - } - - return config; - - } - /** * Set the caching header on the response * @param builder Response builder to put the caching header on diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java index 06bc8ae..d203cd3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java @@ -106,22 +106,22 @@ import org.rhq.enterprise.server.rest.domain.Link; public class AlertDefinitionHandlerBean extends AbstractRestBean {
@EJB - AlertDefinitionManagerLocal alertDefinitionManager; + private AlertDefinitionManagerLocal alertDefinitionManager;
@EJB - AlertNotificationManagerLocal notificationMgr; + private AlertNotificationManagerLocal notificationMgr;
@EJB - AlertConditionManagerLocal conditionMgr; + private AlertConditionManagerLocal conditionMgr;
@EJB - AlertManagerLocal alertManager; + private AlertManagerLocal alertManager;
@EJB - ResourceGroupManagerLocal resourceGroupMgr; + private ResourceGroupManagerLocal resourceGroupMgr;
@EJB - ResourceTypeManagerLocal resourceTypeMgr; + private ResourceTypeManagerLocal resourceTypeMgr;
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) @@ -169,8 +169,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @Context Request request, @Context UriInfo uriInfo) {
AlertDefinition def = alertDefinitionManager.getAlertDefinition(caller, definitionId); - if (def==null) + if (def==null) { throw new StuffNotFoundException("AlertDefinition with id " + definitionId ); + }
EntityTag eTag = new EntityTag(Integer.toHexString(def.hashCode())); Response.ResponseBuilder builder = request.evaluatePreconditions(eTag); @@ -285,8 +286,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @Context UriInfo uriInfo) {
AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,definitionId); - if (definition==null) + if (definition==null) { throw new StuffNotFoundException("AlertDefinition with id " + definitionId); + }
definition = new AlertDefinition(definition); // detach
@@ -302,10 +304,12 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { // Set the recovery id if such a definition exists at all if (definitionRest.getRecoveryId()>0) { AlertDefinition recoveryDef = alertDefinitionManager.getAlertDefinition(caller,definitionRest.getRecoveryId()); - if (recoveryDef!=null) + if (recoveryDef!=null) { definition.setRecoveryId(definitionRest.getRecoveryId()); - else + } + else { throw new StuffNotFoundException("Alert to recover with id " + definitionRest.getRecoveryId()); + } }
@@ -348,34 +352,24 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { StringBuilder builder = new StringBuilder(); for (int i = 0; i < vals.length ; i++) { builder.append(vals[i].name()); - if (i < vals.length-1) + if (i < vals.length-1) { builder.append(", "); + } } throw new BadArgumentException("dampening category","Allowed values are: " + builder.toString()); } AlertDampening dampening = new AlertDampening(dampeningCategory); - if (adr.getDampeningCount()!=null) { - if (adr.getDampeningCount().contains(" ")) { - String tmp = adr.getDampeningCount().trim(); - int num = Integer.parseInt(tmp.substring(0,tmp.indexOf(' '))); - tmp = tmp.substring(tmp.lastIndexOf(' ')).trim(); - dampening.setValue(num); - dampening.setValueUnits(AlertDampening.TimeUnits.valueOf(tmp.toUpperCase())); - } - else { - dampening.setValue(Integer.parseInt(adr.getDampeningCount())); - } - } - if (adr.getDampeningPeriod()!=null) { - if (adr.getDampeningPeriod().contains(" ")) { - String tmp = adr.getDampeningPeriod().trim(); - int num = Integer.parseInt(tmp.substring(0,tmp.indexOf(' '))); - tmp = tmp.substring(tmp.lastIndexOf(' ')).trim(); - dampening.setPeriod(num); - dampening.setPeriodUnits(AlertDampening.TimeUnits.valueOf(tmp.toUpperCase())); - } - else { - dampening.setPeriod(Integer.parseInt(adr.getDampeningPeriod())); + if (adr.getDampeningCount()>-1) { + dampening.setValue(adr.getDampeningCount()); + } + if (adr.getDampeningPeriod()>0) { + dampening.setPeriod(adr.getDampeningPeriod()); + try { + if (adr.getDampeningUnit()!=null) { + dampening.setPeriodUnits(AlertDampening.TimeUnits.valueOf(adr.getDampeningUnit().toUpperCase())); + } + } catch (Exception e) { + throw new BadArgumentException("dampenign unit", "Allowed values are MINUTES,HOURS,DAYS, WEEKS"); } }
@@ -439,8 +433,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { definition2 = entityManager.find(AlertDefinition.class,definitionId); AlertCondition condition=null; for (AlertCondition c: definition2.getConditions()) { - if (c.getId() == conditionId) + if (c.getId() == conditionId) { condition=c; + } }
definition2.getConditions().remove(condition); @@ -522,8 +517,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @ApiParam("The id of the condition to retrieve") @PathParam("cid") int conditionId) {
AlertCondition condition = conditionMgr.getAlertConditionById(conditionId); - if (condition==null) + if (condition==null) { throw new StuffNotFoundException("No condition with id " + conditionId); + } AlertConditionRest acr = conditionToConditionRest(condition);
return Response.ok(acr).build(); @@ -565,8 +561,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { AlertConditionRest result = conditionToConditionRest(createdCondition);
Response.ResponseBuilder builder; - if (isCreate) + if (isCreate) { builder = Response.created(uri); + } else { builder = Response.ok(); builder.location(uri); @@ -583,8 +580,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @ApiParam("The id of the notification definition to retrieve") @PathParam("nid") int notificationId) {
AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); - if (notification==null) + if (notification==null) { throw new StuffNotFoundException("No notification with id " + notificationId); + } AlertNotificationRest anr = notificationToNotificationRest(notification);
return Response.ok(anr).build(); @@ -618,8 +616,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @ApiParam("The updated notification definition to use") AlertNotificationRest notificationRest) {
AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); - if (notification==null) + if (notification==null) { throw new StuffNotFoundException("No notification with id " + notificationId); + }
AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,notification.getAlertDefinition().getId());
@@ -634,8 +633,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { List<AlertNotification> notifications = definition.getAlertNotifications(); int newNotifId = 0; for (AlertNotification n : notifications) { - if (n.getSenderName().equals(notification.getSenderName())) + if (n.getSenderName().equals(notification.getSenderName())) { newNotifId = n.getId(); + } }
AlertNotification result = notificationMgr.getAlertNotification(caller,newNotifId); @@ -667,8 +667,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
// Now check if the definition exists as well AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,definitionId); - if (definition==null) + if (definition==null) { throw new StuffNotFoundException("AlertDefinition with id " + definitionId); + }
// definition and sender are valid, continue int existingNotificationCount = definition.getAlertNotifications().size(); @@ -816,10 +817,13 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { adr.setDampeningCategory(dampening.getCategory().name()); AlertDampening.TimeUnits units = dampening.getValueUnits(); String s = units != null ? " " + units.name() : ""; - adr.setDampeningCount(dampening.getValue() + s); + adr.setDampeningCount(dampening.getValue()); units = dampening.getPeriodUnits(); s = units != null ? " " + units.name() : ""; - adr.setDampeningPeriod(dampening.getPeriod() + s); + adr.setDampeningPeriod(dampening.getPeriod()); + if (dampening.getPeriodUnits()!=null) { + adr.setDampeningUnit(dampening.getPeriodUnits().name()); + }
if (def.getResource()!=null) { adr.getLinks().add(createUILink(uriInfo,UILinkTemplate.RESOURCE_ALERT_DEF,def.getResource().getId(),adr.getId())); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java index 0a37a9d..4c80bd1 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java @@ -79,10 +79,8 @@ import org.rhq.enterprise.server.rest.domain.*; @Interceptors(SetCallerInterceptor.class) public class AlertHandlerBean extends AbstractRestBean {
-// private final Log log = LogFactory.getLog(AlertHandlerBean.class); - @EJB - AlertManagerLocal alertManager; + private AlertManagerLocal alertManager;
@GZIP @@ -107,10 +105,12 @@ public class AlertHandlerBean extends AbstractRestBean { if (resourceId!=null && definitionId!=null) { throw new BadArgumentException("At most one of 'resourceId' and 'definitionId' may be given"); } - if (size==0) + if (size==0) { throw new BadArgumentException("size","Must not be 0"); - if (page<1) + } + if (page<1) { throw new BadArgumentException("page","Must be >=1"); + }
AlertCriteria criteria = new AlertCriteria();
@@ -119,8 +119,9 @@ public class AlertHandlerBean extends AbstractRestBean { pageControl.setPageNumber(page); criteria.setPageControl(pageControl); } - else + else { criteria.setPaging(page-1, size); // TODO implement linking to next page + }
if (since!=null) { criteria.addFilterStartTime(since); @@ -335,8 +336,9 @@ public class AlertHandlerBean extends AbstractRestBean { AlertCriteria criteria = new AlertCriteria(); criteria.addFilterId(id); List<Alert> alerts = alertManager.findAlertsByCriteria(caller,criteria); - if (alerts.isEmpty()) + if (alerts.isEmpty()) { throw new StuffNotFoundException("Alert with id " + id); + }
return alerts.get(0); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java index 07b2a1c..1099679 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java @@ -43,9 +43,9 @@ import org.rhq.enterprise.server.rest.domain.RHQErrorWrapper; public class CustomExceptionMapper implements ExceptionMapper<Exception> {
@Context - HttpHeaders httpHeaders; + private HttpHeaders httpHeaders;
- Log log = LogFactory.getLog(getClass().getName()); + private Log log = LogFactory.getLog(getClass().getName());
@Override public Response toResponse(Exception e) { @@ -53,24 +53,25 @@ public class CustomExceptionMapper implements ExceptionMapper<Exception> { Response.ResponseBuilder builder; Response.Status status;
- if (e instanceof StuffNotFoundException) + if (e instanceof StuffNotFoundException) { status =Response.Status.NOT_FOUND; - else if (e instanceof ResourceNotFoundException) + } else if (e instanceof ResourceNotFoundException) { status = Response.Status.NOT_FOUND; - else if (e instanceof ResourceGroupNotFoundException) + } else if (e instanceof ResourceGroupNotFoundException) { status = Response.Status.NOT_FOUND; - else if (e instanceof ResourceTypeNotFoundException) + } else if (e instanceof ResourceTypeNotFoundException) { status = Response.Status.NOT_FOUND; - else if (e instanceof ParameterMissingException) + } else if (e instanceof ParameterMissingException) { status = Response.Status.NOT_ACCEPTABLE; - else if (e instanceof BadArgumentException) + } else if (e instanceof BadArgumentException) { status = Response.Status.NOT_ACCEPTABLE; - else if (e instanceof PermissionException) + } else if (e instanceof PermissionException) { status = Response.Status.FORBIDDEN; - else if (e instanceof EJBException && e.getCause()!=null && e.getCause() instanceof IllegalArgumentException) + } else if (e instanceof EJBException && e.getCause()!=null && e.getCause() instanceof IllegalArgumentException) { status = Response.Status.NOT_ACCEPTABLE; - else + } else { status = Response.Status.SERVICE_UNAVAILABLE; + }
builder = Response.status(status); String message = e.getMessage(); @@ -93,8 +94,9 @@ public class CustomExceptionMapper implements ExceptionMapper<Exception> { log.debug(e.getMessage()); mediaType = MediaType.TEXT_PLAIN_TYPE; } - if (mediaType.getType().equals("text") && mediaType.getSubtype().equals("csv")) + if (mediaType.getType().equals("text") && mediaType.getSubtype().equals("csv")) { mediaType = MediaType.TEXT_PLAIN_TYPE; + }
if (mediaType.equals(MediaType.TEXT_PLAIN_TYPE)) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java index ccfed9f..8bc2cb9 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java @@ -47,6 +47,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo;
+import com.wordnik.swagger.annotations.ApiError; +import com.wordnik.swagger.annotations.ApiErrors; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam;
@@ -69,13 +71,17 @@ import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PageOrdering; +import org.rhq.core.domain.util.StringUtils; +import org.rhq.enterprise.server.operation.OperationDefinitionNotFoundException; import org.rhq.enterprise.server.operation.OperationManagerLocal; import org.rhq.enterprise.server.resource.ResourceManagerLocal; +import org.rhq.enterprise.server.resource.ResourceNotFoundException; import org.rhq.enterprise.server.rest.domain.Link; import org.rhq.enterprise.server.rest.domain.OperationDefinitionRest; import org.rhq.enterprise.server.rest.domain.OperationHistoryRest; import org.rhq.enterprise.server.rest.domain.OperationRest; import org.rhq.enterprise.server.rest.domain.SimplePropDef; +import org.rhq.enterprise.server.rest.helper.ConfigurationHelper;
/** * Deal with operations @@ -88,32 +94,31 @@ import org.rhq.enterprise.server.rest.domain.SimplePropDef; public class OperationsHandlerBean extends AbstractRestBean {
@EJB - OperationManagerLocal opsManager; + private OperationManagerLocal opsManager;
@EJB - ResourceManagerLocal resourceManager; + private ResourceManagerLocal resourceManager;
@GET @Path("definition/{id}") @Cache(maxAge = 1200) @ApiOperation("Retrieve a single operation definition by its id") public Response getOperationDefinition( - @ApiParam("Id of the definition to retrieve") @PathParam("id") int definitionId, - @ApiParam("Id of a resource that supports this operation") @QueryParam("resourceId") Integer resourceId, - @Context UriInfo uriInfo, - @Context Request request, - @Context HttpHeaders httpHeaders) { - - + @ApiParam("Id of the definition to retrieve") @PathParam("id") int definitionId, + @ApiParam("Id of a resource that supports this operation") @QueryParam("resourceId") Integer resourceId, + @Context UriInfo uriInfo, + @Context Request request) {
OperationDefinition def; def = getFromCache(definitionId, OperationDefinition.class); if (def==null) { - def = opsManager.getOperationDefinition(caller,definitionId); - if (def==null) - throw new StuffNotFoundException("OperationDefinition with id " + definitionId); - else + try { + def = opsManager.getOperationDefinition(caller,definitionId); putToCache(definitionId,OperationDefinition.class,def); + } + catch (OperationDefinitionNotFoundException ode) { + throw new StuffNotFoundException("Operation definition with id " + definitionId); + } }
EntityTag eTag = new EntityTag(Integer.toHexString(def.hashCode())); @@ -145,43 +150,27 @@ public class OperationsHandlerBean extends AbstractRestBean {
}
- private void copyParamsForDefinition(OperationDefinition def, OperationDefinitionRest odr) { - ConfigurationDefinition cd = def.getParametersConfigurationDefinition(); - if (cd==null) - return; - - for (Map.Entry<String,PropertyDefinition> entry : cd.getPropertyDefinitions().entrySet()) { - PropertyDefinition pd = entry.getValue(); - if (pd instanceof PropertyDefinitionSimple) { - PropertyDefinitionSimple pds = (PropertyDefinitionSimple) pd; - SimplePropDef prop = new SimplePropDef(); - prop.setName(pds.getName()); - prop.setRequired(pds.isRequired()); - prop.setType(pds.getType()); - prop.setDefaultValue(pds.getDefaultValue()); - odr.addParam(prop); - } - log.debug("copyParams: " + pd.getName() + " not yet supported"); - } - } - @GZIP @GET @Path("definitions") @Cache(maxAge = 1200) @ApiOperation("List all operation definitions for a resource") public Response getOperationDefinitions( - @ApiParam(value = "Id of the resource",required = true) @QueryParam("resourceId") Integer resourceId, - @Context UriInfo uriInfo, - @Context Request request, - @Context HttpHeaders httpHeaders) { + @ApiParam(value = "Id of the resource", required = true) @QueryParam("resourceId") Integer resourceId, + @Context UriInfo uriInfo, + @Context Request request) {
- if (resourceId == null) + if (resourceId == null) { throw new ParameterMissingException("resourceId"); + }
- Resource res =resourceManager.getResource(caller,resourceId); - if(res==null) + Resource res; + try { + res = resourceManager.getResource(caller,resourceId); + } + catch (ResourceNotFoundException rnfe) { throw new StuffNotFoundException("resource with id " + resourceId); + }
ResourceType resourceType = res.getResourceType();
@@ -226,16 +215,24 @@ public class OperationsHandlerBean extends AbstractRestBean { @ApiParam(value = "Id of the resource", required = true) @QueryParam("resourceId") Integer resourceId, @Context UriInfo uriInfo) {
- if (resourceId == null) + if (resourceId == null) { throw new ParameterMissingException("resourceId"); + }
- Resource res =resourceManager.getResource(caller,resourceId); - if(res==null) + try { + // Check if the resource exists at all + resourceManager.getResource(caller,resourceId); + } + catch (ResourceNotFoundException rnfe) { throw new StuffNotFoundException("resource with id " + resourceId); + }
- OperationDefinition opDef = opsManager.getOperationDefinition(caller,definitionId); - if (opDef==null) { + OperationDefinition opDef; + try { + opDef = opsManager.getOperationDefinition(caller,definitionId); + } + catch (OperationDefinitionNotFoundException odnfe) { throw new StuffNotFoundException("Operation definition with id " + definitionId); } OperationRest operationRest = new OperationRest(resourceId,definitionId); @@ -266,9 +263,11 @@ public class OperationsHandlerBean extends AbstractRestBean { @Path("{id}") @ApiOperation("Return a (draft) operation") public Response getOperation(@ApiParam("Id of the operation to retrieve") @PathParam("id") int operationId) { + OperationRest op = getFromCache(operationId,OperationRest.class); - if (op==null) + if (op==null) { throw new StuffNotFoundException("Operation with id " + operationId); + }
return Response.ok(op).build(); } @@ -277,20 +276,40 @@ public class OperationsHandlerBean extends AbstractRestBean { @Path("{id}") @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) @ApiOperation("Update a (draft) operation. If the state is set to 'ready', the operation will be scheduled") + @ApiErrors({ + @ApiError(code = 404, reason = "No draft operation with the passed id exists"), + @ApiError(code = 406, reason = "Draft was set for scheduling, but parameters failed validation"), + @ApiError(code = 200, reason = "Update was successful, operation was scheduled if requested" ) + } + ) public Response updateOperation(@ApiParam("Id of the operation to update") @PathParam("id") int operationId, OperationRest operation, @Context UriInfo uriInfo) {
- if (!operation.isReadyToSubmit() && operation.getDefinitionId()>0 && !operation.getName().isEmpty()) { - // TODO check all the required parameters for presence before allowing to submit - operation.setReadyToSubmit(true); + OperationRest op = getFromCache(operationId,OperationRest.class); + if (op==null) { + throw new StuffNotFoundException("Operation with id " + operationId); } + + Configuration parameters = ConfigurationHelper.mapToConfiguration(operation.getParams()); + if (operation.isReadyToSubmit()) { - // todo check params
- // submit + OperationDefinition opDef = opsManager.getOperationDefinition(caller,operation.getDefinitionId());
- Configuration parameters = mapToConfiguration(operation.getParams()); + // Validate parameters + ConfigurationDefinition parameterDefinition = opDef.getParametersConfigurationDefinition(); + List<String> errorMessages = ConfigurationHelper.checkConfigurationWrtDefinition(parameters, parameterDefinition);
+ if (errorMessages.size()>0) { + // Configuration is not ok + operation.setReadyToSubmit(false); + throw new BadArgumentException("Validation of parameters failed", StringUtils.getListAsString(errorMessages,", ")); + } + } + + if (operation.isReadyToSubmit()) { + + // submit ResourceOperationSchedule sched = opsManager.scheduleResourceOperation(caller,operation.getResourceId(),operation.getName(),0,0,0,-1, parameters,"Test"); JobId jobId = new JobId(sched.getJobName(),sched.getJobGroup()); @@ -304,12 +323,12 @@ public class OperationsHandlerBean extends AbstractRestBean { else { UriBuilder uriBuilder = uriInfo.getBaseUriBuilder(); uriBuilder.path("/operation/{id}"); - URI uri = uriBuilder.build(operation.getId()); + URI uri = uriBuilder.build(operationId); Link editLink = new Link("edit",uri.toString()); operation.addLink(editLink); } // Update item in cache - putToCache(operation.getId(),OperationRest.class,operation); + putToCache(operationId,OperationRest.class,operation); Response.ResponseBuilder builder = Response.ok(operation); return builder.build(); } @@ -381,8 +400,9 @@ public class OperationsHandlerBean extends AbstractRestBean { @Context HttpHeaders httpHeaders) {
ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria(); - if (resourceId>0) + if (resourceId>0) { criteria.addFilterResourceIds(resourceId); + }
criteria.addSortEndTime(PageOrdering.DESC);
@@ -424,30 +444,41 @@ public class OperationsHandlerBean extends AbstractRestBean {
}
- + /** + * Create a REST-object from the passed operation history + * @param history History object to convert + * @param uriInfo URI info of the incoming request, used to create links + * @return a populated OperationHistoryRest object + */ private OperationHistoryRest historyToHistoryRest(ResourceOperationHistory history, UriInfo uriInfo) { String status; - if (history.getStatus()==null) + if (history.getStatus()==null) { status = " - no information yet -"; - else + } + else { status = history.getStatus().getDisplayName(); + }
OperationHistoryRest hist = new OperationHistoryRest(); hist.setStatus(status); - if (history.getResource()!=null) + if (history.getResource()!=null) { hist.setResourceName(history.getResource().getName()); + } hist.setOperationName(history.getOperationDefinition().getName()); hist.lastModified(history.getModifiedTime()); - if (history.getErrorMessage()!=null) + if (history.getErrorMessage()!=null) { hist.setErrorMessage(history.getErrorMessage()); + } if (history.getResults()!=null) { Configuration results = history.getResults(); for (Property p : results.getProperties()) { String val; - if (p instanceof PropertySimple) + if (p instanceof PropertySimple) { val = ((PropertySimple)p).getStringValue(); - else + } + else { val = p.toString(); + } hist.getResult().put(p.getName(),val); } } @@ -465,4 +496,34 @@ public class OperationsHandlerBean extends AbstractRestBean { return hist; }
+ /** + * Copies the parameters of an OperationDefinition into to an object that can be + * returned to a REST-client, so that this knows which fields are to be filled in, + * of which type they are and which ones are required + * @param def OperationsDefinition to "copy" + * @param definitionRest The definition to fill in + */ + private void copyParamsForDefinition(OperationDefinition def, OperationDefinitionRest definitionRest) { + ConfigurationDefinition cd = def.getParametersConfigurationDefinition(); + if (cd==null) { + return; + } + + for (Map.Entry<String,PropertyDefinition> entry : cd.getPropertyDefinitions().entrySet()) { + PropertyDefinition pd = entry.getValue(); + if (pd instanceof PropertyDefinitionSimple) { + PropertyDefinitionSimple pds = (PropertyDefinitionSimple) pd; + SimplePropDef prop = new SimplePropDef(); + prop.setName(pds.getName()); + prop.setRequired(pds.isRequired()); + prop.setType(pds.getType()); + prop.setDefaultValue(pds.getDefaultValue()); + definitionRest.addParam(prop); + } + log.debug("copyParams: " + pd.getName() + " not yet supported"); + } + } + + + } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ParameterMissingException.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ParameterMissingException.java index 16fd62f..d3f3f50 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ParameterMissingException.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ParameterMissingException.java @@ -1,9 +1,12 @@ package org.rhq.enterprise.server.rest;
+import javax.ejb.ApplicationException; + /** * Exception thrown if (Query) Parameters are missing * @author Heiko W. Rupp */ +@ApplicationException(rollback = false, inherited = true) public class ParameterMissingException extends RuntimeException {
public ParameterMissingException(String what) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ReportsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ReportsHandlerBean.java index 1377be4..1b563da 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ReportsHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ReportsHandlerBean.java @@ -76,25 +76,25 @@ import org.rhq.enterprise.server.rest.reporting.SuspectMetricLocal; public class ReportsHandlerBean extends AbstractRestBean {
@EJB - AlertDefinitionLocal alertDefinitionLocal; + private AlertDefinitionLocal alertDefinitionLocal; @EJB - ConfigurationHistoryLocal configurationHistoryLocal; + private ConfigurationHistoryLocal configurationHistoryLocal; @EJB - DriftComplianceLocal driftComplianceLocal; + private DriftComplianceLocal driftComplianceLocal; @EJB - InventorySummaryLocal inventorySummaryLocal; + private InventorySummaryLocal inventorySummaryLocal; @EJB - PlatformUtilizationLocal platformUtilizationLocal; + private PlatformUtilizationLocal platformUtilizationLocal; @EJB - RecentAlertLocal recentAlertLocal; + private RecentAlertLocal recentAlertLocal; @EJB - RecentDriftLocal recentDriftLocal; + private RecentDriftLocal recentDriftLocal; @EJB - RecentOperationsLocal recentOperationsLocal; + private RecentOperationsLocal recentOperationsLocal; @EJB - SuspectMetricLocal suspectMetricLocal; + private SuspectMetricLocal suspectMetricLocal;
- String[] reports = { + private String[] reports = { "alertDefinitions", "configurationHistory", "driftCompliance", diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java index 1c2b516..4e00625 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java @@ -108,6 +108,7 @@ import org.rhq.enterprise.server.rest.domain.MetricSchedule; import org.rhq.enterprise.server.rest.domain.ResourceWithChildren; import org.rhq.enterprise.server.rest.domain.ResourceWithType; import org.rhq.enterprise.server.rest.domain.StringValue; +import org.rhq.enterprise.server.rest.helper.ConfigurationHelper;
/** * Class that deals with getting data about resources @@ -755,8 +756,8 @@ public class ResourceHandlerBean extends AbstractRestBean { if (resType==null) throw new StuffNotFoundException("ResourceType with name [" + typeName + "] and plugin [" + plugin + "]");
- Configuration pluginConfig = mapToConfiguration(request.getPluginConfig()); - Configuration deployConfig = mapToConfiguration(request.getResourceConfig()); + Configuration pluginConfig = ConfigurationHelper.mapToConfiguration(request.getPluginConfig()); + Configuration deployConfig = ConfigurationHelper.mapToConfiguration(request.getResourceConfig());
String packageName = DEFAULT_PACKAGE;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java index 3aded78..612b3f7 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java @@ -51,7 +51,7 @@ import org.rhq.enterprise.server.rest.domain.Link; @Stateless public class RootHandlerBean extends AbstractRestBean {
- String[] roots = { // rel, target + private String[] roots = { // rel, target "platforms","resource/platforms", "groups","group", "dynaGroups","group/definitions", diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/SetCallerInterceptor.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/SetCallerInterceptor.java index 3db8dc5..1da5411 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/SetCallerInterceptor.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/SetCallerInterceptor.java @@ -52,10 +52,10 @@ import org.rhq.enterprise.server.auth.SubjectManagerLocal; public class SetCallerInterceptor {
@Resource - EJBContext ejbContext; + private EJBContext ejbContext;
@EJB - SubjectManagerLocal subjectManager; + private SubjectManagerLocal subjectManager;
private SessionManager sessionManager = SessionManager.getInstance();
@@ -76,8 +76,9 @@ public class SetCallerInterceptor { caller = subjectManager.getSubjectByName(p.getName()); }
- if (caller==null) + if (caller==null) { throw new IllegalAccessException("No calling principal provided"); + }
// Get Subject with a session caller = sessionManager.put(caller); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/StatusHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/StatusHandlerBean.java index 23bbd4b..a6c81b3 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/StatusHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/StatusHandlerBean.java @@ -55,9 +55,9 @@ public class StatusHandlerBean extends AbstractRestBean {
@EJB - SystemInfoManagerLocal infoMgr; + private SystemInfoManagerLocal infoMgr; @EJB - ServerManagerLocal serverManager; + private ServerManagerLocal serverManager;
@GZIP @ApiOperation(value="Retrieve the current configured state of the server along with some runtime information." + diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java index 9851425..cd57b67 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java @@ -74,8 +74,6 @@ import org.rhq.enterprise.server.rest.domain.UserRest; @Stateless public class UserHandlerBean extends AbstractRestBean {
- // private final Log log = LogFactory.getLog(UserHandlerBean.class); - /** * List of favorite {@link org.rhq.core.domain.resource.Resource} id's, delimited by '|' characters. Default is "". */ @@ -88,10 +86,10 @@ public class UserHandlerBean extends AbstractRestBean { public static final String GROUP_HEALTH_GROUPS = ".dashContent.grouphealth.groups";
@EJB - SubjectManagerLocal subjectManager; + private SubjectManagerLocal subjectManager;
@EJB - ResourceManagerLocal resourceManager; + private ResourceManagerLocal resourceManager;
@GZIP @GET @@ -112,10 +110,12 @@ public class UserHandlerBean extends AbstractRestBean { ResourceWithType rwt = fillRWT(res, uriInfo); ret.add(rwt); } catch (Exception e) { - if (e instanceof ResourceNotFoundException) + if (e instanceof ResourceNotFoundException) { log.debug("Favorite resource with id " + id + " not found - not returning to the user"); - else + } + else { log.warn("Retrieving resource with id " + id + " failed: " + e.getLocalizedMessage()); + } } } Response.ResponseBuilder builder; @@ -151,11 +151,12 @@ public class UserHandlerBean extends AbstractRestBean { ResourceGroup res = resourceGroupManager.getResourceGroup(caller, id); GroupRest rwt = fillGroup(res, uriInfo); ret.add(rwt); - } catch (Exception e) { - if (e instanceof ResourceGroupNotFoundException) - log.debug("Favorite group with id " + id + " not found - not returning to the user"); - else - log.warn("Retrieving group with id " + id + " failed: " + e.getLocalizedMessage()); + } + catch (ResourceGroupNotFoundException e) { + log.debug("Favorite group with id " + id + " not found - not returning to the user"); + } + catch (Exception e) { + log.warn("Retrieving group with id " + id + " failed: " + e.getLocalizedMessage()); } } Response.ResponseBuilder builder; @@ -222,8 +223,8 @@ public class UserHandlerBean extends AbstractRestBean { @Path("favorites/group/{id}") @ApiOperation(value = "Remove a group from favorites") public void removeResourceGroupFromFavorites(@ApiParam(name = "id", value = "Id of the group") - @PathParam("id") - int id) { + @PathParam("id") int id) { + Set<Integer> favIds = getGroupIdsForFavorites(); if (favIds.contains(id)) { favIds.remove(id); @@ -242,8 +243,9 @@ public class UserHandlerBean extends AbstractRestBean { HttpHeaders headers) {
Subject subject = subjectManager.getSubjectByName(loginName); - if (subject == null) + if (subject == null) { throw new StuffNotFoundException("User with login " + loginName); + }
EntityTag eTag = new EntityTag(Long.toOctalString(subject.hashCode())); Response.ResponseBuilder builder = request.evaluatePreconditions(eTag); @@ -273,7 +275,8 @@ public class UserHandlerBean extends AbstractRestBean { PropertySimple prop = conf.getSimple(RESOURCE_HEALTH_RESOURCES); if (prop == null) { conf.put(new PropertySimple(RESOURCE_HEALTH_RESOURCES, builder.toString())); - } else { + } + else { prop.setStringValue(builder.toString()); } caller.setUserConfiguration(conf); @@ -290,7 +293,8 @@ public class UserHandlerBean extends AbstractRestBean { PropertySimple prop = conf.getSimple(GROUP_HEALTH_GROUPS); if (prop == null) { conf.put(new PropertySimple(GROUP_HEALTH_GROUPS, builder.toString())); - } else { + } + else { prop.setStringValue(builder.toString()); } caller.setUserConfiguration(conf); @@ -308,13 +312,22 @@ public class UserHandlerBean extends AbstractRestBean {
private Set<Integer> getGroupIdsForFavorites() { Configuration conf = caller.getUserConfiguration(); - if (conf==null) + if (conf==null) { return new HashSet<Integer>(); + } String favsString = conf.getSimpleValue(GROUP_HEALTH_GROUPS, ""); Set<Integer> favIds = getIdsFromFavString(favsString); return favIds; }
+ /** + * Parse the String with favorites. + * The list of favorites is stored in the server as a list + * of ids separated by a pipe '|' character. + * + * @param favsString String as stored in for the user + * @return Set of ids of the favorites + */ private Set<Integer> getIdsFromFavString(String favsString) { Set<Integer> favIds = new TreeSet<Integer>(); if (!favsString.isEmpty()) { @@ -326,13 +339,21 @@ public class UserHandlerBean extends AbstractRestBean { return favIds; }
+ /** + * Create the String with favorites to store for the user + * The list of favorites is stored in the server as a list + * of ids separated by a pipe '|' character + * @param favIds Set of favorite ids + * @return String representation + */ private StringBuilder buildFavStringFromSet(Set<Integer> favIds) { StringBuilder builder = new StringBuilder(); Iterator<Integer> iter = favIds.iterator(); while (iter.hasNext()) { builder.append(iter.next()); - if (iter.hasNext()) + if (iter.hasNext()) { builder.append('|'); + } } return builder; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java index 2224732..f40d92c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java @@ -43,8 +43,9 @@ public class AlertDefinitionRest { List<AlertConditionRest> conditions = new ArrayList<AlertConditionRest>(); List<AlertNotificationRest> notifications = new ArrayList<AlertNotificationRest>(); String dampeningCategory; - String dampeningCount; - String dampeningPeriod; + int dampeningCount; + int dampeningPeriod; + String dampeningUnit; List<Link> links = new ArrayList<Link>();
@SuppressWarnings("unused") @@ -138,24 +139,33 @@ public class AlertDefinitionRest { this.dampeningCategory = dampeningCategory; }
- @ApiProperty(value = "Number of occurrences of an alert (in a given period)") - public String getDampeningCount() { + @ApiProperty(value = "Number of occurrences of an alert (in a given period). Valid values are > -1") + public int getDampeningCount() { return dampeningCount; }
- public void setDampeningCount(String dampeningCount) { + public void setDampeningCount(int dampeningCount) { this.dampeningCount = dampeningCount; }
@ApiProperty( value = "Period to check events. Only applicable for PARTIAL_COUNT, DURATION_COUNT, INVERSE_COUNT") - public String getDampeningPeriod() { + public int getDampeningPeriod() { return dampeningPeriod; }
- public void setDampeningPeriod(String dampeningPeriod) { + public void setDampeningPeriod(int dampeningPeriod) { this.dampeningPeriod = dampeningPeriod; }
+ @ApiProperty( value = "Unit of the dampening period.",allowableValues = "MINUTES, HOURS, DAYS, WEEKS" ) + public String getDampeningUnit() { + return dampeningUnit; + } + + public void setDampeningUnit(String dampeningUnit) { + this.dampeningUnit = dampeningUnit; + } + public List<Link> getLinks() { return links; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/helper/ConfigurationHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/helper/ConfigurationHelper.java new file mode 100644 index 0000000..073966d --- /dev/null +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/helper/ConfigurationHelper.java @@ -0,0 +1,432 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2013 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +package org.rhq.enterprise.server.rest.helper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.PropertyDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertySimpleType; + +/** + * Helper class to deal with configuration objects + * @author Heiko W. Rupp + */ +public class ConfigurationHelper { + + /** + * Convert the passed map into a RHQ configuration object + * @param in Map with items to convert. Map.Entry.Key is the name of the property and Map.Entry.Value the value + * @return a new Configuration object + */ + public static Configuration mapToConfiguration(Map<String, Object> in) { + Configuration config = new Configuration(); + Set<String> mapKeys = in.keySet(); + for (String mapKey : mapKeys) { + Object mapValue = in.get(mapKey); + + if (mapValue instanceof Map) { + Map<String,Object> map = (Map<String, Object>) mapValue; + PropertyMap propertyMap = getPropertyMap(mapKey, map); + config.put(propertyMap); + } + else if (mapValue instanceof List) { + List<Object> objects = (List<Object>) mapValue; + PropertyList propertyList = getPropertyList(mapKey, objects); + config.put(propertyList); + } + else { + config.put(new PropertySimple(mapKey,mapValue)); + } + } + + return config; + + } + + public static Map<String,Object> configurationToMap(Configuration configuration, ConfigurationDefinition definition, + boolean strict) { + + Map<String,Object> result = new HashMap<String, Object>(); + + if (configuration==null) { + return result; + } + + if (configuration.getProperties().isEmpty()) { + return result; + } + + for (Property property : configuration.getProperties()) { + + String propertyName = property.getName(); + PropertyDefinition propertyDefinition = definition.get(propertyName); + if (propertyDefinition==null) { + if (strict) { + throw new IllegalArgumentException("No definition for property " + propertyName + "found"); + } else { + // no definition found and not strict, so skip the property + continue; + } + } + + Object target = convertProperty(property, propertyDefinition, strict); + result.put(propertyName,target); + } + + return result; + } + + private static Object convertProperty(Property property, PropertyDefinition propertyDefinition, boolean strict) { + Object target; + + if (property instanceof PropertyMap) { + PropertyMap propertyMap = (PropertyMap) property; + target = getInnerMap(propertyMap,(PropertyDefinitionMap) propertyDefinition, strict); + } else if (property instanceof PropertyList) { + PropertyList propertyList = (PropertyList) property; + target = getInnerList(propertyList, (PropertyDefinitionList)propertyDefinition, strict); + } else { + target= convertSimplePropertyValue((PropertySimple) property, + ((PropertyDefinitionSimple)propertyDefinition)); + } + return target; + } + + private static Map<String, Object> getInnerMap(PropertyMap propertyMap, PropertyDefinitionMap propertyDefinition, + boolean strict) { + + Map<String, Property> map = propertyMap.getMap(); + Map<String,Object> result = new HashMap<String, Object>(map.size()); + + Set<String> names = map.keySet(); + for (String name : names ) { + Property property = map.get(name); + PropertyDefinition definition = propertyDefinition.get(name); + + Object target = convertProperty(property,definition, strict); + result.put(name,target); + } + + return result; + } + + private static List<Object> getInnerList(PropertyList propertyList, PropertyDefinitionList definition, + boolean strict) { + + List<Object> result = new ArrayList<Object>(propertyList.getList().size()); + + if (definition==null) { + if (strict) { + throw new IllegalArgumentException("No Definition exists for " + propertyList.getName()); + } else { + return result; + } + } + + + PropertyDefinition memberDefinition = definition.getMemberDefinition(); + for (Property property : propertyList.getList()) { + Object target = convertProperty(property,memberDefinition, strict); + result.add(target); + } + + return result; + } + + private static PropertyList getPropertyList(String propertyName, List<Object> objects) { + PropertyList propertyList = new PropertyList(propertyName); + + Property target; + for (Object o : objects) { + if (o instanceof List) { + // Not sure if we actually support that at all inside RHQ + List list = (List) o; + target = getPropertyList(propertyName,list); // TODO propertyName? + } else if (o instanceof Map) { + Map map = (Map) o; + target = getPropertyMap(propertyName,map); // TODO propertyName? + } else { + target = new PropertySimple(propertyName,o); + } + propertyList.add(target); + } + return propertyList; + } + + private static PropertyMap getPropertyMap(String propertyName, Map<String, Object> map) { + PropertyMap propertyMap = new PropertyMap(propertyName); + Set<String> keys = map.keySet(); + for (String key : keys) { + Object value = map.get(key); + Property target; + if (value instanceof Map) { + target = getPropertyMap(key, (Map)value); + } else if (value instanceof List) { + target = getPropertyList(key, (List)value); + } else { + target = new PropertySimple(key,value); + } + propertyMap.put(target); + } + return propertyMap; + } + + /** + * Convert the passed simple property into an object of a matching type. The + * type is determined with the help of the passed definition + * @param property Property to convert + * @param definition Definition of the Property + * @return Object with the correct type + */ + public static Object convertSimplePropertyValue(PropertySimple property, PropertyDefinitionSimple definition) { + + if (definition==null) { + throw new IllegalArgumentException("No definition provided"); + } + + if (property==null) { + return null; + } + + PropertySimpleType type = definition.getType(); + String val = property.getStringValue(); + + Object ret; + + switch (type) { + case STRING: + ret= val; + break; + case INTEGER: + ret= Integer.valueOf(val); + break; + case BOOLEAN: + ret= Boolean.valueOf(val); + break; + case LONG: + ret= Long.valueOf(val); + break; + case FLOAT: + ret= Float.valueOf(val); + break; + case DOUBLE: + ret= Double.valueOf(val); + break; + default: + ret= val; + } + return ret; + } + + + /** + * Check that the passed configuration is valid wrt the passed definition + * @param configuration A Configuration to check + * @param definition A Definition to check the Configuration against + * @return List of validation failure messages. List is empty if no errors were found. + */ + public static List<String> checkConfigurationWrtDefinition(Configuration configuration, + ConfigurationDefinition definition) { + + List<String> messages = new ArrayList<String>(); + + if (configuration==null) { + messages.add("Configuration is null"); + + } + + if (definition==null) { + messages.add("Definition is null"); + } + + if (configuration==null || definition==null) { + return messages; + } + + // Basic validation is done, now have a look at the properties + + for (PropertyDefinition propDef : definition.getPropertyDefinitions().values()) { + String name = propDef.getName(); + Property property = configuration.get(name); + + checkProperty(messages, propDef, property); + } + + + return messages; + } + + /** + * Recursively check the passed property against the passed property definition + * @param messages Validation error messages are added here + * @param propertyDefinition The definition to check against + * @param property The property to check + */ + private static void checkProperty(List<String> messages, PropertyDefinition propertyDefinition, + Property property) { + + String name = propertyDefinition.getName(); + + // If a property is required and not present we can bail out early + if (propertyDefinition.isRequired() && property ==null) { + messages.add("Required property [" + name + "] not found"); + return; + } + + // If a property is not required and is null, it is fine either + if (!propertyDefinition.isRequired() && property==null) { + return; + } + + // Check if the property and definition are of the same kind (simple, map, list) + boolean good = checkIfCompatible(propertyDefinition, property,messages); + // We only need to do this dance if the kinds are matching + if (good) { + if (property instanceof PropertySimple) { + checkDataTypeOfSimpleProperty((PropertyDefinitionSimple) propertyDefinition, (PropertySimple) property, + messages); + } else if (property instanceof PropertyList) { + PropertyList propertyList = (PropertyList) property; + PropertyDefinitionList propertyDefinitionList = (PropertyDefinitionList) propertyDefinition; + for (Property prop : propertyList.getList()) { + checkProperty(messages, propertyDefinitionList.getMemberDefinition(), prop); + } + } else if (property instanceof PropertyMap) { + PropertyMap propertyMap = (PropertyMap) property; + PropertyDefinitionMap propertyDefinitionMap = (PropertyDefinitionMap) propertyDefinition; + for (Map.Entry<String,Property> entry : propertyMap.getMap().entrySet()) { + Property prop = entry.getValue(); + PropertyDefinition definition = propertyDefinitionMap.get(name); + checkProperty(messages,definition,prop); + } + } + } + } + + /** + * Check that for a Property that is defined with one of the non-string data types, the + * stored value is actually valid according to this data type. + * This also checks if a property is required, but its value is actually null. + * + * @param propDef Definition of the property, that contains the data type + * @param property The property to check + * @param messages Validation issues are added to this list. + */ + private static void checkDataTypeOfSimpleProperty(PropertyDefinitionSimple propDef, PropertySimple property, + List<String> messages) { + + String prefix = "Property [" + property.getName() + "] is "; + String val = property.getStringValue(); + + // If a property is not required and its value is null, we can just return + if (!propDef.isRequired() && property.getStringValue()==null) { + return; + } + + // If a property is required and its value is null, we can just return + if (propDef.isRequired() && property.getStringValue()==null) { + messages.add(prefix + "required but was 'null'"); + return; + } + + + switch (propDef.getType()) { + case DOUBLE: + try { + Double.parseDouble(property.getStringValue()); + } catch (NumberFormatException nfe ) { + messages.add(prefix + "no double : " + val); + } + break; + case FLOAT: + float f; + try { + f = Float.parseFloat(property.getStringValue()); + } catch (NumberFormatException nfe ) { + messages.add(prefix + "no float : " + val); + break; + } + if (f < Float.MIN_VALUE || f > Float.MAX_VALUE) { + messages.add(prefix + "no valid float : " + val); + } + break; + case INTEGER: + try { + Integer.parseInt(property.getStringValue()); + } catch (NumberFormatException nfe ) { + messages.add(prefix + "no integer : " + val); + } + break; + case LONG: + try { + Long.parseLong(property.getStringValue()); + } catch (NumberFormatException nfe ) { + messages.add(prefix + "no long : " + val); + } + break; + case BOOLEAN: + String s = val.toLowerCase(); + if (!(s.equals("true") || s.equals("false"))) { + messages.add(prefix + "no boolean : " + val); + } + break; + default: + // Strings and long strings and directories and files + } + } + + /** + * Check if the Kind of Definition and Property match. I.e. if a PropertyMap corresponds to a PropertyDefinitionMap + * @param propDef PropertyDefinition to match + * @param property Property to match with the definition + * @param messages List of messages to add validation errors to. + * @return true if the kinds are matching + */ + private static boolean checkIfCompatible(final PropertyDefinition propDef, final Property property, + final List<String> messages) { + + boolean good = false ; + if (propDef instanceof PropertyDefinitionSimple && property instanceof PropertySimple) { + good = true; + } else if (propDef instanceof PropertyDefinitionMap && property instanceof PropertyMap) { + good = true; + } else if (propDef instanceof PropertyDefinitionList && property instanceof PropertyList) { + good = true; + } + if (!good) { + String name = propDef.getName(); + messages.add("The type of property for [" + name + "] does not match the definition"); + } + return good; + } +} diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java new file mode 100644 index 0000000..7e20630 --- /dev/null +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java @@ -0,0 +1,756 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2013 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package org.rhq.enterprise.server.configuration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.testng.annotations.Test; + +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.PropertyDefinitionList; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; +import org.rhq.core.domain.configuration.definition.PropertySimpleType; +import org.rhq.core.domain.util.StringUtils; +import org.rhq.enterprise.server.rest.helper.ConfigurationHelper; + +/** + * Test the ConfigurationHelper class + * @author Heiko W. Rupp + */ +public class ConfigurationHelperTest { + + @Test + public void testConvertSimpleMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + map.put("Answer",42); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2; + + PropertySimple hello = config.getSimple("Hello"); + assert hello !=null; + assert hello.getStringValue().equals("World"); + + PropertySimple qu = config.getSimple("Answer"); + assert qu!=null; + Integer value = qu.getIntegerValue(); + assert value !=null; + assert value ==42; + } + + @Test + public void testConvertWithNestedMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(3); + map.put("Hello","World"); + map.put("Answer",42); + Map<String,Object> inner = new HashMap<String, Object>(1); + inner.put("Foo","Bar"); + map.put("Inner",inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==3 : "Expected 3 props, got " + properties.size(); + + Property prop = config.get("Inner"); + assert prop!=null; + assert prop instanceof PropertyMap : "Inner is no map"; + + PropertyMap pm = (PropertyMap) prop; + Map<String, Property> innerMap = pm.getMap(); + assert innerMap.size()==1; + + assert inner.containsKey("Foo"); + + } + + @Test + public void testConvertListOfMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + List<Map<String,Object>> list = new ArrayList<Map<String, Object>>(); + map.put("list",list); + + Map<String,Object> inner = new HashMap<String, Object>(1); + inner.put("Foo","Bar"); + list.add(inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2 : "Expected 2 props, got " + properties.size(); + + Property prop = config.get("Inner"); + assert prop==null; + + prop = config.get("list"); + assert prop instanceof PropertyList : "list is no list"; + + PropertyList pl = (PropertyList) prop; + List<Property> propertyList = pl.getList(); + assert propertyList.size()==1; + PropertyMap innerMapProperty = (PropertyMap) propertyList.get(0); + + Map<String, Property> propertyMap = innerMapProperty.getMap(); + assert propertyMap.size()==1; + Map<String,Property> innerMap = propertyMap; + + assert innerMap.containsKey("Foo"); + Property property = innerMapProperty.get("Foo"); + assert property != null; + assert property instanceof PropertySimple; + PropertySimple ps = (PropertySimple) property; + assert ps.getStringValue().equals("Bar"); + + } + + @Test + public void testConvertWithListOfSimple() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + map.put("Answer",42); + List<String> inner = new ArrayList<String>(2); + inner.add("Foo"); + inner.add("Bar"); + map.put("Inner", inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==3 : "Expected 3 props, got " + properties.size(); + + Property prop = config.get("Inner"); + assert prop!=null; + assert prop instanceof PropertyList : "Inner is no list"; + + PropertyList plist = (PropertyList) prop; + List<Property> propertyList = plist.getList(); + assert propertyList.size()==2; + for (Property innerProp : propertyList) { + assert innerProp instanceof PropertySimple; + PropertySimple ps = (PropertySimple) innerProp; + assert ps.getName().equals("Inner"); + assert ps.getStringValue().equals("Foo") || ps.getStringValue().equals("Bar"); + } + + } + + @Test + public void testConvertAndValidateBoolean() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(); + map.put("bool1","true"); + map.put("bool2","TruE"); + map.put("bool3","fAlSe"); + map.put("bool4", "false"); + map.put("bool5", 42); + map.put("bool6", "Hugo"); + map.put("bool7",null); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==7 : "Expected 7 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("bool1","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool2","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool3","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool4","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool5","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool6","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool7","A boolean",true, PropertySimpleType.BOOLEAN)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==3 : "Expected 3 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n "); + + } + + @Test + public void testConvertAndValidateMissingRequired() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(1); + map.put("bool1","true"); + // required 2nd entry is missing + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==1 : "Expected 1 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("bool1","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("bool2","A boolean",true, PropertySimpleType.BOOLEAN)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==1 : "Expected 1 error, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n "); + + } + + @Test + public void testConvertAndValidateNotRequiredButNull() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(1); + map.put("bool1","true"); + map.put("optional",null); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2 : "Expected 2 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("bool1","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("optional","null string",false, PropertySimpleType.STRING)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==0 : "Expected 0 error, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n "); + + } + + @Test + public void testConvertAndValidateMismatchingKind() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(1); + map.put("bool1","true"); + map.put("optional",null); + Map<String,Object> inner = new HashMap<String, Object>(1); + inner.put("Foo","Bar"); + map.put("Inner",inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==3 : "Expected 3 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("bool1","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("optional","null string",false, PropertySimpleType.STRING)); + // We define Inner as a simple property, but the user supplied a map + definition.put(new PropertyDefinitionSimple("Inner","null string",false, PropertySimpleType.STRING)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==1 : "Expected 1 error, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n "); + + } + + @Test + public void testConvertAndValidateMismatchingKind2() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(1); + map.put("bool1","true"); + map.put("optional",null); + map.put("Inner","Frobnitz"); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==3 : "Expected 3 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("bool1","A boolean",true, PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("optional","null string",false, PropertySimpleType.STRING)); + // We define Inner as a list property, but the user supplied a simple one + definition.put(new PropertyDefinitionList("Inner","Bla",true, + new PropertyDefinitionSimple("Inner","fasel",true,PropertySimpleType.STRING))); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==1 : "Expected 1 error, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n "); + + } + + @Test + public void testConvertAndValidateNumeric() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("float1",1.1f); + map.put("float2",Double.MAX_VALUE); + map.put("float3",null); + map.put("float4","abc"); + + map.put("double1",1.1d); + map.put("double2",null); + map.put("double3","hugo"); + + map.put("int1",42); + map.put("int2",Long.MAX_VALUE); + map.put("int3",null); + map.put("int4","abc"); + + map.put("long1",-5); + map.put("long2",null); + map.put("long3","Frobnitz"); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==14 : "Expected 14 props but got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla","For testing"); + definition.put(new PropertyDefinitionSimple("float1","A float",true, PropertySimpleType.FLOAT)); + definition.put(new PropertyDefinitionSimple("float2","A float",true, PropertySimpleType.FLOAT)); + definition.put(new PropertyDefinitionSimple("float3","A float",true, PropertySimpleType.FLOAT)); + definition.put(new PropertyDefinitionSimple("float4","A float",true, PropertySimpleType.FLOAT)); + + definition.put(new PropertyDefinitionSimple("double1","A double",true, PropertySimpleType.DOUBLE)); + definition.put(new PropertyDefinitionSimple("double2","A double",true, PropertySimpleType.DOUBLE)); + definition.put(new PropertyDefinitionSimple("double3","A double",true, PropertySimpleType.DOUBLE)); + + definition.put(new PropertyDefinitionSimple("int1","An int",true, PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("int2","An int",true, PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("int3","An int",true, PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("int4","An int",true, PropertySimpleType.INTEGER)); + + definition.put(new PropertyDefinitionSimple("long1","A long",true, PropertySimpleType.LONG)); + definition.put(new PropertyDefinitionSimple("long2","A long",true, PropertySimpleType.LONG)); + definition.put(new PropertyDefinitionSimple("long3","A long",true, PropertySimpleType.LONG)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==10 : "Expected 10 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n"); + + } + + @Test + public void testValidateNullConfiguration() throws Exception { + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(null,new ConfigurationDefinition("bla",null)); + assert errors != null; + assert errors.size()==1; + + } + + @Test + public void testValidateNullDefinition() throws Exception { + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(new Configuration(),null); + assert errors != null; + assert errors.size()==1; + + } + + @Test + public void testConvertAndValidateSimpleMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + map.put("Answer",42); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("Hello",null,true,PropertySimpleType.STRING)); + definition.put(new PropertyDefinitionSimple("Answer",null,true,PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("Optional",null,false,PropertySimpleType.INTEGER)); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2; + + PropertySimple hello = config.getSimple("Hello"); + assert hello !=null; + assert hello.getStringValue().equals("World"); + + PropertySimple qu = config.getSimple("Answer"); + assert qu!=null; + Integer integerValue = qu.getIntegerValue(); + assert integerValue !=null; + assert integerValue ==42; + } + + @Test + public void testConvertValidateNonRequiredNotPresent() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==0 : "Expected 0 props, got " + properties.size(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("Answer",null,false,PropertySimpleType.INTEGER)); + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==0 : "Expected 0 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n"); + + } + + @Test + public void testConvertAndValidateListOfMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + List<Map<String,Object>> list = new ArrayList<Map<String, Object>>(); + map.put("list",list); + + Map<String,Object> inner = new HashMap<String, Object>(1); + inner.put("Foo","Bar"); + list.add(inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2 : "Expected 2 props, got " + properties.size(); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("Hello",null,true,PropertySimpleType.STRING)); + definition.put(new PropertyDefinitionSimple("Answer",null,false,PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionList("list",null,true, + new PropertyDefinitionMap("list",null,true, + new PropertyDefinitionSimple("list",null,true,PropertySimpleType.STRING)))); + definition.put(new PropertyDefinitionSimple("aString",null,false,PropertySimpleType.INTEGER)); + + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==0 : "Expected 0 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n"); + + } + + @Test + public void testConvertAndValidateMapOfMap() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + Map<String,Map<String,Object>> list = new HashMap<String, Map<String, Object>>(); + map.put("list",list); + + Map<String,Object> inner = new HashMap<String, Object>(1); + inner.put("Foo","Bar"); + list.put("outer", inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2 : "Expected 2 props, got " + properties.size(); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("Hello",null,true,PropertySimpleType.STRING)); + definition.put(new PropertyDefinitionMap("list",null,true, + new PropertyDefinitionMap("list",null,true, + new PropertyDefinitionSimple("list",null,true,PropertySimpleType.STRING)))); + + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==0 : "Expected 0 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n"); + + } + + @Test + public void testConvertAndValidateMapWithListOfSimple() throws Exception { + + Map<String,Object> map = new HashMap<String, Object>(2); + map.put("Hello","World"); + + Map<String,List<String>> list = new HashMap<String, List<String>>(); + map.put("list",list); + + List<String> inner = new ArrayList<String>(); + inner.add("Foo"); + inner.add("Bar"); + list.put("outer", inner); + + Configuration config = ConfigurationHelper.mapToConfiguration(map); + + assert config!=null; + Collection<Property> properties = config.getProperties(); + assert properties.size()==2 : "Expected 2 props, got " + properties.size(); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("Hello",null,true,PropertySimpleType.STRING)); + definition.put(new PropertyDefinitionMap("list",null,true, + new PropertyDefinitionList("list",null,true, + new PropertyDefinitionSimple("list",null,true,PropertySimpleType.STRING)))); + + + List<String> errors = ConfigurationHelper.checkConfigurationWrtDefinition(config,definition); + + assert errors!=null; + assert errors.size()==0 : "Expected 0 errors, but got " + errors.size() + "\n" + StringUtils.getListAsString(errors,",\n"); + + } + + @Test + public void testConfigToMapSimple() throws Exception { + + Configuration config = new Configuration(); + config.put(new PropertySimple("number",42)); + config.put(new PropertySimple("string","Hello")); + config.put(new PropertySimple("bool",true)); + config.put(new PropertySimple("float",1.1f)); + config.put(new PropertySimple("double",2.3d)); + config.put(new PropertySimple("long",Long.MAX_VALUE)); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("number",null,false,PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)); + definition.put(new PropertyDefinitionSimple("bool",null,false,PropertySimpleType.BOOLEAN)); + definition.put(new PropertyDefinitionSimple("float",null,false,PropertySimpleType.FLOAT)); + definition.put(new PropertyDefinitionSimple("double",null,false,PropertySimpleType.DOUBLE)); + definition.put(new PropertyDefinitionSimple("long",null,false,PropertySimpleType.LONG)); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, true); + + assert map != null; + assert map.entrySet().size()==6; + + assert map.containsKey("number"); + assert map.containsKey("string"); + + assert map.get("number") != null; + assert (Integer)map.get("number") == 42; + + assert map.get("string") != null; + assert map.get("string").equals("Hello"); + + assert (Boolean)map.get("bool") == true; + + assert map.get("float") != null; + assert (Float)map.get("float") ==1.1f; + + assert map.get("double") != null; + assert (Double) map.get("double") ==2.3d; + + assert map.get("long") != null; + assert (Long)map.get("long") == Long.MAX_VALUE; + + } + + @Test + public void testEmptyConfigToMap() throws Exception { + + Configuration config = new Configuration(); + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("number",null,false,PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, true); + + assert map != null; + assert map.entrySet().size()==0; + + + } + + @Test + public void testNullConfigToMap() throws Exception { + + Configuration config = null; + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionSimple("number",null,false,PropertySimpleType.INTEGER)); + definition.put(new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, true); + + assert map != null; + assert map.entrySet().size()==0; + + } + + @Test + public void testConfigToMapComplexList() throws Exception { + + Configuration config = new Configuration(); + PropertyList propertyList = new PropertyList("aList"); + propertyList.add(new PropertySimple("string", "Hello")); + propertyList.add(new PropertySimple("string", "World")); + config.put(propertyList); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionList("aList",null,false, + new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING))); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, true); + + assert map != null; + assert map.entrySet().size()==1; + + assert map.containsKey("aList"); + + } + + @Test + public void testConfigToMapComplexMap() throws Exception { + + Configuration config = new Configuration(); + PropertyMap propertyMap = new PropertyMap("aMap"); + config.put(propertyMap); + PropertyList propertyList = new PropertyList("aList"); + propertyList.add(new PropertySimple("string", "Hello")); + propertyList.add(new PropertySimple("string", "World")); + propertyMap.put(propertyList); + + propertyMap.put(new PropertySimple("aString","Frobnitz")); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionMap("aMap",null,false, + new PropertyDefinitionList("aList",null,false, + new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)), + new PropertyDefinitionSimple("aString",null,false,PropertySimpleType.STRING))); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, true); + + assert map != null; + assert map.entrySet().size()==1; + + assert map.containsKey("aMap"); + assert map.get("aMap") instanceof Map; + Map<String,Object> innerMap = (Map<String, Object>) map.get("aMap"); + + assert innerMap.containsKey("aString"); + assert innerMap.containsKey("aList"); + + } + + @Test + public void testConfigToMapComplexMapWithBadSetupStrict() throws Exception { + + Configuration config = new Configuration(); + PropertyMap propertyMap = new PropertyMap("aMap"); + config.put(propertyMap); + PropertyList propertyList = new PropertyList("aList"); + propertyList.add(new PropertySimple("string", "Hello")); + propertyList.add(new PropertySimple("string", "World")); + propertyMap.put(propertyList); + + propertyMap.put(new PropertySimple("aString","Frobnitz")); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionMap("aMap",null,false, + new PropertyDefinitionList("aBla",null,false, + new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)), + new PropertyDefinitionSimple("aFoo",null,false,PropertySimpleType.STRING))); + + try { + ConfigurationHelper.configurationToMap(config,definition, true); + assert false; + } catch (IllegalArgumentException iae ) { + System.out.println("Yep, caught the error"); + } + + + } + + @Test + public void testConfigToMapComplexMapWithBadSetupLenient() throws Exception { + + Configuration config = new Configuration(); + PropertyMap propertyMap = new PropertyMap("aMap"); + config.put(propertyMap); + PropertyList propertyList = new PropertyList("aList"); + propertyList.add(new PropertySimple("string", "Hello")); + propertyList.add(new PropertySimple("string", "World")); + propertyMap.put(propertyList); + + propertyMap.put(new PropertySimple("aString","Frobnitz")); + + + ConfigurationDefinition definition = new ConfigurationDefinition("bla",null); + definition.put(new PropertyDefinitionMap("aMap",null,false, + new PropertyDefinitionList("aBla",null,false, + new PropertyDefinitionSimple("string",null,false,PropertySimpleType.STRING)), + new PropertyDefinitionSimple("aFoo",null,false,PropertySimpleType.STRING))); + + Map<String,Object> map = ConfigurationHelper.configurationToMap(config,definition, false); + + assert map != null; + assert map.entrySet().size()==1; + + assert map.containsKey("aMap"); + + } + + @Test + public void testConvertSingleValueNoProperty() throws Exception { + + Object o = ConfigurationHelper.convertSimplePropertyValue(null,new PropertyDefinitionSimple("dummy",null,false,PropertySimpleType.STRING)); + + assert o == null; + + } + + @Test + public void testConvertSingleValueNoDefinition() throws Exception { + + try { + ConfigurationHelper.convertSimplePropertyValue(new PropertySimple("foo","bar"),null); + assert false; + } + catch (IllegalArgumentException iae) { + System.out.println("Yep, good"); + } + + } +} diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java index 3d9f735..fca0f50 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java @@ -266,8 +266,8 @@ public class AlertTest extends AbstractBase { .expect() .statusCode(201) .body("dampeningCategory",is("NONE")) - .body("dampeningCount",is("0")) - .body("dampeningPeriod",is("0")) + .body("dampeningCount",is(0)) + .body("dampeningPeriod",is(0)) .when() .post("/alert/definitions") .as(AlertDefinition.class); @@ -369,8 +369,8 @@ public class AlertTest extends AbstractBase { alertDefinition.setEnabled(false); alertDefinition.setPriority("LOW"); alertDefinition.setDampeningCategory("PARTIAL_COUNT"); - alertDefinition.setDampeningCount("3"); - alertDefinition.setDampeningPeriod("5"); + alertDefinition.setDampeningCount(3); + alertDefinition.setDampeningPeriod(5);
AlertDefinition result = given() @@ -381,8 +381,8 @@ public class AlertTest extends AbstractBase { .expect() .statusCode(201) .body("dampeningCategory",is("PARTIAL_COUNT")) - .body("dampeningCount",is("3")) - .body("dampeningPeriod",is("5")) + .body("dampeningCount",is(3)) + .body("dampeningPeriod",is(5)) .when() .post("/alert/definitions") .as(AlertDefinition.class); @@ -404,8 +404,9 @@ public class AlertTest extends AbstractBase { alertDefinition.setEnabled(false); alertDefinition.setPriority("LOW"); alertDefinition.setDampeningCategory("DURATION_COUNT"); - alertDefinition.setDampeningCount("1"); - alertDefinition.setDampeningPeriod("3 minutes"); + alertDefinition.setDampeningCount(1); + alertDefinition.setDampeningPeriod(3); + alertDefinition.setDampeningUnit("minutes");
AlertDefinition result = given() @@ -416,8 +417,9 @@ public class AlertTest extends AbstractBase { .expect() .statusCode(201) .body("dampeningCategory",is("DURATION_COUNT")) - .body("dampeningCount", is("1")) - .body("dampeningPeriod", is("3 MINUTES")) + .body("dampeningCount", is(1)) + .body("dampeningPeriod", is(3)) + .body("dampeningUnit", is("MINUTES")) .when() .post("/alert/definitions") .as(AlertDefinition.class); diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java index 713a755..e6aea1f 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java @@ -61,8 +61,9 @@ public class OperationsTest extends AbstractBase { definitionId = -1; List<Map<String,Object>> list = r.as(List.class); for (Map<String,Object> map : list) { - if (map.get("name").equals("discovery")) + if (map.get("name").equals("discovery")) { definitionId = (Integer) map.get("id"); + } }
assert definitionId !=-1 : "No discovery operation found"; @@ -85,6 +86,92 @@ public class OperationsTest extends AbstractBase { }
@Test + public void testGetDefinitionByUnknownId() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .pathParam("did",-42) + .expect() + .statusCode(404) + .when() + .get("/operation/definition/{did}"); + + } + + @Test + public void testGetDefinitionsForUnknownResource() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .queryParam("resourceId",42) + .expect() + .statusCode(404) + .when() + .get("/operation/definitions"); + } + + @Test + public void testGetDefinitionsForMissingResourceId() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .expect() + .statusCode(406) + .when() + .get("/operation/definitions"); + } + + @Test + public void testCreateScheduleByUnknownDefinitionId() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .pathParam("did",-42) + .expect() + .statusCode(406) + .when() + .post("/operation/definition/{did}"); + + } + + @Test + public void testCreateScheduleForUnknownResource() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .queryParam("resourceId", 42) + .pathParam("definitionId", definitionId) + .expect() + .statusCode(404) + .when() + .post("/operation/definition/{definitionId}"); + } + + @Test + public void testCreateScheduleForMissingResourceId() throws Exception { + + // Now retrieve that definition by id + + given() + .header(acceptJson) + .pathParam("definitionId", definitionId) + .expect() + .statusCode(406) + .when() + .post("/operation/definition/{definitionId}"); + } + + @Test public void testCreateDraftOperation() throws Exception {
Operation draft = @@ -196,8 +283,9 @@ public class OperationsTest extends AbstractBase { String history = null; List<Link> links = scheduled.getLinks(); for (Link link : links) { - if (link.getRel().equals("history")) - history = (String) link.getHref(); + if (link.getRel().equals("history")) { + history = link.getHref(); + } } assert history != null;
@@ -272,4 +360,98 @@ public class OperationsTest extends AbstractBase { } }
+ @Test + public void testOpsScheduleMissingRequiredParam() throws Exception { + + int platformId = findIdOfARealPlatform(); + + Operation draft = + given() + .header(acceptJson) + .pathParam("definitionId",definitionId) + .queryParam("resourceId",platformId) + .expect() + .statusCode(200) + .log().ifError() + .when() + .post("/operation/definition/{definitionId}") + .as(Operation.class); + + assert draft != null; + assert draft.getDefinitionId() == definitionId; + + int draftId = draft.getId(); + + // explicitly remove the param from the draft for + // the test + Map<String, Object> params = draft.getParams(); + if (params.containsKey("detailedDiscovery")) { + params.remove("detailedDiscovery"); + } + + // Update to put the new version in the server + // We don't want to submit, so the server does not + // validate and we should get a 200 back + draft.setReadyToSubmit(false); + given() + .contentType(ContentType.JSON) + .pathParam("id",draftId) + .body(draft) + .expect() + .statusCode(200) + .log().ifError() + .when() + .put("/operation/{id}"); + + + // update to schedule, lacking the required param + draft.setReadyToSubmit(true); + + given() + .contentType(ContentType.JSON) + .pathParam("id",draftId) + .body(draft) + .expect() + .statusCode(406) + .log().ifError() + .when() + .put("/operation/{id}"); + } + + @Test + public void testOpsScheduleRequiredParamWrongDataType() throws Exception { + + int platformId = findIdOfARealPlatform(); + + Operation draft = + given() + .header(acceptJson) + .pathParam("definitionId",definitionId) + .queryParam("resourceId",platformId) + .expect() + .statusCode(200) + .log().ifError() + .when() + .post("/operation/definition/{definitionId}") + .as(Operation.class); + + assert draft != null; + assert draft.getDefinitionId() == definitionId; + + int draftId = draft.getId(); + + draft.getParams().put("detailedDiscovery", 42); + draft.setReadyToSubmit(true); + + // update to schedule + given() + .contentType(ContentType.JSON) + .pathParam("id",draftId) + .body(draft) + .expect() + .statusCode(406) + .log().ifError() + .when() + .put("/operation/{id}"); + } } diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java index 5922770..d6da534 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java @@ -50,7 +50,7 @@ public class RootURITest extends AbstractBase { .expect().statusCode(200) .when().get("/");
- given().header("Accept","application/json") + given().header("Accept","application/xml") .expect().statusCode(200) .when().get("/index");
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/AlertDefinition.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/AlertDefinition.java index 5049a98..b870443 100644 --- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/AlertDefinition.java +++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/AlertDefinition.java @@ -41,8 +41,9 @@ public class AlertDefinition { List<AlertCondition> conditions = new ArrayList<AlertCondition>(); List<AlertNotification> notifications = new ArrayList<AlertNotification>(); String dampeningCategory = "NONE"; - String dampeningCount; - String dampeningPeriod; + int dampeningCount; + int dampeningPeriod; + String dampeningUnit; List<Link> links;
@@ -121,22 +122,30 @@ public class AlertDefinition { this.dampeningCategory = dampeningCategory; }
- public String getDampeningCount() { + public int getDampeningCount() { return dampeningCount; }
- public void setDampeningCount(String dampeningCount) { + public void setDampeningCount(int dampeningCount) { this.dampeningCount = dampeningCount; }
- public String getDampeningPeriod() { + public int getDampeningPeriod() { return dampeningPeriod; }
- public void setDampeningPeriod(String dampeningPeriod) { + public void setDampeningPeriod(int dampeningPeriod) { this.dampeningPeriod = dampeningPeriod; }
+ public String getDampeningUnit() { + return dampeningUnit; + } + + public void setDampeningUnit(String dampeningUnit) { + this.dampeningUnit = dampeningUnit; + } + public List<Link> getLinks() { return links; }
commit d72ac1e6bba8cbeb054a7cbfc8d7df026a09a5fc Author: Heiko W. Rupp hwr@redhat.com Date: Wed May 8 09:17:22 2013 +0200
Add another email for Thomas
diff --git a/.mailmap b/.mailmap index 384ec04..ac0fdc9 100644 --- a/.mailmap +++ b/.mailmap @@ -75,5 +75,6 @@ Test JON User test_jon@jon01.qa.atl2.redhat.com Todd B Sanders tsanders@dhcp231-67.rdu.redhat.com Torben Jäger torben@jit-central.com Thomas Segismont tsegismo@redhat.com Thomas SEGISMONT tsegismo@redhat.com +Thomas Segismont tsegismo@redhat.com Thomas Segismont tsegismont@gmail.com Thomas Segismont tsegismo@redhat.com hudson auto wnstb@yahoo.com
commit bbe5654f0755eac835b78351a8ef71a7e3398037 Author: Mike Thompson mithomps@redhat.com Date: Tue May 7 16:58:43 2013 -0700
[BZ 960646] - RFE Redesigned Availability Chart - Add disabled state cross hatch SVG pattern. Pixel tweeks.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java index 76c8f69..4e6a0ce 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java @@ -18,6 +18,9 @@ */ package org.rhq.enterprise.gui.coregui.client.inventory.common.charttype;
+import java.util.Date; +import java.util.List; + import org.rhq.core.domain.measurement.Availability; import org.rhq.core.domain.measurement.MeasurementUnits; import org.rhq.core.domain.resource.group.composite.ResourceGroupAvailability; @@ -27,9 +30,6 @@ import org.rhq.enterprise.gui.coregui.client.Messages; import org.rhq.enterprise.gui.coregui.client.util.Log; import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient;
-import java.util.Date; -import java.util.List; - /** * Contains the javascript chart definition for an implementation of the d3 availability chart. This implementation is * just a line that changes color based on availability type: up=green, down=red, orange=disabled, unknown=grey, @@ -66,7 +66,7 @@ public class AvailabilityOverUnderGraphType { // loop through the avail intervals for (Availability availability : availabilityList) { sb.append("{ "availType":"" + availability.getAvailabilityType() + "", "); - sb.append(" "availTypeMessage":"" + availability.getAvailabilityType()+ "", "); + sb.append(" "availTypeMessage":"" + availability.getAvailabilityType() + "", "); sb.append(" "availStart":" + availability.getStartTime() + ", "); // last record will be null long endTime = availability.getEndTime() != null ? availability.getEndTime() : (new Date()).getTime(); @@ -84,8 +84,9 @@ public class AvailabilityOverUnderGraphType { // loop through the group avail down intervals for (ResourceGroupAvailability groupAvailability : groupAvailabilityList) { // allows substitution for situations like WARN=MIXED for easier terminology - String availabilityTypeMessage = (groupAvailability.getGroupAvailabilityType().equals(ResourceGroupComposite.GroupAvailabilityType.WARN)) - ? MSG.chart_hover_availability_type_warn() : groupAvailability.getGroupAvailabilityType().name(); + String availabilityTypeMessage = (groupAvailability.getGroupAvailabilityType() + .equals(ResourceGroupComposite.GroupAvailabilityType.WARN)) ? MSG + .chart_hover_availability_type_warn() : groupAvailability.getGroupAvailabilityType().name();
sb.append("{ "availType":"" + groupAvailability.getGroupAvailabilityType() + "", "); sb.append(" "availTypeMessage":"" + availabilityTypeMessage + "", "); @@ -139,7 +140,6 @@ public class AvailabilityOverUnderGraphType { barOffset = 10, width = 750 - margin.left - margin.right + barOffset, height = 40 - margin.top - margin.bottom, - pixelsOffHeight = 0, svg;
@@ -161,65 +161,65 @@ public class AvailabilityOverUnderGraphType { .domain([0, 4]),
xAxis = $wnd.d3.svg.axis() - .scale(timeScale) - .ticks(12) - .tickSize(10, 0, 0) - .orient("bottom"), - - calcBarY = function(d) { - var ABOVE = -10, - BELOW = 0, - STRADDLE = -5, - offset; - - if (d.availType === 'DOWN') { - offset = BELOW; - } - else if (d.availType === 'DISABLED') { - offset = STRADDLE; - } - else if (d.availType === 'UNKNOWN') { - offset = STRADDLE; - } - else if (d.availType === 'UP') { - offset = ABOVE; - } - else if (d.availType === 'WARN') { - offset = STRADDLE; - } - else if (d.availType === 'EMPTY') { - offset = STRADDLE; - } - return yScale(0) + offset; - - }, - - calcBarFill = function(d) { - if (d.availType === 'DOWN') { - return "#FF1919"; // red - } - else if (d.availType === 'DISABLED') { - return "#FF9933"; // orange - } - else if (d.availType === 'UNKNOWN') { - return "#CCC"; // gray - } - else if (d.availType === 'UP') { - return "#198C19"; // green - } - else if (d.availType === 'WARN') { - return "#FFA500"; // yellow - } - else if (d.availType === 'EMPTY') { - return "#CCC"; // gray - } - else { - // should not ever happen, but... - console.warn("AvailabilityType not valid."); - return "#000"; //black - } - }, - svg = $wnd.d3.select(availChartContext.chartSelection).append("g") + .scale(timeScale) + .ticks(12) + .tickSize(13, 0, 0) + .orient("bottom"), + + calcBarY = function (d) { + var ABOVE = -10, + BELOW = 0, + STRADDLE = -5, + offset; + + if (d.availType === 'DOWN') { + offset = BELOW; + } + else if (d.availType === 'DISABLED') { + offset = STRADDLE; + } + else if (d.availType === 'UNKNOWN') { + offset = STRADDLE; + } + else if (d.availType === 'UP') { + offset = ABOVE; + } + else if (d.availType === 'WARN') { + offset = STRADDLE; + } + else if (d.availType === 'EMPTY') { + offset = STRADDLE; + } + return yScale(0) + offset; + + }, + + calcBarFill = function (d) { + if (d.availType === 'DOWN') { + return "#FF1919"; // red + } + else if (d.availType === 'DISABLED') { + return "url(#diagonalHatchFill)"; // grey diagonal hatches + } + else if (d.availType === 'UNKNOWN') { + return "#CCC"; // gray + } + else if (d.availType === 'UP') { + return "#198C19"; // green + } + else if (d.availType === 'WARN') { + return "#FFA500"; // orange + } + else if (d.availType === 'EMPTY') { + return "#CCC"; // gray + } + else { + // should not ever happen, but... + console.warn("AvailabilityType not valid."); + return "#000"; //black + } + }, + svg = $wnd.d3.select(availChartContext.chartSelection).append("g") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); @@ -234,11 +234,9 @@ public class AvailabilityOverUnderGraphType { }) .attr("y", function (d) { return calcBarY(d); - }) .attr("height", function (d) { return 10; - }) .attr("width", function (d) { return timeScale(+d.availEnd) - timeScale(+d.availStart); @@ -250,43 +248,43 @@ public class AvailabilityOverUnderGraphType {
// create x-axis svg.append("g") - .attr("class", "x axis") - .attr("stroke", "#50505a") - .attr("stroke-width", "0.5") - .attr("transform", "translate(0," + height + ")") - .attr("letter-spacing", "3") - .style("text-anchor", "end") - .call(xAxis); + .attr("class", "x axis") + .attr("fill", "#50505a") + .attr("stroke-width", "0.5") + .attr("transform", "translate(0," + height + ")") + .attr("letter-spacing", "3") + .style("text-anchor", "end") + .call(xAxis);
svg.append("text") - .attr("class", "availabilityLabel") - .attr("x", -40) - .attr("y", 10) - .style("font-size", "12px") - .style("font-family", "Arial, Verdana, sans-serif;") - .style("font-weight", "bold") - .attr("fill", "#003168") - .text("Availability"); + .attr("class", "availabilityLabel") + .attr("x", -40) + .attr("y", 10) + .style("font-size", "12px") + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-weight", "bold") + .attr("fill", "#003168") + .text("Availability");
svg.append("text") - .attr("class", "upLabel") - .attr("x", -5) - .attr("y", 28) - .style("font-family", "Arial, Verdana, sans-serif;") - .style("font-size", "9px") - .attr("fill", "#50505a") - .style("text-anchor", "end") - .text("UP"); + .attr("class", "upLabel") + .attr("x", -5) + .attr("y", 28) + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-size", "9px") + .attr("fill", "#50505a") + .style("text-anchor", "end") + .text("UP");
svg.append("text") - .attr("class", "downLabel") - .attr("x", -5) - .attr("y", 39) - .style("font-family", "Arial, Verdana, sans-serif;") - .style("font-size", "9px") - .attr("fill", "#50505a") - .style("text-anchor", "end") - .text("DOWN"); + .attr("class", "downLabel") + .attr("x", -5) + .attr("y", 39) + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-size", "9px") + .attr("fill", "#50505a") + .style("text-anchor", "end") + .text("DOWN");
}
@@ -306,19 +304,15 @@ public class AvailabilityOverUnderGraphType { }
function formatHovers(d) { - var hoverString, - timeFormatter = $wnd.d3.time.format(availChartContext.chartHoverTimeFormat), + var timeFormatter = $wnd.d3.time.format(availChartContext.chartHoverTimeFormat), dateFormatter = $wnd.d3.time.format(availChartContext.chartHoverDateFormat), - availStart = new Date(+d.availStart), - availEnd = new Date(+d.availEnd); + availStart = new Date(+d.availStart);
- hoverString = - '<div class="chartHoverEnclosingDiv">' + + return '<div class="chartHoverEnclosingDiv">' + '<div class="chartHoverAlignLeft"><span >' + availChartContext.hoverBarAvailabilityLabel + ': </span><span style="width:50px;">' + d.availTypeMessage + '</span></div>' + - '<div class="chartHoverAlignLeft"><span>'+ dateFormatter(availStart) + ' ' + timeFormatter(availStart) + '</span></div>' + + '<div class="chartHoverAlignLeft"><span>' + dateFormatter(availStart) + ' ' + timeFormatter(availStart) + '</span></div>' + '<div class="chartHoverAlignLeft"><span >' + availChartContext.hoverBarLabel + ': </span><span style="width:50px;">' + d.availDuration + '</span></div>' + '</div>'; - return hoverString;
}
@@ -341,7 +335,7 @@ public class AvailabilityOverUnderGraphType { availabilityGraph.draw(availChartContext); }
- }-*/; + }-*/;
public String getChartId() { return String.valueOf(entityId); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java index 7df45d1..b876c74 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java @@ -634,7 +634,7 @@ public abstract class AbstractActivityView extends EnhancedVLayout implements Re setIsModal(true); setShowModalMask(true); setWidth(950); - setHeight(350); + setHeight(370); setShowResizer(true); setCanDragResize(true); centerInPage(); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/MetricD3GraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/MetricD3GraphView.java index b590e86..f8887bf 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/MetricD3GraphView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/MetricD3GraphView.java @@ -67,6 +67,31 @@ public class MetricD3GraphView extends EnhancedVLayout { + " width="6" height="3">" + " <path d="M 0 0 6 0" style="stroke:#2E9EC2; fill:none;"/>" + " </pattern>" + + "<pattern id="diagonalHatchFill" patternUnits="userSpaceOnUse" x="0" y="0" width="105" height="105">" + + "<g style="fill:none; stroke:black; stroke-width:1">" + + "<circle cx="0" cy="0" r="1000" fill="grey"/>" + + "<path d="M0 90 l15,15"/>" + + "<path d="M0 75 l30,30"/>" + + "<path d="M0 60 l45,45"/>" + + "<path d="M0 45 l60,60"/>" + + "<path d="M0 30 l75,75"/>" + + "<path d="M0 15 l90,90"/>" + + "<path d="M0 0 l105,105"/>" + + "<path d="M15 0 l90,90"/>" + + "<path d="M30 0 l75,75"/>" + + "<path d="M45 0 l60,60"/>" + + "<path d="M60 0 l45,45"/>" + + "<path d="M75 0 l30,30"/>" + + "<path d="M90 0 l15,15"/>" + + "</g>" + + "</pattern>" + + "<pattern id="diagonalHatch" patternUnits="userSpaceOnUse" x="0" y="0" width="105" height="105">" + + "<g style="fill:none; stroke:black; stroke-width:1">" + "<path d="M0 90 l15,15"/>" + + "<path d="M0 75 l30,30"/>" + "<path d="M0 60 l45,45"/>" + "<path d="M0 45 l60,60"/>" + + "<path d="M0 30 l75,75"/>" + "<path d="M0 15 l90,90"/>" + "<path d="M0 0 l105,105"/>" + + "<path d="M15 0 l90,90"/>" + "<path d="M30 0 l75,75"/>" + "<path d="M45 0 l60,60"/>" + + "<path d="M60 0 l45,45"/>" + "<path d="M75 0 l30,30"/>" + "<path d="M90 0 l15,15"/>" + "</g>" + + "</pattern>" + " <pattern id="downStripes" patternUnits="userSpaceOnUse" x="0" y="0"" + " width="6" height="3">" + " <path d="M 0 0 6 0" style="stroke:#ff8a9a; fill:none;"/>" @@ -101,9 +126,9 @@ public class MetricD3GraphView extends EnhancedVLayout { StringBuilder divAndSvgDefs = new StringBuilder(); divAndSvgDefs .append("<div id="" - + getFullChartId() - + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink%5C" style="height:" - + getChartHeight() + "px;">"); + + getFullChartId() + + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink%5C" style="height:" + + getChartHeight() + "px;">"); divAndSvgDefs.append(getSvgDefs()); divAndSvgDefs.append("</svg></div>");
@@ -133,14 +158,11 @@ public class MetricD3GraphView extends EnhancedVLayout { graph.drawJsniChart(); }
- public String getFullChartId() { return "rChart-" + graph.getMetricGraphData().getChartId();
}
- - public Integer getChartHeight() { return graph.getMetricGraphData().getChartHeight(); } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java index d06bab2..ca8b117 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java @@ -25,7 +25,6 @@ import com.smartgwt.client.widgets.HTMLFlow; import org.rhq.core.domain.measurement.Availability; import org.rhq.core.domain.resource.group.composite.ResourceGroupAvailability; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityGraph; -import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityLineGraphType; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType; import org.rhq.enterprise.gui.coregui.client.util.Log; import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout; @@ -43,7 +42,7 @@ public class AvailabilityD3Graph extends EnhancedVLayout implements Availability public AvailabilityD3Graph(AvailabilityOverUnderGraphType graphType) { super(); this.availabilityGraphType = graphType; - setHeight(70); + setHeight(65); setWidth100(); }
@@ -83,15 +82,26 @@ public class AvailabilityD3Graph extends EnhancedVLayout implements Availability
StringBuilder divAndSvgDefs = new StringBuilder(); divAndSvgDefs.append("<div id="availChart-" + availabilityGraphType.getChartId() - + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" style="height:110px;">"); + + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" style="height:65px;">"); + divAndSvgDefs.append(getSvgDefs()); divAndSvgDefs.append("</svg></div>"); HTMLFlow graph = new HTMLFlow(divAndSvgDefs.toString()); graph.setWidth100(); - graph.setHeight(25); + graph.setHeight(65); addMember(graph);
}
+ /** + * Svg definitions for patterns and gradients to use on SVG shapes. + * @return xml String + */ + private static String getSvgDefs() { + return " <defs>"+ + "<pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"> <path d="M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2" /> </pattern>" + + "</defs>"; + } + @Override public void destroy() { super.destroy();
commit ee5255b684d733fa01989930676f5d0e7e17d51e Author: mtho11 mikecthompson@gmail.com Date: Mon May 6 14:23:28 2013 -0700
[BZ 960646] - RFE Redesigned Availability Charts.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java new file mode 100644 index 0000000..76c8f69 --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/AvailabilityOverUnderGraphType.java @@ -0,0 +1,381 @@ +/* + * 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.enterprise.gui.coregui.client.inventory.common.charttype; + +import org.rhq.core.domain.measurement.Availability; +import org.rhq.core.domain.measurement.MeasurementUnits; +import org.rhq.core.domain.resource.group.composite.ResourceGroupAvailability; +import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; +import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.Messages; +import org.rhq.enterprise.gui.coregui.client.util.Log; +import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient; + +import java.util.Date; +import java.util.List; + +/** + * Contains the javascript chart definition for an implementation of the d3 availability chart. This implementation is + * just a line that changes color based on availability type: up=green, down=red, orange=disabled, unknown=grey, + * empty=grey, warn=yellow. This version of the availability graph shows continuous intervals. + * + * @author Mike Thompson + */ +public class AvailabilityOverUnderGraphType { + + private static Messages MSG = CoreGUI.getMessages(); + private List<Availability> availabilityList; + private List<ResourceGroupAvailability> groupAvailabilityList; + private Integer entityId; + + /** + * General constructor for stacked bar graph when you have all the data needed to produce the graph. (This is true + * for all cases but the dashboard portlet). + */ + public AvailabilityOverUnderGraphType(Integer entityId) { + this.entityId = entityId; + } + + public void setAvailabilityList(List<Availability> availabilityList) { + this.availabilityList = availabilityList; + } + + public void setGroupAvailabilityList(List<ResourceGroupAvailability> groupAvailabilityList) { + this.groupAvailabilityList = groupAvailabilityList; + } + + public String getAvailabilityJson() { + StringBuilder sb = new StringBuilder("["); + if (null != availabilityList) { + // loop through the avail intervals + for (Availability availability : availabilityList) { + sb.append("{ "availType":"" + availability.getAvailabilityType() + "", "); + sb.append(" "availTypeMessage":"" + availability.getAvailabilityType()+ "", "); + sb.append(" "availStart":" + availability.getStartTime() + ", "); + // last record will be null + long endTime = availability.getEndTime() != null ? availability.getEndTime() : (new Date()).getTime(); + sb.append(" "availEnd":" + endTime + ", "); + + long availDuration = endTime - availability.getStartTime(); + String availDurationString = MeasurementConverterClient.format((double) availDuration, + MeasurementUnits.MILLISECONDS, true); + sb.append(" "availDuration": "" + availDurationString + "" },"); + + } + sb.setLength(sb.length() - 1); + + } else if (null != groupAvailabilityList) { + // loop through the group avail down intervals + for (ResourceGroupAvailability groupAvailability : groupAvailabilityList) { + // allows substitution for situations like WARN=MIXED for easier terminology + String availabilityTypeMessage = (groupAvailability.getGroupAvailabilityType().equals(ResourceGroupComposite.GroupAvailabilityType.WARN)) + ? MSG.chart_hover_availability_type_warn() : groupAvailability.getGroupAvailabilityType().name(); + + sb.append("{ "availType":"" + groupAvailability.getGroupAvailabilityType() + "", "); + sb.append(" "availTypeMessage":"" + availabilityTypeMessage + "", "); + sb.append(" "availStart":" + groupAvailability.getStartTime() + ", "); + // last record will be null + long endTime = groupAvailability.getEndTime() != null ? groupAvailability.getEndTime() : (new Date()) + .getTime(); + sb.append(" "availEnd":" + endTime + ", "); + + long availDuration = endTime - groupAvailability.getStartTime(); + String availDurationString = MeasurementConverterClient.format((double) availDuration, + MeasurementUnits.MILLISECONDS, true); + sb.append(" "availDuration": "" + availDurationString + "" },"); + + } + sb.setLength(sb.length() - 1); + } + + sb.append("]"); + Log.debug(sb.toString()); + return sb.toString(); + } + + /** + * The magic JSNI to draw the charts with d3. + */ + public native void drawJsniChart() /*-{ + console.log("Draw Enhanced Availability chart"); + + var global = this, + // tidy up all of our interactions with java (via JSNI) thru AvailChartContext class + // NOTE: rhq.js has the javascript object constructors in it. + availChartContext = new $wnd.AvailChartContext(global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartId()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getAvailabilityJson()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartDateLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartTimeLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverStartLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverEndLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverBarLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverAvailabilityLabel()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverTimeFormat()(), + global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType::getChartHoverDateFormat()() + ); + + + var availabilityGraph = function () { + "use strict"; + // privates + + var margin = {top: 5, right: 5, bottom: 5, left: 40}, + barOffset = 10, + width = 750 - margin.left - margin.right + barOffset, + height = 40 - margin.top - margin.bottom, + pixelsOffHeight = 0, + svg; + + + function drawBars(availChartContext) { + var xAxisMin = $wnd.d3.min(availChartContext.data, function (d) { + return +d.availStart; + }), + xAxisMax = $wnd.d3.max(availChartContext.data, function (d) { + return +d.availEnd; + }), + + timeScale = $wnd.d3.time.scale() + .range([0, width]) + .domain([xAxisMin, xAxisMax]), + + yScale = $wnd.d3.scale.linear() + .clamp(true) + .rangeRound([height, 0]) + .domain([0, 4]), + + xAxis = $wnd.d3.svg.axis() + .scale(timeScale) + .ticks(12) + .tickSize(10, 0, 0) + .orient("bottom"), + + calcBarY = function(d) { + var ABOVE = -10, + BELOW = 0, + STRADDLE = -5, + offset; + + if (d.availType === 'DOWN') { + offset = BELOW; + } + else if (d.availType === 'DISABLED') { + offset = STRADDLE; + } + else if (d.availType === 'UNKNOWN') { + offset = STRADDLE; + } + else if (d.availType === 'UP') { + offset = ABOVE; + } + else if (d.availType === 'WARN') { + offset = STRADDLE; + } + else if (d.availType === 'EMPTY') { + offset = STRADDLE; + } + return yScale(0) + offset; + + }, + + calcBarFill = function(d) { + if (d.availType === 'DOWN') { + return "#FF1919"; // red + } + else if (d.availType === 'DISABLED') { + return "#FF9933"; // orange + } + else if (d.availType === 'UNKNOWN') { + return "#CCC"; // gray + } + else if (d.availType === 'UP') { + return "#198C19"; // green + } + else if (d.availType === 'WARN') { + return "#FFA500"; // yellow + } + else if (d.availType === 'EMPTY') { + return "#CCC"; // gray + } + else { + // should not ever happen, but... + console.warn("AvailabilityType not valid."); + return "#000"; //black + } + }, + svg = $wnd.d3.select(availChartContext.chartSelection).append("g") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + + svg.selectAll("rect.availBars") + .data(availChartContext.data) + .enter().append("rect") + .attr("class", "availBars") + .attr("x", function (d) { + return timeScale(+d.availStart); + }) + .attr("y", function (d) { + return calcBarY(d); + + }) + .attr("height", function (d) { + return 10; + + }) + .attr("width", function (d) { + return timeScale(+d.availEnd) - timeScale(+d.availStart); + }) + .attr("opacity", ".9") + .attr("fill", function (d) { + return calcBarFill(d); + }); + + // create x-axis + svg.append("g") + .attr("class", "x axis") + .attr("stroke", "#50505a") + .attr("stroke-width", "0.5") + .attr("transform", "translate(0," + height + ")") + .attr("letter-spacing", "3") + .style("text-anchor", "end") + .call(xAxis); + + svg.append("text") + .attr("class", "availabilityLabel") + .attr("x", -40) + .attr("y", 10) + .style("font-size", "12px") + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-weight", "bold") + .attr("fill", "#003168") + .text("Availability"); + + svg.append("text") + .attr("class", "upLabel") + .attr("x", -5) + .attr("y", 28) + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-size", "9px") + .attr("fill", "#50505a") + .style("text-anchor", "end") + .text("UP"); + + svg.append("text") + .attr("class", "downLabel") + .attr("x", -5) + .attr("y", 39) + .style("font-family", "Arial, Verdana, sans-serif;") + .style("font-size", "9px") + .attr("fill", "#50505a") + .style("text-anchor", "end") + .text("DOWN"); + + } + + function createHovers() { + $wnd.jQuery('svg rect.availBars').tipsy({ + gravity: 's', + html: true, + trigger: 'hover', + title: function () { + var d = this.__data__; + return formatHovers(d); + }, + show: function (e, el) { + el.css({ 'z-index': '990000'}) + } + }); + } + + function formatHovers(d) { + var hoverString, + timeFormatter = $wnd.d3.time.format(availChartContext.chartHoverTimeFormat), + dateFormatter = $wnd.d3.time.format(availChartContext.chartHoverDateFormat), + availStart = new Date(+d.availStart), + availEnd = new Date(+d.availEnd); + + hoverString = + '<div class="chartHoverEnclosingDiv">' + + '<div class="chartHoverAlignLeft"><span >' + availChartContext.hoverBarAvailabilityLabel + ': </span><span style="width:50px;">' + d.availTypeMessage + '</span></div>' + + '<div class="chartHoverAlignLeft"><span>'+ dateFormatter(availStart) + ' ' + timeFormatter(availStart) + '</span></div>' + + '<div class="chartHoverAlignLeft"><span >' + availChartContext.hoverBarLabel + ': </span><span style="width:50px;">' + d.availDuration + '</span></div>' + + '</div>'; + return hoverString; + + } + + return { + // Public API + draw: function (chartContext) { + "use strict"; + console.info("AvailabilityChart"); + //console.time("availabilityChart"); + drawBars(availChartContext); + createHovers(); + //console.timeEnd("availabilityChart"); + } + }; // end public closure + + + }(); + + if (availChartContext.data !== undefined && availChartContext.data.length > 0) { + availabilityGraph.draw(availChartContext); + } + + }-*/; + + public String getChartId() { + return String.valueOf(entityId); + } + + public String getChartTimeLabel() { + return MSG.chart_time_label(); + } + + public String getChartDateLabel() { + return MSG.chart_date_label(); + } + + public String getChartHoverAvailabilityLabel() { + return MSG.chart_hover_availability_label(); + } + + public String getChartHoverStartLabel() { + return MSG.chart_hover_start_label(); + } + + public String getChartHoverEndLabel() { + return MSG.chart_hover_end_label(); + } + + public String getChartHoverBarLabel() { + return MSG.chart_hover_bar_label(); + } + + public String getChartHoverTimeFormat() { + return MSG.chart_hover_time_format(); + } + + public String getChartHoverDateFormat() { + return MSG.chart_hover_date_format(); + } +} diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java index d9a4205..15f400d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java @@ -234,8 +234,10 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { chart.append("g").append("rect") .attr("class", "rightSidePanel") .attr("x", xLabel - 10) - .attr("y", margin.top + 60) - .attr("height", 100) + .attr("y", margin.top + 70) + .attr("rx", 10) + .attr("ry", 10) + .attr("height", 80) .attr("width", 135) .attr("opacity", "0.3") .attr("fill", "#E8E8E8"); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/D3GroupGraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/D3GroupGraphListView.java index 786701b..7691c5f 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/D3GroupGraphListView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/D3GroupGraphListView.java @@ -42,6 +42,7 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.inventory.AutoRefresh; import org.rhq.enterprise.gui.coregui.client.inventory.common.AbstractD3GraphListView; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityLineGraphType; +import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphImpl; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.MetricD3GraphView; @@ -74,7 +75,7 @@ public final class D3GroupGraphListView extends AbstractD3GraphListView implemen
addMember(measurementRangeEditor); if (showAvailabilityGraph) { - availabilityGraph = new AvailabilityD3Graph(new AvailabilityLineGraphType(resourceGroup.getId())); + availabilityGraph = new AvailabilityD3Graph(new AvailabilityOverUnderGraphType(resourceGroup.getId())); // first step in 2 step to create d3 chart // create a placeholder for avail graph availabilityGraph.createGraphMarker(); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/D3GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/D3GraphListView.java index 26f3626..58d3050 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/D3GraphListView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/D3GraphListView.java @@ -47,6 +47,7 @@ import org.rhq.enterprise.gui.coregui.client.components.measurement.UserPreferen import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.inventory.common.AbstractD3GraphListView; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityLineGraphType; +import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphImpl; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.avail.AvailabilityD3Graph; @@ -130,7 +131,7 @@ public class D3GraphListView extends AbstractD3GraphListView { addMember(measurementRangeEditor);
if (showAvailabilityGraph) { - availabilityGraph = new AvailabilityD3Graph(new AvailabilityLineGraphType(resource.getId())); + availabilityGraph = new AvailabilityD3Graph(new AvailabilityOverUnderGraphType(resource.getId())); // first step in 2 step to create d3 chart // create a placeholder for avail graph availabilityGraph.createGraphMarker(); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java index d03fefe..d06bab2 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/avail/AvailabilityD3Graph.java @@ -26,6 +26,7 @@ import org.rhq.core.domain.measurement.Availability; import org.rhq.core.domain.resource.group.composite.ResourceGroupAvailability; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityGraph; import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityLineGraphType; +import org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.AvailabilityOverUnderGraphType; import org.rhq.enterprise.gui.coregui.client.util.Log; import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout;
@@ -37,12 +38,12 @@ import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout; */ public class AvailabilityD3Graph extends EnhancedVLayout implements AvailabilityGraph {
- protected AvailabilityLineGraphType availabilityGraphType; + protected AvailabilityOverUnderGraphType availabilityGraphType;
- public AvailabilityD3Graph(AvailabilityLineGraphType graphType) { + public AvailabilityD3Graph(AvailabilityOverUnderGraphType graphType) { super(); this.availabilityGraphType = graphType; - setHeight(25); + setHeight(70); setWidth100(); }
@@ -82,7 +83,7 @@ public class AvailabilityD3Graph extends EnhancedVLayout implements Availability
StringBuilder divAndSvgDefs = new StringBuilder(); divAndSvgDefs.append("<div id="availChart-" + availabilityGraphType.getChartId() - + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" style="height:20px;">"); + + "" ><svg xmlns="http://www.w3.org/2000/svg%5C" version="1.1" style="height:110px;">"); divAndSvgDefs.append("</svg></div>"); HTMLFlow graph = new HTMLFlow(divAndSvgDefs.toString()); graph.setWidth100();
commit 85215f76e7ec578a7cad3a13e983c6cbffa0650f Author: mtho11 mikecthompson@gmail.com Date: Wed Apr 24 16:16:15 2013 -0700
Trivial: add *.DS_Store files to .gitignore
diff --git a/.gitignore b/.gitignore index 92b2176..3bd9232 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ modules/enterprise/gui/coregui/build/classes/ modules/enterprise/gui/content_http-war/build/classes/ #created by rhq-enterprise-server's unit tests modules/enterprise/server/jar/transaction.log - .idea/ .metadata/ *cache.html @@ -27,6 +26,7 @@ modules/enterprise/server/jar/transaction.log .*.jsfdia .wtpmodules *~ +*.DS_Store
#these are created by the python script engine during the tests cachedir/
commit f875212be4a8cfaf0905e2fd376a579197b83148 Author: Thomas Segismont tsegismo@redhat.com Date: Tue May 7 14:25:34 2013 +0200
Bug 865629 - (PRODMGT-245) Add more metrics to AS7 plugin
Added missing metrics Added integration test
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml index cfe756d..5f538b7 100644 --- a/modules/plugins/jboss-as-7/pom.xml +++ b/modules/plugins/jboss-as-7/pom.xml @@ -615,6 +615,7 @@ <include>org/rhq/modules/plugins/jbossas7/itest/**/*Test.java</include> <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java</include>--> + <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java</include>--> 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 45f4e05..742c4d5 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 @@ -8864,6 +8864,22 @@ <metric property="responseTime" dataType="calltime" defaultOn="false" units="milliseconds" destinationType="URL" description="the minimum, maximum, and average response times for requests serviced by this webapp"/> + <metric property="active-sessions" displayName="Currently Active Sessions" + description="The number of sessions that are currently active"/> + <metric property="duplicated-session-ids" displayName="Duplicated Session Ids" + description="The number of duplicated session identifiers"/> + <metric property="expired-sessions" measurementType="trendsup" displayName="Expired Sessions" + description="The number of expired sessions"/> + <metric property="max-active-sessions" displayName="Maximum Active Sessions" + description="The maximum number of sessions that have been active"/> + <metric property="rejected-sessions" measurementType="trendsup" displayName="Rejected Sessions" + description="The number of sessions rejected"/> + <metric property="session-avg-alive-time" units="milliseconds" displayName="Average Session Alive Time" + description="The average alive time of sessions"/> + <metric property="session-max-alive-time" units="milliseconds" displayName="Max Session Alive Time" + description="The maximum alive time of sessions"/> + <metric property="sessions-created" measurementType="trendsup" displayName="Created Sessions" + description="The number of sessions created"/>
</service>
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java index 6f84e34..5b552bc 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java @@ -19,6 +19,11 @@
package org.rhq.modules.plugins.jbossas7.itest.standalone;
+import static java.util.concurrent.TimeUnit.SECONDS; +import static org.rhq.core.domain.util.ResourceTypeUtility.getMeasurementDefinitions; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -27,6 +32,8 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; import java.util.Set;
import org.mockito.Mockito; @@ -47,8 +54,18 @@ import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.content.PackageDetailsKey; import org.rhq.core.domain.content.transfer.DeployPackagesResponse; import org.rhq.core.domain.content.transfer.ResourcePackageDetails; +import org.rhq.core.domain.measurement.DataType; +import org.rhq.core.domain.measurement.MeasurementDataNumeric; +import org.rhq.core.domain.measurement.MeasurementDataTrait; +import org.rhq.core.domain.measurement.MeasurementDefinition; +import org.rhq.core.domain.measurement.MeasurementReport; +import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.domain.resource.CreateResourceStatus; import org.rhq.core.domain.resource.Resource; +import org.rhq.core.domain.util.MeasurementDefinitionFilter; +import org.rhq.core.pc.inventory.ResourceContainer; +import org.rhq.core.pc.util.FacetLockType; +import org.rhq.core.pluginapi.measurement.MeasurementFacet; import org.rhq.modules.plugins.jbossas7.StandaloneASComponent; import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest; import org.rhq.test.arquillian.DiscoveredResources; @@ -101,6 +118,9 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest { @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "Deployment") private Set<Resource> deploymentResources;
+ @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "Web Runtime") + private Set<Resource> webRuntimeResources; + private static TestDeployments DEPLOYMENT_TO_SERVE = TestDeployments.DEPLOYMENT_1;
private static long copyStreamAndReturnCount(InputStream in, OutputStream out) throws IOException { @@ -242,6 +262,60 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest { }
@Test(priority = 15) + @RunDiscovery + public void testWebRuntimeMetricsHaveNonNullValues() throws Exception { + assertTrue(webRuntimeResources != null && !webRuntimeResources.isEmpty(), + "Web Runtime resource should have been discovered"); + assertEquals(webRuntimeResources.size(), 1, "Found more than one Web Runtime resource: " + webRuntimeResources); + + Resource webRuntimeResource = webRuntimeResources.iterator().next(); + ResourceContainer webRuntimeResourceContainer = pluginContainer.getInventoryManager().getResourceContainer( + webRuntimeResource); + MeasurementFacet measurementFacet = webRuntimeResourceContainer.createResourceComponentProxy( + MeasurementFacet.class, FacetLockType.READ, SECONDS.toMillis(5), false, false); + MeasurementReport report = new MeasurementReport(); + Set<MeasurementScheduleRequest> measurementScheduleRequests = getMeasurementScheduleRequests(webRuntimeResource); + measurementFacet.getValues(report, measurementScheduleRequests); + assertEquals(report.getCallTimeData().size(), 0, "No calltime data was requested"); + assertTrue( + report.getNumericData().size() + report.getTraitData().size() == measurementScheduleRequests.size(), + "Some requested measurements are missing: " + + getMissingMeasurements(measurementScheduleRequests, report.getNumericData(), report.getTraitData())); + } + + private Set<String> getMissingMeasurements(Set<MeasurementScheduleRequest> measurementScheduleRequests, + Set<MeasurementDataNumeric> numericData, Set<MeasurementDataTrait> traitData) { + Set<String> missingMeasurements = new HashSet<String>(); + for (MeasurementScheduleRequest measurementScheduleRequest : measurementScheduleRequests) { + missingMeasurements.add(measurementScheduleRequest.getName()); + } + for (MeasurementDataNumeric measurementDataNumeric : numericData) { + missingMeasurements.remove(measurementDataNumeric.getName()); + } + for (MeasurementDataTrait measurementDataTrait : traitData) { + missingMeasurements.remove(measurementDataTrait.getName()); + } + return missingMeasurements; + } + + private Set<MeasurementScheduleRequest> getMeasurementScheduleRequests(Resource webRuntimeResource) { + Set<MeasurementDefinition> measurementDefinitions = getMeasurementDefinitions( + webRuntimeResource.getResourceType(), new MeasurementDefinitionFilter() { + private final Set<DataType> acceptableDataTypes = EnumSet.of(DataType.MEASUREMENT, DataType.TRAIT); + + public boolean accept(MeasurementDefinition measurementDefinition) { + return acceptableDataTypes.contains(measurementDefinition.getDataType()); + } + }); + Set<MeasurementScheduleRequest> measurementScheduleRequests = new HashSet<MeasurementScheduleRequest>(); + for (MeasurementDefinition measurementDefinition : measurementDefinitions) { + measurementScheduleRequests.add(new MeasurementScheduleRequest(-1, measurementDefinition.getName(), -1, + true, measurementDefinition.getDataType(), measurementDefinition.getRawNumericType())); + } + return measurementScheduleRequests; + } + + @Test(priority = 16) public void testUndeploy() throws Exception { Resource deployment = deploymentResources.iterator().next(); DeleteResourceRequest request = new DeleteResourceRequest(0, deployment.getId());
commit e589245b50710f5487ce3efcd527f73c02df8ea3 Author: John Mazzitelli mazz@redhat.com Date: Mon May 6 19:02:55 2013 -0400
BZ 817825 don't show "Loading..." for leaf nodes in resource type drop down menus this still doesn't fix the Platform plugin's platform type submenus.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java index e2650e4..90511d7 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java @@ -77,8 +77,6 @@ public class ResourceSelector extends AbstractSelector<Resource, ResourceCriteri typeSelectItem.setValueField("id"); typeSelectItem.setCanSelectParentItems(true); typeSelectItem.setLoadDataOnDemand(false); - typeSelectItem.setEmptyMenuMessage(MSG.common_msg_loading()); - typeSelectItem.setShowIcons(false);
if (this.forceResourceTypeFilter) { typeSelectItem.setDisabled(true); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/type/ResourceTypePluginTreeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/type/ResourceTypePluginTreeDataSource.java index 136db95..c1c9e66 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/type/ResourceTypePluginTreeDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/type/ResourceTypePluginTreeDataSource.java @@ -19,8 +19,6 @@ package org.rhq.enterprise.gui.coregui.client.inventory.resource.type;
import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap;
import com.google.gwt.user.client.rpc.AsyncCallback; @@ -144,12 +142,6 @@ public class ResourceTypePluginTreeDataSource extends DataSource { } }
- Collections.sort(nodes, new Comparator<TreeNode>() { - public int compare(TreeNode o1, TreeNode o2) { - return o1.getName().compareTo(o2.getName()); - } - }); - TreeNode[] treeNodes = nodes.toArray(new TreeNode[nodes.size()]); return treeNodes; } @@ -198,9 +190,8 @@ public class ResourceTypePluginTreeDataSource extends DataSource { setParentID(null);
setAttribute("name", pluginName + " " + pluginStr); - // setAttribute("plugin",pluginName); - setIcon("types/plugin_16.png"); // todo doesn't work setEnabled(true); + // setIcon(IconEnum.PLUGIN.getIcon16x16Path()); // IPickTreeItem doesn't appear to want to use this }
@Override @@ -245,10 +236,7 @@ public class ResourceTypePluginTreeDataSource extends DataSource { setAttribute("name", resourceType.getName()); setAttribute("plugin", resourceType.getPlugin()); setAttribute("category", resourceType.getCategory().getDisplayName()); - - setIcon("types/" + resourceType.getCategory().getDisplayName() + "_up_16.png"); - - setIsFolder(true); + // setIcon(ImageManager.getResourceIcon(resourceType.getCategory())); // IPickTreeItem doesn't appear to want to use this }
public ResourceType getResourceType() {
commit 82a86c90fcc05ec19b1b9b63771fe12905cb2f09 Author: John Mazzitelli mazz@redhat.com Date: Mon May 6 16:03:20 2013 -0400
BZ 960265 bring back the GWT calltime page
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java index a68170a..91db630 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java @@ -28,6 +28,7 @@ import com.smartgwt.client.widgets.Canvas;
import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.common.EntityContext; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.DataType; @@ -55,7 +56,6 @@ import org.rhq.enterprise.gui.coregui.client.drift.ResourceDriftDefinitionsView; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.inventory.InventoryView; import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.AbstractTwoLevelTabSetView; -import org.rhq.enterprise.gui.coregui.client.inventory.common.detail.monitoring.IFrameWithMeasurementRangeEditorView; import org.rhq.enterprise.gui.coregui.client.inventory.common.event.EventCompositeHistoryView; import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupListView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceCompositeSearchView; @@ -64,6 +64,7 @@ import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.configura import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.inventory.PluginConfigurationEditView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.inventory.PluginConfigurationHistoryListView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.inventory.ResourceAgentView; +import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.CalltimeView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.D3GraphListView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.avail.ResourceAvailabilityView; import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.schedules.ResourceSchedulesView; @@ -437,8 +438,7 @@ public class ResourceDetailView extends viewFactory = (!visible) ? null : new ViewFactory() { @Override public Canvas createView() { - return new IFrameWithMeasurementRangeEditorView("/rhq/resource/monitor/response-plain.xhtml?id=" - + resource.getId()); + return new CalltimeView(EntityContext.forResource(resource.getId())); } }; updateSubTab(this.monitoringTab, this.monitorCallTime, visible, true, viewFactory);
commit 98f5814fe4acb2dd5a9305170460638e3cd984e1 Author: Stefan Negrea snegrea@redhat.com Date: Mon May 6 11:05:04 2013 -0500
Update development version to 4.8.0-SNAPSHOT.
diff --git a/code-coverage/pom.xml b/code-coverage/pom.xml index f1f8cec..dbb487d 100644 --- a/code-coverage/pom.xml +++ b/code-coverage/pom.xml @@ -3,7 +3,7 @@ <parent> <artifactId>rhq-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-code-coverage</artifactId> diff --git a/modules/cli-tests/pom.xml b/modules/cli-tests/pom.xml index c4dadc9..efe6d1f 100644 --- a/modules/cli-tests/pom.xml +++ b/modules/cli-tests/pom.xml @@ -8,7 +8,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/common/ant-bundle/pom.xml b/modules/common/ant-bundle/pom.xml index 4cf6703..138e9ca 100644 --- a/modules/common/ant-bundle/pom.xml +++ b/modules/common/ant-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/common/drift/pom.xml b/modules/common/drift/pom.xml index 9d7a132..5afdead 100644 --- a/modules/common/drift/pom.xml +++ b/modules/common/drift/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-common-drift</artifactId> diff --git a/modules/common/filetemplate-bundle/pom.xml b/modules/common/filetemplate-bundle/pom.xml index 32692b5..0beb20b 100644 --- a/modules/common/filetemplate-bundle/pom.xml +++ b/modules/common/filetemplate-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-filetemplate-bundle-common</artifactId> diff --git a/modules/common/jboss-as-dmr-client/pom.xml b/modules/common/jboss-as-dmr-client/pom.xml index 4f43692..b8c1682 100644 --- a/modules/common/jboss-as-dmr-client/pom.xml +++ b/modules/common/jboss-as-dmr-client/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-jboss-as-dmr-client</artifactId> diff --git a/modules/common/jboss-as/pom.xml b/modules/common/jboss-as/pom.xml index b9ee5be..6dac77b 100644 --- a/modules/common/jboss-as/pom.xml +++ b/modules/common/jboss-as/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-common-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-jboss-as-common</artifactId> diff --git a/modules/common/pom.xml b/modules/common/pom.xml index 4ed6d92..088e268 100644 --- a/modules/common/pom.xml +++ b/modules/common/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/core/arquillian-integration/archive/pom.xml b/modules/core/arquillian-integration/archive/pom.xml index 7c7e949..fe5f377 100644 --- a/modules/core/arquillian-integration/archive/pom.xml +++ b/modules/core/arquillian-integration/archive/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-arquillian-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<!-- Model Version --> diff --git a/modules/core/arquillian-integration/container/pom.xml b/modules/core/arquillian-integration/container/pom.xml index 75a7a05..258d050 100644 --- a/modules/core/arquillian-integration/container/pom.xml +++ b/modules/core/arquillian-integration/container/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-arquillian-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<!-- Model Version --> diff --git a/modules/core/arquillian-integration/pom.xml b/modules/core/arquillian-integration/pom.xml index 9637dfc..67b02a8 100644 --- a/modules/core/arquillian-integration/pom.xml +++ b/modules/core/arquillian-integration/pom.xml @@ -9,7 +9,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/arquillian-integration/suite-extension/pom.xml b/modules/core/arquillian-integration/suite-extension/pom.xml index 5d80c3f..231ab67 100644 --- a/modules/core/arquillian-integration/suite-extension/pom.xml +++ b/modules/core/arquillian-integration/suite-extension/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-arquillian-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<!-- Model Version --> diff --git a/modules/core/arquillian-integration/test-agent-plugin/pom.xml b/modules/core/arquillian-integration/test-agent-plugin/pom.xml index f086ca3..4ed7bca 100644 --- a/modules/core/arquillian-integration/test-agent-plugin/pom.xml +++ b/modules/core/arquillian-integration/test-agent-plugin/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-arquillian-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/client-api/pom.xml b/modules/core/client-api/pom.xml index acd19c9..7adcd3b 100644 --- a/modules/core/client-api/pom.xml +++ b/modules/core/client-api/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/comm-api/pom.xml b/modules/core/comm-api/pom.xml index 9fd9f98..1fb2161 100644 --- a/modules/core/comm-api/pom.xml +++ b/modules/core/comm-api/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index d77ee51..cc040f8 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/domain/pom.xml b/modules/core/domain/pom.xml index d572d9d..776459d 100644 --- a/modules/core/domain/pom.xml +++ b/modules/core/domain/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-core-domain</artifactId> diff --git a/modules/core/gui/pom.xml b/modules/core/gui/pom.xml index b3b7706..dc21aad 100644 --- a/modules/core/gui/pom.xml +++ b/modules/core/gui/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/native-system/pom.xml b/modules/core/native-system/pom.xml index 04be12b..46fe305 100644 --- a/modules/core/native-system/pom.xml +++ b/modules/core/native-system/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/core/plugin-api/pom.xml b/modules/core/plugin-api/pom.xml index a24c330..8060a89 100644 --- a/modules/core/plugin-api/pom.xml +++ b/modules/core/plugin-api/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/plugin-container-itest/pom.xml b/modules/core/plugin-container-itest/pom.xml index 900eb72..9c801de 100644 --- a/modules/core/plugin-container-itest/pom.xml +++ b/modules/core/plugin-container-itest/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-core-plugin-container-itest</artifactId> diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml index 06395a2..3c070a9 100644 --- a/modules/core/plugin-container/pom.xml +++ b/modules/core/plugin-container/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-core-plugin-container</artifactId> diff --git a/modules/core/plugin-test-api/pom.xml b/modules/core/plugin-test-api/pom.xml index fc49cf3..18fa318 100644 --- a/modules/core/plugin-test-api/pom.xml +++ b/modules/core/plugin-test-api/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-core-plugin-test-api</artifactId> diff --git a/modules/core/plugin-test-util/pom.xml b/modules/core/plugin-test-util/pom.xml index c75dcbc..0374729 100644 --- a/modules/core/plugin-test-util/pom.xml +++ b/modules/core/plugin-test-util/pom.xml @@ -9,7 +9,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/plugin-validator/pom.xml b/modules/core/plugin-validator/pom.xml index d05b721..99c875d 100644 --- a/modules/core/plugin-validator/pom.xml +++ b/modules/core/plugin-validator/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/plugindoc/pom.xml b/modules/core/plugindoc/pom.xml index c3c7175..426d298 100644 --- a/modules/core/plugindoc/pom.xml +++ b/modules/core/plugindoc/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/core/pom.xml b/modules/core/pom.xml index c4992af..c41a8f4 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/core/util/pom.xml b/modules/core/util/pom.xml index b799891..cdc3b9b 100644 --- a/modules/core/util/pom.xml +++ b/modules/core/util/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-core-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>rhq-core-util</artifactId> diff --git a/modules/enterprise/agent/pom.xml b/modules/enterprise/agent/pom.xml index cb1fad0..2d7093d 100644 --- a/modules/enterprise/agent/pom.xml +++ b/modules/enterprise/agent/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/agentupdate/pom.xml b/modules/enterprise/agentupdate/pom.xml index 3b66b92..67ed9a8 100644 --- a/modules/enterprise/agentupdate/pom.xml +++ b/modules/enterprise/agentupdate/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml index a41fb6c..d5b7643 100644 --- a/modules/enterprise/binding/pom.xml +++ b/modules/enterprise/binding/pom.xml @@ -3,10 +3,10 @@ <parent> <artifactId>rhq-enterprise-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <artifactId>rhq-script-bindings</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Script Bindings</name> <description>Abstraction of different facilities and default configurations for script bindings</description>
diff --git a/modules/enterprise/comm/pom.xml b/modules/enterprise/comm/pom.xml index c312dc1..8148262 100644 --- a/modules/enterprise/comm/pom.xml +++ b/modules/enterprise/comm/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/content_http-war/pom.xml b/modules/enterprise/gui/content_http-war/pom.xml index 333aa5d..a140a9c 100644 --- a/modules/enterprise/gui/content_http-war/pom.xml +++ b/modules/enterprise/gui/content_http-war/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-gui-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml index 035ade8..cb7dd3a 100644 --- a/modules/enterprise/gui/coregui/pom.xml +++ b/modules/enterprise/gui/coregui/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml index 1fa9ec1..018a802 100644 --- a/modules/enterprise/gui/pom.xml +++ b/modules/enterprise/gui/pom.xml @@ -8,7 +8,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/portal-war/pom.xml b/modules/enterprise/gui/portal-war/pom.xml index a827c3c..d2998cc 100644 --- a/modules/enterprise/gui/portal-war/pom.xml +++ b/modules/enterprise/gui/portal-war/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/remoting-war/pom.xml b/modules/enterprise/gui/remoting-war/pom.xml index 70ece03..638bccd 100644 --- a/modules/enterprise/gui/remoting-war/pom.xml +++ b/modules/enterprise/gui/remoting-war/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/rest-examples-war/pom.xml b/modules/enterprise/gui/rest-examples-war/pom.xml index 2a5091c..c9aa075 100644 --- a/modules/enterprise/gui/rest-examples-war/pom.xml +++ b/modules/enterprise/gui/rest-examples-war/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/gui/rest-war/pom.xml b/modules/enterprise/gui/rest-war/pom.xml index 5d3dbfc..33e330e 100644 --- a/modules/enterprise/gui/rest-war/pom.xml +++ b/modules/enterprise/gui/rest-war/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml index 489d603..3fad441 100644 --- a/modules/enterprise/pom.xml +++ b/modules/enterprise/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/remoting/cli/pom.xml b/modules/enterprise/remoting/cli/pom.xml index e371826..dec19d0 100644 --- a/modules/enterprise/remoting/cli/pom.xml +++ b/modules/enterprise/remoting/cli/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/remoting/client-api/pom.xml b/modules/enterprise/remoting/client-api/pom.xml index 2c7b6f9..cba50db 100644 --- a/modules/enterprise/remoting/client-api/pom.xml +++ b/modules/enterprise/remoting/client-api/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/remoting/client-deps/pom.xml b/modules/enterprise/remoting/client-deps/pom.xml index b411a87..6db40f2 100644 --- a/modules/enterprise/remoting/client-deps/pom.xml +++ b/modules/enterprise/remoting/client-deps/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/remoting/pom.xml b/modules/enterprise/remoting/pom.xml index 3ab9e66..7bf574e 100644 --- a/modules/enterprise/remoting/pom.xml +++ b/modules/enterprise/remoting/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/scripting/api/pom.xml b/modules/enterprise/scripting/api/pom.xml index 07768cd..268af3a 100644 --- a/modules/enterprise/scripting/api/pom.xml +++ b/modules/enterprise/scripting/api/pom.xml @@ -3,10 +3,10 @@ <parent> <artifactId>rhq-scripting-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <artifactId>rhq-scripting-api</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Scripting API</name> <description>Provides API for adding scripting support to RHQ using different javax.scripting - based interpreters</description>
diff --git a/modules/enterprise/scripting/javascript/pom.xml b/modules/enterprise/scripting/javascript/pom.xml index 32eb12d..acc09aa 100644 --- a/modules/enterprise/scripting/javascript/pom.xml +++ b/modules/enterprise/scripting/javascript/pom.xml @@ -4,10 +4,10 @@ <parent> <artifactId>rhq-scripting-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <artifactId>rhq-scripting-javascript</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Javascript support</name> <description>Provides RHQ scripting in Javascript using Rhino</description>
diff --git a/modules/enterprise/scripting/pom.xml b/modules/enterprise/scripting/pom.xml index 5c82958..a58f1ca 100644 --- a/modules/enterprise/scripting/pom.xml +++ b/modules/enterprise/scripting/pom.xml @@ -3,12 +3,12 @@ <parent> <artifactId>rhq-enterprise-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <artifactId>rhq-scripting-parent</artifactId> <packaging>pom</packaging>
- <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Scripting Parent Module</name>
<modules> diff --git a/modules/enterprise/scripting/python/pom.xml b/modules/enterprise/scripting/python/pom.xml index f6a1149c..dc69d9e 100644 --- a/modules/enterprise/scripting/python/pom.xml +++ b/modules/enterprise/scripting/python/pom.xml @@ -3,10 +3,10 @@ <parent> <artifactId>rhq-scripting-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <artifactId>rhq-scripting-python</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Python support</name> <description>Provides RHQ scripting in Python using Jython</description>
diff --git a/modules/enterprise/server/appserver/pom.xml b/modules/enterprise/server/appserver/pom.xml index 0e46986..f186d70 100644 --- a/modules/enterprise/server/appserver/pom.xml +++ b/modules/enterprise/server/appserver/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/client-api/pom.xml b/modules/enterprise/server/client-api/pom.xml index 6bb6ea2..3e69ded 100644 --- a/modules/enterprise/server/client-api/pom.xml +++ b/modules/enterprise/server/client-api/pom.xml @@ -5,13 +5,13 @@ <parent> <artifactId>rhq-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
<groupId>org.rhq</groupId> <artifactId>rhq-server-client-api</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Enterprise Server Client API</name> <description>The implementation of the client API when accessing the server locally</description>
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index 939f107..867ebe1 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/installer/pom.xml b/modules/enterprise/server/installer/pom.xml index 150daf2..23d8e94 100644 --- a/modules/enterprise/server/installer/pom.xml +++ b/modules/enterprise/server/installer/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/itests-2/pom.xml b/modules/enterprise/server/itests-2/pom.xml index 9f9ba81..5e4e076 100644 --- a/modules/enterprise/server/itests-2/pom.xml +++ b/modules/enterprise/server/itests-2/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml index acb8931..84e34c4 100644 --- a/modules/enterprise/server/jar/pom.xml +++ b/modules/enterprise/server/jar/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/plugins/alert-cli/pom.xml b/modules/enterprise/server/plugins/alert-cli/pom.xml index 68ea87a..ea9bd42 100644 --- a/modules/enterprise/server/plugins/alert-cli/pom.xml +++ b/modules/enterprise/server/plugins/alert-cli/pom.xml @@ -3,11 +3,11 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <groupId>org.rhq</groupId> <artifactId>alert-cli</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>RHQ Enterprise Server CLI Script Alert Plugin</name> <description>An alert sender able to execute an arbitrary CLI script as a response to an alert</description>
diff --git a/modules/enterprise/server/plugins/alert-email/pom.xml b/modules/enterprise/server/plugins/alert-email/pom.xml index ec91baf..a2102a3 100644 --- a/modules/enterprise/server/plugins/alert-email/pom.xml +++ b/modules/enterprise/server/plugins/alert-email/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq.server</groupId> <artifactId>alert-email</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Email Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-irc/pom.xml b/modules/enterprise/server/plugins/alert-irc/pom.xml index ea7bd90..bd5f656 100644 --- a/modules/enterprise/server/plugins/alert-irc/pom.xml +++ b/modules/enterprise/server/plugins/alert-irc/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-irc</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server IRC Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-log4j/pom.xml b/modules/enterprise/server/plugins/alert-log4j/pom.xml index c50b5cb..934cb7e 100644 --- a/modules/enterprise/server/plugins/alert-log4j/pom.xml +++ b/modules/enterprise/server/plugins/alert-log4j/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-log4j</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Log4J Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-microblog/pom.xml b/modules/enterprise/server/plugins/alert-microblog/pom.xml index c576b41..28d1d56 100644 --- a/modules/enterprise/server/plugins/alert-microblog/pom.xml +++ b/modules/enterprise/server/plugins/alert-microblog/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-microblog</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Microblog Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-mobicents/pom.xml b/modules/enterprise/server/plugins/alert-mobicents/pom.xml index 5d9fb43..4338526 100644 --- a/modules/enterprise/server/plugins/alert-mobicents/pom.xml +++ b/modules/enterprise/server/plugins/alert-mobicents/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-mobicents</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Mobicents Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-operations/pom.xml b/modules/enterprise/server/plugins/alert-operations/pom.xml index 24813ad..21ec5f7 100644 --- a/modules/enterprise/server/plugins/alert-operations/pom.xml +++ b/modules/enterprise/server/plugins/alert-operations/pom.xml @@ -2,14 +2,14 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-operations</artifactId> <packaging>jar</packaging> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Opertions Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-roles/pom.xml b/modules/enterprise/server/plugins/alert-roles/pom.xml index 31acb49..a6c054a 100644 --- a/modules/enterprise/server/plugins/alert-roles/pom.xml +++ b/modules/enterprise/server/plugins/alert-roles/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-roles</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Roles Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-snmp/pom.xml b/modules/enterprise/server/plugins/alert-snmp/pom.xml index b09ed2a..f84398b 100644 --- a/modules/enterprise/server/plugins/alert-snmp/pom.xml +++ b/modules/enterprise/server/plugins/alert-snmp/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-snmp</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server SNMP Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/alert-subject/pom.xml b/modules/enterprise/server/plugins/alert-subject/pom.xml index cd0263b..d4d2564 100644 --- a/modules/enterprise/server/plugins/alert-subject/pom.xml +++ b/modules/enterprise/server/plugins/alert-subject/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>alert-subject</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Subject Alert Plugin</name>
diff --git a/modules/enterprise/server/plugins/ant-bundle/pom.xml b/modules/enterprise/server/plugins/ant-bundle/pom.xml index 489b37b..648b451 100644 --- a/modules/enterprise/server/plugins/ant-bundle/pom.xml +++ b/modules/enterprise/server/plugins/ant-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/cobbler/pom.xml b/modules/enterprise/server/plugins/cobbler/pom.xml index 94cbe7d..6f56e82 100644 --- a/modules/enterprise/server/plugins/cobbler/pom.xml +++ b/modules/enterprise/server/plugins/cobbler/pom.xml @@ -4,14 +4,14 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>rhq-serverplugin-cobbler</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server Cobbler Plugin</name>
diff --git a/modules/enterprise/server/plugins/disk/pom.xml b/modules/enterprise/server/plugins/disk/pom.xml index c111bcc..21bb689 100644 --- a/modules/enterprise/server/plugins/disk/pom.xml +++ b/modules/enterprise/server/plugins/disk/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/drift-rhq/pom.xml b/modules/enterprise/server/plugins/drift-rhq/pom.xml index 52b3a7c..7111543 100644 --- a/modules/enterprise/server/plugins/drift-rhq/pom.xml +++ b/modules/enterprise/server/plugins/drift-rhq/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml index b43da47..6ab0964 100644 --- a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml +++ b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/jboss-software/pom.xml b/modules/enterprise/server/plugins/jboss-software/pom.xml index 33a11a1..32ffc76 100644 --- a/modules/enterprise/server/plugins/jboss-software/pom.xml +++ b/modules/enterprise/server/plugins/jboss-software/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/packagetype-cli/pom.xml b/modules/enterprise/server/plugins/packagetype-cli/pom.xml index 80799ab..2a75e07 100644 --- a/modules/enterprise/server/plugins/packagetype-cli/pom.xml +++ b/modules/enterprise/server/plugins/packagetype-cli/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq</groupId> <artifactId>packagetype-cli</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<name>RHQ Enterprise Server CLI Package Type Plugin</name>
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 827bc41..dc862db 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/plugins/url/pom.xml b/modules/enterprise/server/plugins/url/pom.xml index 5660473..bb1740d 100644 --- a/modules/enterprise/server/plugins/url/pom.xml +++ b/modules/enterprise/server/plugins/url/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml index 0d80df3..06da613 100644 --- a/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml +++ b/modules/enterprise/server/plugins/validate-all-serverplugins/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/plugins/yum/pom.xml b/modules/enterprise/server/plugins/yum/pom.xml index 75b3cdc..6f8ac10 100644 --- a/modules/enterprise/server/plugins/yum/pom.xml +++ b/modules/enterprise/server/plugins/yum/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/pom.xml b/modules/enterprise/server/pom.xml index 494e98e..9c60e30 100644 --- a/modules/enterprise/server/pom.xml +++ b/modules/enterprise/server/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/safe-invoker/pom.xml b/modules/enterprise/server/safe-invoker/pom.xml index 8c509f4..b2b741e 100644 --- a/modules/enterprise/server/safe-invoker/pom.xml +++ b/modules/enterprise/server/safe-invoker/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/sars/pom.xml b/modules/enterprise/server/sars/pom.xml index 2b00e67..d4f7715 100644 --- a/modules/enterprise/server/sars/pom.xml +++ b/modules/enterprise/server/sars/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/sars/services-sar/pom.xml b/modules/enterprise/server/sars/services-sar/pom.xml index 4586a8b..014420b 100644 --- a/modules/enterprise/server/sars/services-sar/pom.xml +++ b/modules/enterprise/server/sars/services-sar/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-sars-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/enterprise/server/startup-subsystem/pom.xml b/modules/enterprise/server/startup-subsystem/pom.xml index 3359f33..7152fc3 100644 --- a/modules/enterprise/server/startup-subsystem/pom.xml +++ b/modules/enterprise/server/startup-subsystem/pom.xml @@ -9,7 +9,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/enterprise/server/xml-schemas/pom.xml b/modules/enterprise/server/xml-schemas/pom.xml index 98783f1..00e558b 100644 --- a/modules/enterprise/server/xml-schemas/pom.xml +++ b/modules/enterprise/server/xml-schemas/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../../../pom.xml</relativePath> </parent>
diff --git a/modules/helpers/bundleGen/pom.xml b/modules/helpers/bundleGen/pom.xml index 82fabfc..f2f2455 100644 --- a/modules/helpers/bundleGen/pom.xml +++ b/modules/helpers/bundleGen/pom.xml @@ -3,13 +3,13 @@ <parent> <artifactId>rhq-helpers</artifactId> <groupId>org.rhq.helpers</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>org.rhq.helpers</groupId> <artifactId>bundleGen</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version>
<build> <plugins> diff --git a/modules/helpers/jeeGen/pom.xml b/modules/helpers/jeeGen/pom.xml index 348b780..6f36514 100644 --- a/modules/helpers/jeeGen/pom.xml +++ b/modules/helpers/jeeGen/pom.xml @@ -9,7 +9,7 @@ <parent> <artifactId>rhq-helpers</artifactId> <groupId>org.rhq.helpers</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq.helpers</groupId> diff --git a/modules/helpers/perftest-support/pom.xml b/modules/helpers/perftest-support/pom.xml index ed71426..8772058 100644 --- a/modules/helpers/perftest-support/pom.xml +++ b/modules/helpers/perftest-support/pom.xml @@ -3,11 +3,11 @@ <parent> <artifactId>rhq-helpers</artifactId> <groupId>org.rhq.helpers</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <groupId>org.rhq.helpers</groupId> <artifactId>perftest-support</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <name>Performance Testing Support</name> <description>To support performance testing, this is a basic tool to support extracting and later reimporting of data from/to a database. diff --git a/modules/helpers/pom.xml b/modules/helpers/pom.xml index bd47d23..ecebf6c 100644 --- a/modules/helpers/pom.xml +++ b/modules/helpers/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/helpers/rest-docs-generator/pom.xml b/modules/helpers/rest-docs-generator/pom.xml index e72aab4..c5a4a41 100644 --- a/modules/helpers/rest-docs-generator/pom.xml +++ b/modules/helpers/rest-docs-generator/pom.xml @@ -24,7 +24,7 @@ <parent> <artifactId>rhq-helpers</artifactId> <groupId>org.rhq.helpers</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
diff --git a/modules/helpers/rtfilter-subsystem/pom.xml b/modules/helpers/rtfilter-subsystem/pom.xml index f3cbb2e..baf0801 100644 --- a/modules/helpers/rtfilter-subsystem/pom.xml +++ b/modules/helpers/rtfilter-subsystem/pom.xml @@ -9,7 +9,7 @@ <parent> <groupId>org.rhq.helpers</groupId> <artifactId>rhq-helpers</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq.helpers</groupId> diff --git a/modules/helpers/rtfilter/pom.xml b/modules/helpers/rtfilter/pom.xml index da9cf66..bf4ca3d 100644 --- a/modules/helpers/rtfilter/pom.xml +++ b/modules/helpers/rtfilter/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq.helpers</groupId> <artifactId>rhq-helpers</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq.helpers</groupId> diff --git a/modules/integration-tests/apache-plugin-test/pom.xml b/modules/integration-tests/apache-plugin-test/pom.xml index ce66fd5..a9d7296 100644 --- a/modules/integration-tests/apache-plugin-test/pom.xml +++ b/modules/integration-tests/apache-plugin-test/pom.xml @@ -4,7 +4,7 @@ <parent> <artifactId>rhq-integration-tests</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/integration-tests/jndi-access/jndi-access-test/pom.xml b/modules/integration-tests/jndi-access/jndi-access-test/pom.xml index f83573d..48808ac 100644 --- a/modules/integration-tests/jndi-access/jndi-access-test/pom.xml +++ b/modules/integration-tests/jndi-access/jndi-access-test/pom.xml @@ -4,7 +4,7 @@ <parent> <artifactId>jndi-access-test-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>jndi-access-test</artifactId> diff --git a/modules/integration-tests/jndi-access/pom.xml b/modules/integration-tests/jndi-access/pom.xml index caef075..6ded494 100644 --- a/modules/integration-tests/jndi-access/pom.xml +++ b/modules/integration-tests/jndi-access/pom.xml @@ -4,7 +4,7 @@ <parent> <artifactId>rhq-integration-tests</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/integration-tests/jndi-access/remote-server/pom.xml b/modules/integration-tests/jndi-access/remote-server/pom.xml index b28b9bf..d11992a 100644 --- a/modules/integration-tests/jndi-access/remote-server/pom.xml +++ b/modules/integration-tests/jndi-access/remote-server/pom.xml @@ -4,7 +4,7 @@ <parent> <artifactId>jndi-access-test-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>jndi-access-remote-server</artifactId> diff --git a/modules/integration-tests/pom.xml b/modules/integration-tests/pom.xml index f110387..7e5f521 100644 --- a/modules/integration-tests/pom.xml +++ b/modules/integration-tests/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/modules/integration-tests/rest-api/pom.xml b/modules/integration-tests/rest-api/pom.xml index 6061752..bca2fe4 100644 --- a/modules/integration-tests/rest-api/pom.xml +++ b/modules/integration-tests/rest-api/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-integration-tests</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>
diff --git a/modules/plugins/aliases/pom.xml b/modules/plugins/aliases/pom.xml index 14874eb..2809e95 100644 --- a/modules/plugins/aliases/pom.xml +++ b/modules/plugins/aliases/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/ant-bundle/pom.xml b/modules/plugins/ant-bundle/pom.xml index 9c3e48d..75a98a4 100644 --- a/modules/plugins/ant-bundle/pom.xml +++ b/modules/plugins/ant-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/apache/pom.xml b/modules/plugins/apache/pom.xml index 3f6bca5..380f6e6 100644 --- a/modules/plugins/apache/pom.xml +++ b/modules/plugins/apache/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/augeas/pom.xml b/modules/plugins/augeas/pom.xml index 4e663e6..ada89b3 100644 --- a/modules/plugins/augeas/pom.xml +++ b/modules/plugins/augeas/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/byteman/pom.xml b/modules/plugins/byteman/pom.xml index 6a85842..37ffe0e 100644 --- a/modules/plugins/byteman/pom.xml +++ b/modules/plugins/byteman/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/cassandra/pom.xml b/modules/plugins/cassandra/pom.xml index d576083..a17a3d8 100644 --- a/modules/plugins/cassandra/pom.xml +++ b/modules/plugins/cassandra/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/cobbler/pom.xml b/modules/plugins/cobbler/pom.xml index c01634b..9424397 100644 --- a/modules/plugins/cobbler/pom.xml +++ b/modules/plugins/cobbler/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/cron/pom.xml b/modules/plugins/cron/pom.xml index 27f290b..3aa5463 100644 --- a/modules/plugins/cron/pom.xml +++ b/modules/plugins/cron/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/database/pom.xml b/modules/plugins/database/pom.xml index 7959a32..03349f8 100644 --- a/modules/plugins/database/pom.xml +++ b/modules/plugins/database/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/filetemplate-bundle/pom.xml b/modules/plugins/filetemplate-bundle/pom.xml index c67fc10..8a5f0e6 100644 --- a/modules/plugins/filetemplate-bundle/pom.xml +++ b/modules/plugins/filetemplate-bundle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/grub/pom.xml b/modules/plugins/grub/pom.xml index 4a3ad1d..a1c3353 100644 --- a/modules/plugins/grub/pom.xml +++ b/modules/plugins/grub/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/hadoop/pom.xml b/modules/plugins/hadoop/pom.xml index dd99a37..d8325e4 100644 --- a/modules/plugins/hadoop/pom.xml +++ b/modules/plugins/hadoop/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/hibernate/pom.xml b/modules/plugins/hibernate/pom.xml index 0303046..adee980 100644 --- a/modules/plugins/hibernate/pom.xml +++ b/modules/plugins/hibernate/pom.xml @@ -6,7 +6,7 @@ <groupId>org.rhq</groupId> <!-- Bypass the jopr-plugins-parent which can not have children. It must build after the plugins in order to execute integration tests on them. --> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/hosts/pom.xml b/modules/plugins/hosts/pom.xml index 9ca39d3..f587112 100644 --- a/modules/plugins/hosts/pom.xml +++ b/modules/plugins/hosts/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/hudson/pom.xml b/modules/plugins/hudson/pom.xml index 1a8d193..d1f3e43 100644 --- a/modules/plugins/hudson/pom.xml +++ b/modules/plugins/hudson/pom.xml @@ -6,12 +6,12 @@ <parent> <artifactId>rhq-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> <artifactId>rhq-hudson-plugin</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <packaging>jar</packaging>
<name>RHQ Hudson Plugin</name> diff --git a/modules/plugins/iis/pom.xml b/modules/plugins/iis/pom.xml index 69f1dbb..93a915f 100644 --- a/modules/plugins/iis/pom.xml +++ b/modules/plugins/iis/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/irc/pom.xml b/modules/plugins/irc/pom.xml index 875e82f..b043e7b 100644 --- a/modules/plugins/irc/pom.xml +++ b/modules/plugins/irc/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>rhq-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/jboss-as-5/pom.xml b/modules/plugins/jboss-as-5/pom.xml index 221d4cc..f2e6f8a 100644 --- a/modules/plugins/jboss-as-5/pom.xml +++ b/modules/plugins/jboss-as-5/pom.xml @@ -9,7 +9,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml index 81b2322..cfe756d 100644 --- a/modules/plugins/jboss-as-7/pom.xml +++ b/modules/plugins/jboss-as-7/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/jboss-as/pom.xml b/modules/plugins/jboss-as/pom.xml index bd58a06..b792d26 100644 --- a/modules/plugins/jboss-as/pom.xml +++ b/modules/plugins/jboss-as/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/jboss-cache-v3/pom.xml b/modules/plugins/jboss-cache-v3/pom.xml index c83611c..837852d 100644 --- a/modules/plugins/jboss-cache-v3/pom.xml +++ b/modules/plugins/jboss-cache-v3/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/jboss-cache/pom.xml b/modules/plugins/jboss-cache/pom.xml index 421f24d..3828a6a 100644 --- a/modules/plugins/jboss-cache/pom.xml +++ b/modules/plugins/jboss-cache/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/jmx/pom.xml b/modules/plugins/jmx/pom.xml index 48e3f93..864f675 100644 --- a/modules/plugins/jmx/pom.xml +++ b/modules/plugins/jmx/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/kickstart/pom.xml b/modules/plugins/kickstart/pom.xml index 9255d09..094f451 100644 --- a/modules/plugins/kickstart/pom.xml +++ b/modules/plugins/kickstart/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/mod-cluster/pom.xml b/modules/plugins/mod-cluster/pom.xml index 62ffc81..54b9f53 100644 --- a/modules/plugins/mod-cluster/pom.xml +++ b/modules/plugins/mod-cluster/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/mysql/pom.xml b/modules/plugins/mysql/pom.xml index 14e39a3..572851e 100644 --- a/modules/plugins/mysql/pom.xml +++ b/modules/plugins/mysql/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/netservices/pom.xml b/modules/plugins/netservices/pom.xml index 22db736..6b663ff 100644 --- a/modules/plugins/netservices/pom.xml +++ b/modules/plugins/netservices/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/noop/pom.xml b/modules/plugins/noop/pom.xml index 1f43ea4..68af26a 100644 --- a/modules/plugins/noop/pom.xml +++ b/modules/plugins/noop/pom.xml @@ -26,7 +26,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/oracle/pom.xml b/modules/plugins/oracle/pom.xml index dc4f4aa..ed93d10 100644 --- a/modules/plugins/oracle/pom.xml +++ b/modules/plugins/oracle/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/pattern-generator/pom.xml b/modules/plugins/pattern-generator/pom.xml index 1d40834..5653d69 100644 --- a/modules/plugins/pattern-generator/pom.xml +++ b/modules/plugins/pattern-generator/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/perftest/pom.xml b/modules/plugins/perftest/pom.xml index 593a70b..f852e8a 100644 --- a/modules/plugins/perftest/pom.xml +++ b/modules/plugins/perftest/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/platform/pom.xml b/modules/plugins/platform/pom.xml index ef210b6..e28148c 100644 --- a/modules/plugins/platform/pom.xml +++ b/modules/plugins/platform/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml index 9d6a147..0e27179 100644 --- a/modules/plugins/pom.xml +++ b/modules/plugins/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent>
diff --git a/modules/plugins/postfix/pom.xml b/modules/plugins/postfix/pom.xml index 6ee7474..12ae83c 100644 --- a/modules/plugins/postfix/pom.xml +++ b/modules/plugins/postfix/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/postgres/pom.xml b/modules/plugins/postgres/pom.xml index 1e323fb..26d37b3 100644 --- a/modules/plugins/postgres/pom.xml +++ b/modules/plugins/postgres/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/rhq-agent/pom.xml b/modules/plugins/rhq-agent/pom.xml index e187c17..6bf549f 100644 --- a/modules/plugins/rhq-agent/pom.xml +++ b/modules/plugins/rhq-agent/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/rhq-server/pom.xml b/modules/plugins/rhq-server/pom.xml index 5327977..968a154 100644 --- a/modules/plugins/rhq-server/pom.xml +++ b/modules/plugins/rhq-server/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/samba/pom.xml b/modules/plugins/samba/pom.xml index 23dadb6..20e41c4 100644 --- a/modules/plugins/samba/pom.xml +++ b/modules/plugins/samba/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/script/pom.xml b/modules/plugins/script/pom.xml index 3772829..d31500b 100644 --- a/modules/plugins/script/pom.xml +++ b/modules/plugins/script/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/script2/pom.xml b/modules/plugins/script2/pom.xml index 3bec031..36ab8be 100644 --- a/modules/plugins/script2/pom.xml +++ b/modules/plugins/script2/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/snmptrapd/pom.xml b/modules/plugins/snmptrapd/pom.xml index ae92638..74d740b 100644 --- a/modules/plugins/snmptrapd/pom.xml +++ b/modules/plugins/snmptrapd/pom.xml @@ -2,7 +2,7 @@ <parent> <artifactId>rhq-plugins-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<modelVersion>4.0.0</modelVersion> diff --git a/modules/plugins/sshd/pom.xml b/modules/plugins/sshd/pom.xml index 93856c9..e0a216e 100644 --- a/modules/plugins/sshd/pom.xml +++ b/modules/plugins/sshd/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/sudoers/pom.xml b/modules/plugins/sudoers/pom.xml index d10ef73..3891b84 100644 --- a/modules/plugins/sudoers/pom.xml +++ b/modules/plugins/sudoers/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/tomcat/pom.xml b/modules/plugins/tomcat/pom.xml index 8cdd836..eb97008 100644 --- a/modules/plugins/tomcat/pom.xml +++ b/modules/plugins/tomcat/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.jboss.on</groupId> diff --git a/modules/plugins/twitter/pom.xml b/modules/plugins/twitter/pom.xml index 52e155c..45c2544 100644 --- a/modules/plugins/twitter/pom.xml +++ b/modules/plugins/twitter/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/validate-all-plugins/pom.xml b/modules/plugins/validate-all-plugins/pom.xml index 1e8c6fc..63eb6ae 100644 --- a/modules/plugins/validate-all-plugins/pom.xml +++ b/modules/plugins/validate-all-plugins/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/plugins/virt/pom.xml b/modules/plugins/virt/pom.xml index 1c2bbca..de510c5 100644 --- a/modules/plugins/virt/pom.xml +++ b/modules/plugins/virt/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/pom.xml b/modules/pom.xml index 82d911d..8f4cf31 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<groupId>org.rhq</groupId> diff --git a/modules/test-utils/pom.xml b/modules/test-utils/pom.xml index f536119..c343deb 100644 --- a/modules/test-utils/pom.xml +++ b/modules/test-utils/pom.xml @@ -7,7 +7,7 @@ <parent> <artifactId>rhq-modules-parent</artifactId> <groupId>org.rhq</groupId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> </parent>
<artifactId>test-utils</artifactId> diff --git a/pom.xml b/pom.xml index da1506f..b46ee9e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@
<groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>4.7.0-SNAPSHOT</version> + <version>4.8.0-SNAPSHOT</version> <packaging>pom</packaging>
<name>RHQ</name>
commit 0989c0c6cad40b787e4148d40b95418d1dd7a4cf Author: Stefan Negrea snegrea@redhat.com Date: Mon May 6 11:02:05 2013 -0500
Disable all the arquillian-integration submodules from building when maven.test.skip is true. Also, fix modules that depended on these modules to include them only if they are built. (cherry picked from commit 7e9678418a8ee2683aafb395c1cc25415ab375e3)
diff --git a/modules/core/arquillian-integration/pom.xml b/modules/core/arquillian-integration/pom.xml index 7e215a3..9637dfc 100644 --- a/modules/core/arquillian-integration/pom.xml +++ b/modules/core/arquillian-integration/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
<modelVersion>4.0.0</modelVersion> @@ -19,11 +19,30 @@ <name>RHQ Arquillian Integration Modules</name> <description>parent POM for integration modules with Arquillian</description>
- <modules> - <module>test-agent-plugin</module> - <module>container</module> - <module>archive</module> - <module>suite-extension</module> - </modules> + + <profiles> + <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <modules> + <module>test-agent-plugin</module> + <module>container</module> + <module>archive</module> + <module>suite-extension</module> + </modules> + </profile> + </profiles>
</project> diff --git a/modules/core/plugin-test-api/pom.xml b/modules/core/plugin-test-api/pom.xml index 9c91bc0..fc49cf3 100644 --- a/modules/core/plugin-test-api/pom.xml +++ b/modules/core/plugin-test-api/pom.xml @@ -1,5 +1,5 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
<modelVersion>4.0.0</modelVersion> @@ -24,59 +24,80 @@ <version>${project.version}</version> </dependency>
- <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>test-utils</artifactId> - <version>${project.version}</version> - </dependency> + </dependencies>
- <dependency> - <groupId>org.rhq</groupId> - <artifactId>rhq-arquillian-agent-plugin-container-embedded</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.powermock</groupId> - <artifactId>powermock-module-testng</artifactId> - </dependency> - - <dependency> - <groupId>org.powermock</groupId> - <artifactId>powermock-api-mockito</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.arquillian.container</groupId> - <artifactId>arquillian-container-spi</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.arquillian.core</groupId> - <artifactId>arquillian-core-spi</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.arquillian.container</groupId> - <artifactId>arquillian-container-test-api</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.arquillian.test</groupId> - <artifactId>arquillian-test-spi</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.arquillian.testng</groupId> - <artifactId>arquillian-testng-container</artifactId> - </dependency> - - <dependency> - <groupId>org.jboss.shrinkwrap.resolver</groupId> - <artifactId>shrinkwrap-resolver-depchain</artifactId> - <type>pom</type> - </dependency>
- </dependencies> + <profiles> + <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>test-utils</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-arquillian-agent-plugin-container-embedded</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-testng</artifactId> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.container</groupId> + <artifactId>arquillian-container-spi</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.core</groupId> + <artifactId>arquillian-core-spi</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.container</groupId> + <artifactId>arquillian-container-test-api</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.test</groupId> + <artifactId>arquillian-test-spi</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.arquillian.testng</groupId> + <artifactId>arquillian-testng-container</artifactId> + </dependency> + + <dependency> + <groupId>org.jboss.shrinkwrap.resolver</groupId> + <artifactId>shrinkwrap-resolver-depchain</artifactId> + <type>pom</type> + </dependency> + </dependencies> + </profile> + </profiles>
</project> diff --git a/modules/core/pom.xml b/modules/core/pom.xml index c51fb51..c4992af 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -1,5 +1,5 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
<modelVersion>4.0.0</modelVersion> @@ -23,9 +23,7 @@ <profile> <id>default</id> <activation> - <property> - <name>java.home</name> - </property> + <activeByDefault>true</activeByDefault> </activation> <modules> <module>util</module> @@ -47,6 +45,38 @@ </modules> </profile>
+ <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>avoid.test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>true</value> + </property> + </activation> + <modules> + <module>util</module> + <module>native-system</module> + <module>comm-api</module> + <module>dbutils</module> + <module>domain</module> + <module>plugin-api</module> + <module>client-api</module> + <module>plugin-container</module> + <module>gui</module> + <module>plugin-validator</module> + <module>arquillian-integration</module> + <module>plugin-test-api</module> + <module>plugin-container-itest</module> + </modules> + </profile> + + <profile> <id>plugindoc</id> <modules> diff --git a/modules/plugins/cassandra/pom.xml b/modules/plugins/cassandra/pom.xml index 9888aa0..d576083 100644 --- a/modules/plugins/cassandra/pom.xml +++ b/modules/plugins/cassandra/pom.xml @@ -63,20 +63,6 @@ <artifactId>snakeyaml</artifactId> <version>1.10</version> </dependency> - <dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-api</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-util</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> </dependencies>
<build> @@ -231,6 +217,39 @@ </build>
<profiles> + <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-api</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-util</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + </profile> + <profile> <id>dev</id>
diff --git a/modules/plugins/jboss-as-5/pom.xml b/modules/plugins/jboss-as-5/pom.xml index d9838cf..221d4cc 100644 --- a/modules/plugins/jboss-as-5/pom.xml +++ b/modules/plugins/jboss-as-5/pom.xml @@ -119,21 +119,6 @@ <!-- Test Deps -->
<dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-api</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-util</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - - <dependency> <groupId>org.jboss.spec.javax.jms</groupId> <artifactId>jboss-jms-api_1.1_spec</artifactId> <version>1.0.0.Final</version> @@ -218,6 +203,39 @@
<profiles>
+ <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-api</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-util</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + </profile> + <profile> <id>integration-tests</id> <!-- diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml index 33b2bd7..81b2322 100644 --- a/modules/plugins/jboss-as-7/pom.xml +++ b/modules/plugins/jboss-as-7/pom.xml @@ -99,21 +99,6 @@ <!-- === Test Deps === -->
<dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-api</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>${rhq.groupId}</groupId> - <artifactId>rhq-core-plugin-test-util</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - - <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <scope>test</scope> @@ -250,6 +235,39 @@
<profiles>
+ <profile> + <!-- + This profile has been created to avoid unnecessary resolution of test dependencies during a build that + does not run, compile or need tests. + More test dependencies are to be moved here if the set of sub-dependencies is complex, references project + test jars, or conflicts with changing the container version. + --> + <id>test.dependencies</id> + <activation> + <property> + <name>maven.test.skip</name> + <value>!true</value> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-api</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>${rhq.groupId}</groupId> + <artifactId>rhq-core-plugin-test-util</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + </profile> + <profile> <id>java7</id> <activation>
commit cad0a43803d781bf2ba28eab71b80f822bf2d07d Author: Stefan Negrea snegrea@redhat.com Date: Mon May 6 11:01:37 2013 -0500
Update test to avoid disabled managers. This is especially important for the TagManager that can be disabled via build properties. (cherry picked from commit c9ccdbf61842dd115ce0d3067752e85dbb1db730)
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/client/security/test/ScriptingAPIServerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/client/security/test/ScriptingAPIServerTest.java index aa0ebd4..024e4f6 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/client/security/test/ScriptingAPIServerTest.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/client/security/test/ScriptingAPIServerTest.java @@ -87,6 +87,10 @@ public class ScriptingAPIServerTest extends ScriptableAbstractEJB3Test { //Simplification itself is unit tested separately.
for (RhqManager m : RhqManager.values()) { + if (!m.enabled()) { + continue; + } + String name = m.name(); // Only check for the TagManager if it is enabled at all if (name.contains("TagManager") && !RhqManager.TagManager.enabled()) {
commit 5fecc675d08aa9220a163f0e35530dc6c07447b6 Author: Thomas Segismont tsegismo@redhat.com Date: Mon May 6 16:20:24 2013 +0200
Add test case for Bug 911321 - [EAP 6.1] Reload operation fails in standalone mode
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml index 23a02c4..33b2bd7 100644 --- a/modules/plugins/jboss-as-7/pom.xml +++ b/modules/plugins/jboss-as-7/pom.xml @@ -30,6 +30,7 @@ <java.tieredCompilation>-Dxxx</java.tieredCompilation> <java.useCompressedOOPS>-Dxxx</java.useCompressedOOPS> <rhq.internal>false</rhq.internal> + <as7.itest.mock.http.management.server.port>32259</as7.itest.mock.http.management.server.port> </properties>
@@ -118,6 +119,13 @@ <scope>test</scope> </dependency>
+ <dependency> + <groupId>org.eclipse.jetty.aggregate</groupId> + <artifactId>jetty-all</artifactId> + <version>8.1.8.v20121106</version> + <scope>test</scope> + </dependency> + <!-- For native subsystem --> <dependency> <groupId>org.hyperic</groupId> @@ -588,6 +596,7 @@ <!-- only include integration tests; normal unit tests are handled above by surefire plugin --> <include>org/rhq/modules/plugins/jbossas7/itest/**/*Test.java</include> <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java</include>--> + <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java</include>--> <!--<include>org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java</include>--> @@ -609,6 +618,7 @@ <jboss.domain.portOffset>${jboss.domain.portOffset}</jboss.domain.portOffset> <jboss.domain.httpManagementPort>${jboss.domain.httpManagementPort}</jboss.domain.httpManagementPort> <settings.localRepository>${settings.localRepository}</settings.localRepository> + <as7.itest.mock.http.management.server.port>${as7.itest.mock.http.management.server.port}</as7.itest.mock.http.management.server.port> </systemPropertyVariables> </configuration> <executions> diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java new file mode 100644 index 0000000..9597d47 --- /dev/null +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java @@ -0,0 +1,239 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2013 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +package org.rhq.modules.plugins.jbossas7.itest.standalone; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.mockito.Mockito.when; +import static org.rhq.core.pluginapi.event.log.LogFileEventResourceComponentHelper.LOG_EVENT_SOURCES_CONFIG_PROP; +import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.HOSTNAME; +import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.MANAGEMENT_CONNECTION_TIMEOUT; +import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.PASSWORD; +import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.PORT; +import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.USER; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codehaus.jackson.map.ObjectMapper; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.PropertyList; +import org.rhq.core.domain.measurement.AvailabilityType; +import org.rhq.core.pluginapi.availability.AvailabilityContext; +import org.rhq.core.pluginapi.inventory.ResourceContext; +import org.rhq.core.pluginapi.operation.OperationResult; +import org.rhq.core.system.SystemInfoFactory; +import org.rhq.core.util.StringUtil; +import org.rhq.modules.plugins.jbossas7.StandaloneASComponent; +import org.rhq.modules.plugins.jbossas7.json.Operation; +import org.rhq.modules.plugins.jbossas7.json.Result; + +/** + * Check that management operations that might be interrupted by AS server (connection closed before the http response + * is sent) don't make RHQ operations fail. + * + * See https://bugzilla.redhat.com/show_bug.cgi?id=911321 + * + * @author Thomas Segismont + */ +public class InterruptibleOperationsTest { + + private static final Log LOG = LogFactory.getLog(InterruptibleOperationsTest.class); + + private static final String HTTP_HOST = "localhost"; + + private static final int HTTP_PORT = 31159; + + private static final String HTTP_PORT_VARIABLE = "as7.itest.mock.http.management.server.port"; + + @Mock + private ResourceContext resourceContext; + + private StandaloneASComponent serverComponent; + + private Server jettyServer; + + private ExecutorService executorService; + + @BeforeMethod + private void setup() throws Exception { + MockitoAnnotations.initMocks(this); + serverComponent = new TestStandaloneASComponent(); + int httpPort = getJettyPort(); + setupResourceContext(httpPort); + setupJettyServer(httpPort); + jettyServer.start(); + executorService = Executors.newSingleThreadExecutor(); + serverComponent.start(resourceContext); + } + + private void setupJettyServer(int httpPort) { + jettyServer = new Server(new InetSocketAddress(HTTP_HOST, httpPort)); + ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + jettyServer.setHandler(context); + HttpServlet testServlet = new TestServlet(); + context.addServlet(new ServletHolder(testServlet), "/*"); + } + + private static int getJettyPort() { + String httpPortVariable = System.getProperty(HTTP_PORT_VARIABLE); + if (StringUtil.isNotBlank(httpPortVariable)) { + try { + int port = Integer.parseInt(httpPortVariable); + LOG.info("Using port " + httpPortVariable + " for http server"); + return port; + } catch (NumberFormatException e) { + LOG.warn("Invalid port variable: " + httpPortVariable); + } + } + LOG.info("Using default port " + String.valueOf(HTTP_PORT) + " for http server"); + return HTTP_PORT; + } + + private void setupResourceContext(int httpPort) { + when(resourceContext.getPluginConfiguration()).thenReturn(pluginConfig(httpPort)); + when(resourceContext.getResourceKey()).thenReturn("/TestServer"); + when(resourceContext.getSystemInformation()).thenReturn(SystemInfoFactory.createJavaSystemInfo()); + when(resourceContext.getAvailabilityContext()).thenReturn(Mockito.mock(AvailabilityContext.class)); + } + + private Configuration pluginConfig(int httpPort) { + Configuration pluginConfig = new Configuration(); + pluginConfig.setSimpleValue(HOSTNAME, "localhost"); + pluginConfig.setSimpleValue(PORT, String.valueOf(httpPort)); + pluginConfig.setSimpleValue(USER, "pipo"); + pluginConfig.setSimpleValue(PASSWORD, "molo"); + pluginConfig.setSimpleValue(MANAGEMENT_CONNECTION_TIMEOUT, "-1"); + pluginConfig.getMap().put(LOG_EVENT_SOURCES_CONFIG_PROP, new PropertyList()); + return pluginConfig; + } + + @AfterMethod + private void tearDown() throws Exception { + LOG.info("Shutting down Jetty test server"); + try { + if (jettyServer != null) { + jettyServer.stop(); + } + } catch (Exception ignore) { + } + if (executorService != null) { + executorService.shutdownNow(); + } + } + + @Test(timeOut = 60 * 1000) + public void testReloadOperation() throws Exception { + OperationResult operationResult = serverComponent.invokeOperation("reload", new Configuration()); + assertEquals(operationResult.getSimpleResult(), "Success"); + } + + @Test(timeOut = 60 * 1000) + public void testShutdown() throws Exception { + OperationResult operationResult = serverComponent.invokeOperation("shutdown", new Configuration()); + assertEquals(operationResult.getSimpleResult(), "Success"); + } + + private class RestartJetty implements Runnable { + @Override + public void run() { + try { + jettyServer.stop(); + } catch (Exception ignore) { + } + try { + Thread.sleep(SECONDS.toMillis(2)); + } catch (Exception ignore) { + } + try { + jettyServer.start(); + } catch (Exception ignore) { + } + } + } + + private class TestServlet extends HttpServlet { + + private ObjectMapper objectMapper = new ObjectMapper(); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + Operation operation = objectMapper.readValue(req.getInputStream(), Operation.class); + // Check if we recevied an operation which a real http management interface might interrupt + if (operation.getOperation().equals("reload") || operation.getOperation().equals("shutdown")) { + // Schedule a Jetty restart + executorService.submit(new RestartJetty()); + // Then wait until Jetty is shutdown + try { + Thread.sleep(Long.MAX_VALUE); + } catch (InterruptedException ignore) { + } + return; + } + // Standard operation. Return simple success + Result result = new Result(); + result.setOutcome("success"); + objectMapper.writeValue(resp.getOutputStream(), result); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req, resp); + } + + } + + // Tweak StandaloneASComponent implementation for this test case + private class TestStandaloneASComponent extends StandaloneASComponent { + + @Override + public AvailabilityType getAvailability() { + // Avoid various management requests when component is started + return AvailabilityType.DOWN; + } + + @Override + protected boolean waitUntilDown() throws InterruptedException { + // Standard implementation relies on discovery of some resource properties + return true; + } + } + +}
commit 1dba477c3fc0034a5a21960db8447fa9b43f5a56 Author: Stefan Negrea snegrea@redhat.com Date: Fri May 3 17:10:53 2013 -0500
[BZ 959591] Add back specific ant version based on local pom variables to force the download of the dependency even if not directly used in the pom. Without this, the pom would assume that the version referred here is the version from parent poms. This can cause the submodule artifact to miss ant binaries if not already in the local maven repository. (cherry picked from commit 2bb45d3c4c9d5edc71acf4380ce7a10a93937aae)
diff --git a/modules/enterprise/agentupdate/pom.xml b/modules/enterprise/agentupdate/pom.xml index ddec938..3b66b92 100644 --- a/modules/enterprise/agentupdate/pom.xml +++ b/modules/enterprise/agentupdate/pom.xml @@ -37,12 +37,14 @@ <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> + <version>${ant.version}</version> <scope>provided</scope> </dependency>
<dependency> <groupId>org.apache.ant</groupId> <artifactId>ant-launcher</artifactId> + <version>${ant.version}</version> <scope>provided</scope> </dependency>
commit 17865107e38aa503c35f5a608cc1972c09bf5a73 Author: Mike Thompson mithomps@redhat.com Date: Fri May 3 15:01:26 2013 -0700
[BZ 958754] - d3 multi-line chart: time units should have minutes when appropriate. Added the appropriate d3 time format string and updated the nvd3 chart library neither of which fixed the issue. It appears to be an error in nvd3 chart library.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/MetricNvd3BarChartGraph.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/MetricNvd3BarChartGraph.java index 1fec750..a2de9c6 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/MetricNvd3BarChartGraph.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/MetricNvd3BarChartGraph.java @@ -19,7 +19,7 @@ package org.rhq.enterprise.gui.coregui.client.inventory.common.charttype;
/** - * Contains the chart definition for a Bar Chart Graph. + * Contains the chart definition for a MultiLine Graph. * * @author Mike Thompson */ @@ -39,7 +39,7 @@ public final class MetricNvd3BarChartGraph extends AbstractGraph */ public native void drawJsniChart() /*-{ console.log("Draw NVD3 Bar jsni chart"); - console.time("multiChart") + console.time("multiChart"); var global = this, chartId = global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData::getChartId()(), chartHandle = "#rChart-"+chartId, @@ -49,7 +49,7 @@ public final class MetricNvd3BarChartGraph extends AbstractGraph yAxisUnits = global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData::getYAxisUnits()(), xAxisLabel = global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData::getXAxisTitle()(), displayDayOfWeek = global.@org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.MetricGraphData::shouldDisplayDayOfWeekInXAxisLabel()(), - xAxisTimeFormat = (displayDayOfWeek) ? "%a %I %p" : "%I %p", + xAxisTimeFormat = (displayDayOfWeek) ? "%a %I %p" : "%I : %M %p",
// nvd3 defines their json models a standard way (same model for other graphs) data = function() { @@ -63,7 +63,7 @@ public final class MetricNvd3BarChartGraph extends AbstractGraph }; $wnd.nv.addGraph(function() { var chart = $wnd.nv.models.multiBarChart() - .showControls(false) + .showControls(true) .tooltips(true);
chart.xAxis.axisLabel(xAxisLabel) diff --git a/modules/enterprise/gui/coregui/src/main/webapp/css/nv.d3.css b/modules/enterprise/gui/coregui/src/main/webapp/css/nv.d3.css index cc40dfb..163b9a8 100755 --- a/modules/enterprise/gui/coregui/src/main/webapp/css/nv.d3.css +++ b/modules/enterprise/gui/coregui/src/main/webapp/css/nv.d3.css @@ -18,8 +18,8 @@ .nvtooltip { position: absolute; background-color: rgba(255,255,255,1); - padding: 10px; - border: 1px solid #ddd; + padding: 1px; + border: 1px solid rgba(0,0,0,.2); z-index: 10000;
font-family: Arial; @@ -33,12 +33,13 @@ -moz-transition-delay: 500ms; -webkit-transition-delay: 500ms;
- -moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5); - -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5); - box-shadow: 4px 4px 8px rgba(0,0,0,.5); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); + box-shadow: 0 5px 10px rgba(0,0,0,.2);
- -moz-border-radius: 10px; - border-radius: 10px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px;
pointer-events: none;
@@ -50,15 +51,29 @@ user-select: none; }
+.nvtooltip.x-nvtooltip, +.nvtooltip.y-nvtooltip { + padding: 8px; +} + .nvtooltip h3 { margin: 0; - padding: 0; + padding: 4px 14px; + line-height: 18px; + font-weight: normal; + background-color: #f7f7f7; text-align: center; + + border-bottom: 1px solid #ebebeb; + + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; }
.nvtooltip p { margin: 0; - padding: 0; + padding: 5px 14px; text-align: center; }
@@ -93,7 +108,7 @@ svg {
svg text { - font: normal 12px sans-serif; + font: normal 12px Arial; }
svg .title { @@ -101,7 +116,8 @@ svg .title { }
.nvd3 .nv-background { - fill: none; + fill: white; + fill-opacity: 0; /* pointer-events: none; */ @@ -109,7 +125,7 @@ svg .title {
.nvd3.nv-noData { font-size: 18px; - font-weight: bolf; + font-weight: bold; }
@@ -197,12 +213,10 @@ svg .title {
.nvd3 .nv-bars .negative rect { zfill: brown; - cursor: pointer; }
.nvd3 .nv-bars rect { zfill: steelblue; - cursor: pointer; fill-opacity: .75;
transition: fill-opacity 250ms linear; @@ -226,10 +240,6 @@ svg .title { fill: rgba(0,0,0,1); }
-.nvd3 .nv-x.nv-axis text { - transform: rotate(90); -} -
/********** * Bars @@ -302,10 +312,10 @@ svg .title { .nvd3 .nv-groups path.nv-line { fill: none; stroke-width: 2.5px; + /* stroke-linecap: round; shape-rendering: geometricPrecision;
- /* transition: stroke-width 250ms linear; -moz-transition: stroke-width 250ms linear; -webkit-transition: stroke-width 250ms linear; @@ -318,10 +328,10 @@ svg .title {
.nvd3 .nv-groups path.nv-area { stroke: none; + /* stroke-linecap: round; shape-rendering: geometricPrecision;
- /* stroke-width: 2.5px; transition: stroke-width 250ms linear; -moz-transition: stroke-width 250ms linear; @@ -350,8 +360,8 @@ svg .title { }
.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point { - fill-opacity: .5; - stroke-opacity: .5; + fill-opacity: .5 !important; + stroke-opacity: .5 !important; }
@@ -397,9 +407,11 @@ svg .title { * Scatter */
+/* **Attempting to remove this for useVoronoi(false), need to see if it's required anywhere .nvd3 .nv-groups .nv-point { pointer-events: none; } +*/
.nvd3 .nv-groups .nv-point.hover { stroke-width: 20px; @@ -485,21 +497,27 @@ svg .title { * Bullet */
-.nvd3.nv-bullet { font: 10px sans-serif; cursor: pointer; } -.nvd3.nv-bullet rect { fill-opacity: .6; } -.nvd3.nv-bullet rect:hover { fill-opacity: 1; } +.nvd3.nv-bullet { font: 10px sans-serif; } +.nvd3.nv-bullet .nv-measure { fill-opacity: .8; } +.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; } .nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; } .nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; } .nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; } .nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; } .nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; } .nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; } -.nvd3.nv-bullet .nv-measure.nv-s0 { fill: steelblue; } -.nvd3.nv-bullet .nv-measure.nv-s1 { fill: darkblue; } .nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; } .nvd3.nv-bullet .nv-subtitle { fill: #999; }
+.nvd3.nv-bullet .nv-range { + fill: #999; + fill-opacity: .4; +} +.nvd3.nv-bullet .nv-range:hover { + fill-opacity: .7; +} +
/********** @@ -515,7 +533,7 @@ svg .title { }
.nvd3.nv-sparklineplus .nv-hoverValue line { - stroke: #f44; + stroke: #333; stroke-width: 1.5px; }
@@ -531,8 +549,11 @@ svg .title {
.nvd3.nv-sparklineplus .nv-xValue, .nvd3.nv-sparklineplus .nv-yValue { + /* stroke: #666; - font-size: .5em; + */ + stroke-width: 0; + font-size: .9em; font-weight: normal; }
@@ -540,6 +561,24 @@ svg .title { stroke: #f66; }
+.nvd3.nv-sparklineplus .nv-maxValue { + stroke: #2ca02c; + fill: #2ca02c; +} + +.nvd3.nv-sparklineplus .nv-minValue { + stroke: #d62728; + fill: #d62728; +} + +.nvd3.nv-sparklineplus .nv-currentValue { + /* + stroke: #444; + fill: #000; + */ + font-weight: bold; + font-size: 1.1em; +}
/********** * historical stock @@ -629,4 +668,35 @@ svg .title { */ }
+/********** +* Parallel Coordinates +*/ + +.nvd3 .background path { + fill: none; + stroke: #ccc; + stroke-opacity: .4; + shape-rendering: crispEdges; +} + +.nvd3 .foreground path { + fill: none; + stroke: steelblue; + stroke-opacity: .7; +} + +.nvd3 .brush .extent { + fill-opacity: .3; + stroke: #fff; + shape-rendering: crispEdges; +} + +.nvd3 .axis line, .axis path { + fill: none; + stroke: #000; + shape-rendering: crispEdges; +}
+.nvd3 .axis text { + text-shadow: 0 1px 0 #fff; +} \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js b/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js index 2fe2c64..e405d2e 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js +++ b/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js @@ -36,29 +36,34 @@ if (nv.dev) {
// Logs all arguments, and returns the last so you can test things in place nv.log = function() { - if (nv.dev && console.log && console.log.apply) console.log.apply(console, arguments); + if (nv.dev && console.log && console.log.apply) + console.log.apply(console, arguments) + else if (nv.dev && console.log && Function.prototype.bind) { + var log = Function.prototype.bind.call(console.log, console); + log.apply(console, arguments); + } return arguments[arguments.length - 1]; };
nv.render = function render(step) { - step = step || 1; // number of graphs to generate in each timout loop + step = step || 1; // number of graphs to generate in each timeout loop
- render.active = true; + nv.render.active = true; nv.dispatch.render_start();
setTimeout(function() { - var chart; + var chart, graph;
- for (var i = 0; i < step && (graph = render.queue[i]); i++) { + for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) { chart = graph.generate(); if (typeof graph.callback == typeof(Function)) graph.callback(chart); nv.graphs.push(chart); }
- render.queue.splice(0, i); + nv.render.queue.splice(0, i);
- if (render.queue.length) setTimeout(arguments.callee, 0); + if (nv.render.queue.length) setTimeout(arguments.callee, 0); else { nv.render.active = false; nv.dispatch.render_end(); } }, 0); }; @@ -114,7 +119,7 @@ d3.time.monthEnds = d3_time_range(d3.time.monthEnd, function(date) {
/***** - * A no frills tooltip implementation. + * A no-frills tooltip implementation. *****/
@@ -143,39 +148,67 @@ d3.time.monthEnds = d3_time_range(d3.time.monthEnd, function(date) { width = parseInt(container.offsetWidth), windowWidth = nv.utils.windowSize().width, windowHeight = nv.utils.windowSize().height, - scrollTop = body.scrollTop, - scrollLeft = body.scrollLeft, + scrollTop = window.scrollY, + scrollLeft = window.scrollX, left, top;
+ windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16; + windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16; + + var tooltipTop = function ( Elem ) { + var offsetTop = top; + do { + if( !isNaN( Elem.offsetTop ) ) { + offsetTop += (Elem.offsetTop); + } + } while( Elem = Elem.offsetParent ); + return offsetTop; + } + + var tooltipLeft = function ( Elem ) { + var offsetLeft = left; + do { + if( !isNaN( Elem.offsetLeft ) ) { + offsetLeft += (Elem.offsetLeft); + } + } while( Elem = Elem.offsetParent ); + return offsetLeft; + }
switch (gravity) { case 'e': left = pos[0] - width - dist; top = pos[1] - (height / 2); - if (left < scrollLeft) left = pos[0] + dist; - if (top < scrollTop) top = scrollTop + 5; - if (top + height > scrollTop + windowHeight) top = scrollTop - height - 5; + var tLeft = tooltipLeft(container); + var tTop = tooltipTop(container); + if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left; + if (tTop < scrollTop) top = scrollTop - tTop + top; + if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; break; case 'w': left = pos[0] + dist; top = pos[1] - (height / 2); - if (left + width > windowWidth) left = pos[0] - width - dist; - if (top < scrollTop) top = scrollTop + 5; - if (top + height > scrollTop + windowHeight) top = scrollTop - height - 5; + if (tLeft + width > windowWidth) left = pos[0] - width - dist; + if (tTop < scrollTop) top = scrollTop + 5; + if (tTop + height > scrollTop + windowHeight) top = scrollTop - height - 5; break; case 'n': - left = pos[0] - (width / 2); + left = pos[0] - (width / 2) - 5; top = pos[1] + dist; - if (left < scrollLeft) left = scrollLeft + 5; - if (left + width > windowWidth) left = windowWidth - width - 5; - if (top + height > scrollTop + windowHeight) top = pos[1] - height - dist; + var tLeft = tooltipLeft(container); + var tTop = tooltipTop(container); + if (tLeft < scrollLeft) left = scrollLeft + 5; + if (tLeft + width > windowWidth) left = left - width/2 + 5; + if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; break; case 's': left = pos[0] - (width / 2); top = pos[1] - height - dist; - if (left < scrollLeft) left = scrollLeft + 5; - if (left + width > windowWidth) left = windowWidth - width - 5; - if (scrollTop > top) top = pos[1] + 20; + var tLeft = tooltipLeft(container); + var tTop = tooltipTop(container); + if (tLeft < scrollLeft) left = scrollLeft + 5; + if (tLeft + width > windowWidth) left = left - width/2 + 5; + if (scrollTop > tTop) top = scrollTop; break; }
@@ -243,7 +276,7 @@ nv.utils.windowSize = function() {
// Easy way to bind multiple functions to window.onresize -// TODO: give a way to remove a function after its bound, other than removing alkl of them +// TODO: give a way to remove a function after its bound, other than removing all of them nv.utils.windowResize = function(fun){ var oldresize = window.onresize;
@@ -255,7 +288,7 @@ nv.utils.windowResize = function(fun){
// Backwards compatible way to implement more d3-like coloring of graphs. // If passed an array, wrap it in a function which implements the old default -// behaviour +// behavior nv.utils.getColor = function(color) { if (!arguments.length) return nv.utils.defaultColor(); //if you pass in nothing, get default colors back
@@ -263,7 +296,7 @@ nv.utils.getColor = function(color) { return function(d, i) { return d.color || color[i % color.length]; }; else return color; - //can't really help it if someone passes rubish as color + //can't really help it if someone passes rubbish as color }
// Default color chooser uses the index of an object as before. @@ -328,7 +361,7 @@ nv.models.axis = function() { ;
var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 60 //only used for tickLabel currently + , width = 75 //only used for tickLabel currently , height = 60 //only used for tickLabel currently , scale = d3.scale.linear() , axisLabelText = null @@ -337,6 +370,7 @@ nv.models.axis = function() { , rotateLabels = 0 , rotateYLabel = true , staggerLabels = false + , isOrdinal = false , ticks = null ;
@@ -398,11 +432,11 @@ nv.models.axis = function() { axisLabel.exit().remove(); switch (axis.orient()) { case 'top': - axisLabel.enter().append('text').attr('class', 'nv-axislabel') - .attr('text-anchor', 'middle') - .attr('y', 0); + axisLabel.enter().append('text').attr('class', 'nv-axislabel'); var w = (scale.range().length==2) ? scale.range()[1] : (scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])); axisLabel + .attr('text-anchor', 'middle') + .attr('y', 0) .attr('x', w/2); if (showMaxMin) { var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') @@ -428,7 +462,7 @@ nv.models.axis = function() { } break; case 'bottom': - var xLabelMargin = 30; + var xLabelMargin = 36; var maxTextWidth = 30; var xTicks = g.selectAll('g').select("text"); if (rotateLabels%360) { @@ -445,20 +479,22 @@ nv.models.axis = function() { .attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' }) .attr('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end'); } - axisLabel.enter().append('text').attr('class', 'nv-axislabel') - .attr('text-anchor', 'middle') - .attr('y', xLabelMargin); + axisLabel.enter().append('text').attr('class', 'nv-axislabel'); var w = (scale.range().length==2) ? scale.range()[1] : (scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])); axisLabel + .attr('text-anchor', 'middle') + .attr('y', xLabelMargin) .attr('x', w/2); if (showMaxMin) { + //if (showMaxMin && !isOrdinal) { var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') - .data(scale.domain()); + //.data(scale.domain()) + .data([scale.domain()[0], scale.domain()[scale.domain().length - 1]]); axisMaxMin.enter().append('g').attr('class', 'nv-axisMaxMin').append('text'); axisMaxMin.exit().remove(); axisMaxMin .attr('transform', function(d,i) { - return 'translate(' + scale(d) + ',0)' + return 'translate(' + (scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0)) + ',0)' }) .select('text') .attr('dy', '.71em') @@ -471,7 +507,9 @@ nv.models.axis = function() { }); d3.transition(axisMaxMin) .attr('transform', function(d,i) { - return 'translate(' + scale.range()[i] + ',0)' + //return 'translate(' + scale.range()[i] + ',0)' + //return 'translate(' + scale(d) + ',0)' + return 'translate(' + (scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0)) + ',0)' }); } if (staggerLabels) @@ -480,11 +518,11 @@ nv.models.axis = function() {
break; case 'right': - axisLabel.enter().append('text').attr('class', 'nv-axislabel') + axisLabel.enter().append('text').attr('class', 'nv-axislabel'); + axisLabel .attr('text-anchor', rotateYLabel ? 'middle' : 'begin') .attr('transform', rotateYLabel ? 'rotate(90)' : '') - .attr('y', rotateYLabel ? (-Math.max(margin.right,width) - 12) : -10); //TODO: consider calculating this based on largest tick width... OR at least expose this on chart - axisLabel + .attr('y', rotateYLabel ? (-Math.max(margin.right,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart .attr('x', rotateYLabel ? (scale.range()[0] / 2) : axis.tickPadding()); if (showMaxMin) { var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') @@ -514,11 +552,19 @@ nv.models.axis = function() { } break; case 'left': - axisLabel.enter().append('text').attr('class', 'nv-axislabel') + /* + //For dynamically placing the label. Can be used with dynamically-sized chart axis margins + var yTicks = g.selectAll('g').select("text"); + yTicks.each(function(d,i){ + var labelPadding = this.getBBox().width + axis.tickPadding() + 16; + if(labelPadding > width) width = labelPadding; + }); + */ + axisLabel.enter().append('text').attr('class', 'nv-axislabel'); + axisLabel .attr('text-anchor', rotateYLabel ? 'middle' : 'end') .attr('transform', rotateYLabel ? 'rotate(-90)' : '') - .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 12) : -10); //TODO: consider calculating this based on largest tick width... OR at least expose this on chart - axisLabel + .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart .attr('x', rotateYLabel ? (-scale.range()[0] / 2) : -axis.tickPadding()); if (showMaxMin) { var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin') @@ -552,27 +598,41 @@ nv.models.axis = function() { .text(function(d) { return d });
- //check if max and min overlap other values, if so, hide the values that overlap if (showMaxMin && (axis.orient() === 'left' || axis.orient() === 'right')) { + //check if max and min overlap other values, if so, hide the values that overlap g.selectAll('g') // the g's wrapping each tick .each(function(d,i) { + d3.select(this).select('text').attr('opacity', 1); if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it! if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL - d3.select(this).remove(); - else - d3.select(this).select('text').remove(); // Don't remove the ZERO line!! + d3.select(this).attr('opacity', 0); + + d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!! } }); + + //if Max and Min = 0 only show min, Issue #281 + if (scale.domain()[0] == scale.domain()[1] && scale.domain()[0] == 0) + wrap.selectAll('g.nv-axisMaxMin') + .style('opacity', function(d,i) { return !i ? 1 : 0 }); + }
if (showMaxMin && (axis.orient() === 'top' || axis.orient() === 'bottom')) { var maxMinRange = []; wrap.selectAll('g.nv-axisMaxMin') .each(function(d,i) { - if (i) // i== 1, max position - maxMinRange.push(scale(d) - this.getBBox().width - 4) //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case) - else // i==0, min position - maxMinRange.push(scale(d) + this.getBBox().width + 4) + try { + if (i) // i== 1, max position + maxMinRange.push(scale(d) - this.getBBox().width - 4) //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case) + else // i==0, min position + maxMinRange.push(scale(d) + this.getBBox().width + 4) + }catch (err) { + if (i) // i== 1, max position + maxMinRange.push(scale(d) - 4) //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case) + else // i==0, min position + maxMinRange.push(scale(d) + 4) + } }); g.selectAll('g') // the g's wrapping each tick .each(function(d,i) { @@ -660,6 +720,7 @@ nv.models.axis = function() { if (!arguments.length) return scale; scale = _; axis.scale(scale); + isOrdinal = typeof scale.rangeBands === 'function'; d3.rebind(chart, scale, 'domain', 'range', 'rangeBand', 'rangeBands'); return chart; } @@ -705,6 +766,7 @@ nv.models.historicalBar = function() { , getY = function(d) { return d.y } , forceX = [] , forceY = [0] + , padData = false , clipEdge = true , color = nv.utils.defaultColor() , xDomain @@ -726,9 +788,13 @@ nv.models.historicalBar = function() { // Setup Scales
x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )) - .range([0, availableWidth]);
- y .domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) )) + if (padData) + x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); + else + x.range([0, availableWidth]); + + y .domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) )) .range([availableHeight, 0]);
// If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point @@ -846,13 +912,20 @@ nv.models.historicalBar = function() { bars .attr('fill', function(d,i) { return color(d, i); }) .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i }) - .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - ((availableWidth / data[0].values.length) * .5)) + ',0)'; }) //TODO: better width calculations that don't assume always uniform data spacing;w + .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; }) //TODO: better width calculations that don't assume always uniform data spacing;w .attr('width', (availableWidth / data[0].values.length) * .9 )
d3.transition(bars) - .attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) }) - .attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) }); + //.attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) }) + .attr('y', function(d,i) { + return getY(d,i) < 0 ? + y(0) : + y(0) - y(getY(d,i)) < 1 ? + y(0) - 1 : + y(getY(d,i)) + }) + .attr('height', function(d,i) { return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) }); //.order(); // not sure if this makes any sense for this model
}); @@ -936,6 +1009,12 @@ nv.models.historicalBar = function() { return chart; };
+ chart.padData = function(_) { + if (!arguments.length) return padData; + padData = _; + return chart; + }; + chart.clipEdge = function(_) { if (!arguments.length) return clipEdge; clipEdge = _; @@ -980,6 +1059,7 @@ nv.models.bullet = function() { , width = 380 , height = 30 , tickFormat = null + , color = nv.utils.getColor(['#1f77b4']) , dispatch = d3.dispatch('elementMouseover', 'elementMouseout') ;
@@ -1002,7 +1082,7 @@ nv.models.bullet = function() {
// Compute the new x-scale. var x1 = d3.scale.linear() - .domain([0, Math.max(rangez[0], markerz[0], measurez[0])]) // TODO: need to allow forceX and forceY, and xDomain, yDomain + .domain( d3.extent(d3.merge([forceX, rangez])) ) .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
// Retrieve the old x-scale, if this is an update. @@ -1013,6 +1093,11 @@ nv.models.bullet = function() { // Stash the new scale. this.__chart__ = x1;
+ + var rangeMin = d3.min(rangez), //rangez[2] + rangeMax = d3.max(rangez), //rangez[0] + rangeAvg = rangez[1]; + //------------------------------------------------------------
@@ -1024,6 +1109,12 @@ nv.models.bullet = function() { var gEnter = wrapEnter.append('g'); var g = wrap.select('g');
+ gEnter.append('rect').attr('class', 'nv-range nv-rangeMax'); + gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg'); + gEnter.append('rect').attr('class', 'nv-range nv-rangeMin'); + gEnter.append('rect').attr('class', 'nv-measure'); + gEnter.append('path').attr('class', 'nv-markerTriangle'); + wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//------------------------------------------------------------ @@ -1032,8 +1123,118 @@ nv.models.bullet = function() {
var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0) w1 = function(d) { return Math.abs(x1(d) - x1(0)) }; + var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) }, + xp1 = function(d) { return d < 0 ? x1(d) : x1(0) }; + + + g.select('rect.nv-rangeMax') + .attr('height', availableHeight) + .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin)) + .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin)) + .datum(rangeMax > 0 ? rangeMax : rangeMin) + /* + .attr('x', rangeMin < 0 ? + rangeMax > 0 ? + x1(rangeMin) + : x1(rangeMax) + : x1(0)) + */ + + g.select('rect.nv-rangeAvg') + .attr('height', availableHeight) + .attr('width', w1(rangeAvg)) + .attr('x', xp1(rangeAvg)) + .datum(rangeAvg) + /* + .attr('width', rangeMax <= 0 ? + x1(rangeMax) - x1(rangeAvg) + : x1(rangeAvg) - x1(rangeMin)) + .attr('x', rangeMax <= 0 ? + x1(rangeAvg) + : x1(rangeMin)) + */ + + g.select('rect.nv-rangeMin') + .attr('height', availableHeight) + .attr('width', w1(rangeMax)) + .attr('x', xp1(rangeMax)) + .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax)) + .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax)) + .datum(rangeMax > 0 ? rangeMin : rangeMax) + /* + .attr('width', rangeMax <= 0 ? + x1(rangeAvg) - x1(rangeMin) + : x1(rangeMax) - x1(rangeAvg)) + .attr('x', rangeMax <= 0 ? + x1(rangeMin) + : x1(rangeAvg)) + */ + + g.select('rect.nv-measure') + .style('fill', color) + .attr('height', availableHeight / 3) + .attr('y', availableHeight / 3) + .attr('width', measurez < 0 ? + x1(0) - x1(measurez[0]) + : x1(measurez[0]) - x1(0)) + .attr('x', xp1(measurez)) + .on('mouseover', function() { + dispatch.elementMouseover({ + value: measurez[0], + label: 'Current', + pos: [x1(measurez[0]), availableHeight/2] + }) + }) + .on('mouseout', function() { + dispatch.elementMouseout({ + value: measurez[0], + label: 'Current' + }) + }) + + var h3 = availableHeight / 6; + if (markerz[0]) { + g.selectAll('path.nv-markerTriangle') + .attr('transform', function(d) { return 'translate(' + x1(markerz[0]) + ',' + (availableHeight / 2) + ')' }) + .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z') + .on('mouseover', function() { + dispatch.elementMouseover({ + value: markerz[0], + label: 'Previous', + pos: [x1(markerz[0]), availableHeight/2] + }) + }) + .on('mouseout', function() { + dispatch.elementMouseout({ + value: markerz[0], + label: 'Previous' + }) + }); + } else { + g.selectAll('path.nv-markerTriangle').remove(); + } + + + wrap.selectAll('.nv-range') + .on('mouseover', function(d,i) { + var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum"; + + dispatch.elementMouseover({ + value: d, + label: label, + pos: [x1(d), availableHeight/2] + }) + }) + .on('mouseout', function(d,i) { + var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum";
+ dispatch.elementMouseout({ + value: d, + label: label + }) + })
+/* // THIS IS THE PREVIOUS BULLET IMPLEMENTATION, WILL REMOVE SHORTLY // Update the range rects. var range = g.selectAll('rect.nv-range') .data(rangez); @@ -1069,6 +1270,7 @@ nv.models.bullet = function() {
measure.enter().append('rect') .attr('class', function(d, i) { return 'nv-measure nv-s' + i; }) + .style('fill', function(d,i) { return color(d,i ) }) .attr('width', w0) .attr('height', availableHeight / 3) .attr('x', reverse ? x0 : 0) @@ -1119,13 +1321,14 @@ nv.models.bullet = function() { });
d3.transition(marker) - .attr('transform', function(d) { return 'translate(' + x1(d) + ',' + (availableHeight / 2) + ')' }); + .attr('transform', function(d) { return 'translate(' + (x1(d) - x1(0)) + ',' + (availableHeight / 2) + ')' });
marker.exit().remove(); +*/
});
- d3.timer.flush(); + // d3.timer.flush(); // Not needed?
return chart; } @@ -1199,6 +1402,12 @@ nv.models.bullet = function() { return chart; };
+ chart.color = function(_) { + if (!arguments.length) return color; + color = nv.utils.getColor(_); + return chart; + }; + //============================================================
@@ -1271,9 +1480,7 @@ nv.models.bulletChart = function() { //------------------------------------------------------------ // Display No Data message if there's nothing to show.
- /* - // Disabled until I figure out a better way to check for no data with the bullet chart - if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { + if (!d || !ranges.call(this, d, i)) { var noDataText = container.selectAll('.nv-noData').data([noData]);
noDataText.enter().append('text') @@ -1283,14 +1490,13 @@ nv.models.bulletChart = function() {
noDataText .attr('x', margin.left + availableWidth / 2) - .attr('y', margin.top + availableHeight / 2) + .attr('y', 18 + margin.top + availableHeight / 2) .text(function(d) { return d });
return chart; } else { container.selectAll('.nv-noData').remove(); } - */
//------------------------------------------------------------
@@ -1382,7 +1588,7 @@ nv.models.bulletChart = function() {
// Update the tick groups. var tick = g.selectAll('g.nv-tick') - .data(x1.ticks( availableWidth / 100 ), function(d) { + .data(x1.ticks( availableWidth / 50 ), function(d) { return this.textContent || format(d); });
@@ -1467,6 +1673,8 @@ nv.models.bulletChart = function() { chart.dispatch = dispatch; chart.bullet = bullet;
+ d3.rebind(chart, bullet, 'color'); + // left, right, top, bottom chart.orient = function(x) { if (!arguments.length) return orient; @@ -1577,13 +1785,15 @@ nv.models.cumulativeLineChart = function() { , x //can be accessed via chart.xScale() , y //can be accessed via chart.yScale() , id = lines.id() + , state = { index: 0, rescaleY: rescaleY } + , defaultState = null , noData = 'No Data Available.' - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') ;
xAxis .orient('bottom') - .tickPadding(5) + .tickPadding(7) ; yAxis .orient('left') @@ -1610,24 +1820,32 @@ nv.models.cumulativeLineChart = function() { nv.tooltip.show([left, top], content, null, null, offsetElement); };
- +/* + //Moved to see if we can get better behavior to fix issue #315 var indexDrag = d3.behavior.drag() .on('dragstart', dragStart) .on('drag', dragMove) .on('dragend', dragEnd);
- function dragStart(d,i) {} + function dragStart(d,i) { + d3.select(chart.container) + .style('cursor', 'ew-resize'); + }
function dragMove(d,i) { d.x += d3.event.dx; d.i = Math.round(dx.invert(d.x));
d3.select(this).attr('transform', 'translate(' + dx(d.i) + ',0)'); + chart.update(); }
function dragEnd(d,i) { + d3.select(chart.container) + .style('cursor', 'auto'); chart.update(); } +*/
//============================================================
@@ -1646,6 +1864,48 @@ nv.models.cumulativeLineChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + } + + var indexDrag = d3.behavior.drag() + .on('dragstart', dragStart) + .on('drag', dragMove) + .on('dragend', dragEnd); + + + function dragStart(d,i) { + d3.select(chart.container) + .style('cursor', 'ew-resize'); + } + + function dragMove(d,i) { + index.x = d3.event.x; + index.i = Math.round(dx.invert(index.x)); + updateZero(); + } + + function dragEnd(d,i) { + d3.select(chart.container) + .style('cursor', 'auto'); + + // update state and send stateChange with new index + state.index = index.i; + dispatch.stateChange(state); + } + + +
//------------------------------------------------------------ // Display No Data message if there's nothing to show. @@ -1684,6 +1944,9 @@ nv.models.cumulativeLineChart = function() { .map(function(series,i) { var initialDomain = d3.extent(series.values, lines.y());
+ //account for series being disabled when losing 95% or more + if (initialDomain[0] < -.95) initialDomain[0] = -.95; + return [ (initialDomain[0] - initialDomain[1]) / (1 + initialDomain[1]), (initialDomain[1] - initialDomain[0]) / (1 + initialDomain[0]) @@ -1720,6 +1983,7 @@ nv.models.cumulativeLineChart = function() {
gEnter.append('g').attr('class', 'nv-x nv-axis'); gEnter.append('g').attr('class', 'nv-y nv-axis'); + gEnter.append('g').attr('class', 'nv-background'); gEnter.append('g').attr('class', 'nv-linesWrap'); gEnter.append('g').attr('class', 'nv-legendWrap'); gEnter.append('g').attr('class', 'nv-controlsWrap'); @@ -1771,9 +2035,30 @@ nv.models.cumulativeLineChart = function() { wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
+ // Show error if series goes below 100% + var tempDisabled = data.filter(function(d) { return d.tempDisabled }); + + wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates + if (tempDisabled.length) { + wrap.append('text').attr('class', 'tempDisabled') + .attr('x', availableWidth / 2) + .attr('y', '-.71em') + .style('text-anchor', 'end') + .text(tempDisabled.map(function(d) { return d.key }).join(', ') + ' values cannot be calculated for this time period.'); + } + + + //------------------------------------------------------------ // Main Chart Component(s)
+ gEnter.select('.nv-background') + .append('rect'); + + g.select('.nv-background rect') + .attr('width', availableWidth) + .attr('height', availableHeight); + lines //.x(function(d) { return d.x }) .y(function(d) { return d.display.y }) @@ -1781,14 +2066,15 @@ nv.models.cumulativeLineChart = function() { .height(availableHeight) .color(data.map(function(d,i) { return d.color || color(d, i); - }).filter(function(d,i) { return !data[i].disabled })); + }).filter(function(d,i) { return !data[i].disabled && !data[i].tempDisabled }));
var linesWrap = g.select('.nv-linesWrap') - .datum(data.filter(function(d) { return !d.disabled })) + .datum(data.filter(function(d) { return !d.disabled && !d.tempDisabled }));
- d3.transition(linesWrap).call(lines); + //d3.transition(linesWrap).call(lines); + linesWrap.call(lines);
var indexLine = linesWrap.selectAll('.nv-indexLine') @@ -1812,7 +2098,8 @@ nv.models.cumulativeLineChart = function() {
xAxis .scale(x) - .ticks( availableWidth / 100 ) + //Suggest how many ticks based on the chart width and D3 should listen (70 is the optimal number for MM/DD/YY dates) + .ticks( Math.min(data[0].values.length,availableWidth/70) ) .tickSize(-availableHeight, 0);
g.select('.nv-x.nv-axis') @@ -1836,11 +2123,46 @@ nv.models.cumulativeLineChart = function() { // Event Handling/Dispatching (in chart's scope) //------------------------------------------------------------
+ + function updateZero() { + indexLine + .data([index]); + + chart.update(); + } + + g.select('.nv-background rect') + .on('click', function() { + index.x = d3.mouse(this)[0]; + index.i = Math.round(dx.invert(index.x)); + + // update state and send stateChange with new index + state.index = index.i; + dispatch.stateChange(state); + + updateZero(); + }); + + lines.dispatch.on('elementClick', function(e) { + index.i = e.pointIndex; + index.x = dx(index.i); + + // update state and send stateChange with new index + state.index = index.i; + dispatch.stateChange(state); + + updateZero(); + }); + controls.dispatch.on('legendClick', function(d,i) { d.disabled = !d.disabled; rescaleY = !d.disabled;
- selection.transition().call(chart); + state.rescaleY = rescaleY; + dispatch.stateChange(state); + + //selection.transition().call(chart); + selection.call(chart); });
@@ -1855,7 +2177,11 @@ nv.models.cumulativeLineChart = function() { }); }
- selection.transition().call(chart); + state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + + //selection.transition().call(chart); + selection.call(chart); });
/* @@ -1875,6 +2201,37 @@ nv.models.cumulativeLineChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ + // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + + if (typeof e.index !== 'undefined') { + index.i = e.index; + index.x = dx(index.i); + + state.index = e.index; + + indexLine + .data([index]); + } + + + if (typeof e.rescaleY !== 'undefined') { + rescaleY = e.rescaleY; + } + + selection.call(chart); + }); + //============================================================
}); @@ -1944,6 +2301,12 @@ nv.models.cumulativeLineChart = function() { return chart; };
+ chart.rescaleY = function(_) { + if (!arguments.length) return rescaleY; + rescaleY = _ + return rescaleY; + }; + chart.showControls = function(_) { if (!arguments.length) return showControls; showControls = _; @@ -1968,6 +2331,18 @@ nv.models.cumulativeLineChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -1986,16 +2361,20 @@ nv.models.cumulativeLineChart = function() { return data.map(function(line, i) { var v = lines.y()(line.values[idx], idx);
+ //TODO: implement check below, and disable series if series loses 100% or more cause divide by 0 issue + if (v < -.95) { + //if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically correct till it hits 100) + line.tempDisabled = true; + return line; + } + + line.tempDisabled = false; + line.values = line.values.map(function(point, pointIndex) { point.display = {'y': (lines.y()(point, pointIndex) - v) / (1 + v) }; return point; }) - /* - TODO: implement check below, and disable series if series loses 100% or more cause divide by 0 issue - if (v < -.9) { - //if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically currect till it hits 100) - } - */ + return line; }) } @@ -2027,6 +2406,7 @@ nv.models.discreteBar = function() { , xDomain , yDomain , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout') + , rectClass = 'discreteBar' ;
//============================================================ @@ -2128,7 +2508,7 @@ nv.models.discreteBar = function() {
var barsEnter = bars.enter().append('g') .attr('transform', function(d,i,j) { - return 'translate(' + x(getX(d,i)) + ', ' + y(0) + ')' + return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')' }) .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here d3.select(this).classed('hover', true); @@ -2180,13 +2560,13 @@ nv.models.discreteBar = function() {
barsEnter.append('rect') .attr('height', 0) - .attr('width', x.rangeBand() / data.length ) + .attr('width', x.rangeBand() * .9 / data.length )
if (showValues) { barsEnter.append('text') .attr('text-anchor', 'middle') bars.select('text') - .attr('x', x.rangeBand() / 2) + .attr('x', x.rangeBand() * .9 / 2) .attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 }) .text(function(d,i) { return valueFormat(getY(d,i)) }); } else { @@ -2198,16 +2578,24 @@ nv.models.discreteBar = function() { .style('fill', function(d,i) { return d.color || color(d,i) }) .style('stroke', function(d,i) { return d.color || color(d,i) }) .select('rect') - .attr('width', x.rangeBand() / data.length); + .attr('class', rectClass) + .attr('width', x.rangeBand() * .9 / data.length); d3.transition(bars) //.delay(function(d,i) { return i * 1200 / data[0].values.length }) - .attr('transform', function(d,i) { - return 'translate(' + x(getX(d,i)) + ', ' + (getY(d,i) < 0 ? y(0) : y(getY(d,i))) + ')' + .attr('transform', function(d,i) { + var left = x(getX(d,i)) + x.rangeBand() * .05, + top = getY(d,i) < 0 ? + y(0) : + y(0) - y(getY(d,i)) < 1 ? + y(0) - 1 : //make 1 px positive bars show up above y=0 + y(getY(d,i)); + + return 'translate(' + left + ', ' + top + ')' }) - .select('rect') - .attr('height', function(d,i) { - return Math.abs(y(getY(d,i)) - y(0)) - }); + .select('rect') + .attr('height', function(d,i) { + return Math.max(Math.abs(y(getY(d,i)) - y(0)) || 1) + });
//store old scales for use in transitions on update @@ -2313,6 +2701,11 @@ nv.models.discreteBar = function() { return chart; };
+ chart.rectClass= function(_) { + if (!arguments.length) return rectClass; + rectClass = _; + return chart; + } //============================================================
@@ -2343,7 +2736,7 @@ nv.models.discreteBarChart = function() { , x , y , noData = "No Data Available." - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'beforeUpdate') ;
xAxis @@ -2388,7 +2781,7 @@ nv.models.discreteBarChart = function() { - margin.top - margin.bottom;
- chart.update = function() { selection.transition().call(chart); }; + chart.update = function() { dispatch.beforeUpdate(); selection.transition().call(chart); }; chart.container = this;
@@ -2486,10 +2879,11 @@ nv.models.discreteBarChart = function() {
var xTicks = g.select('.nv-x.nv-axis').selectAll('g');
- if (staggerLabels) + if (staggerLabels) { xTicks .selectAll('text') - .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '0' : '12') + ')' }) + .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '5' : '17') + ')' }) + }
yAxis .scale(y) @@ -2753,7 +3147,6 @@ nv.models.distribution = function() {
return chart; } - nv.models.indentedTree = function() {
//============================================================ @@ -2766,6 +3159,7 @@ nv.models.indentedTree = function() { , color = nv.utils.defaultColor() , id = Math.floor(Math.random() * 10000) , header = true + , filterZero = false , noData = "No Data Available." , childIndent = 20 , columns = [{key:'key', label: 'Name', type:'text'}] //TODO: consider functions like chart.addColumn, chart.removeColumn, instead of a block like this @@ -2777,30 +3171,32 @@ nv.models.indentedTree = function() {
//============================================================
+ var idx = 0;
function chart(selection) { selection.each(function(data) { - var i = 0, - depth = 1; + var depth = 1, + container = d3.select(this);
var tree = d3.layout.tree() .children(function(d) { return d.values }) .size([height, childIndent]); //Not sure if this is needed now that the result is HTML
- chart.update = function() { selection.transition().call(chart) }; - chart.container = this; + chart.update = function() { container.transition().duration(600).call(chart) };
//------------------------------------------------------------ // Display No Data message if there's nothing to show. - - if (!data[0].key) data[0].key = noData; + if (!data[0]) data[0] = {key: noData};
//------------------------------------------------------------
var nodes = tree.nodes(data[0]);
+ // nodes.map(function(d) { + // d.id = i++; + // })
//------------------------------------------------------------ // Setup containers and skeleton of chart @@ -2830,7 +3226,7 @@ nv.models.indentedTree = function() {
var tbody = table.selectAll('tbody') - .data(function(d) {return d }); + .data(function(d) { return d }); tbody.enter().append('tbody');
@@ -2842,12 +3238,12 @@ nv.models.indentedTree = function() {
// Update the nodes… var node = tbody.selectAll('tr') - .data(function(d) { return d }, function(d) { return d.id || (d.id == ++i)}); + // .data(function(d) { return d; }, function(d) { return d.id || (d.id == ++i)}); + .data(function(d) { return d.filter(function(d) { return (filterZero && !d.children) ? filterZero(d) : true; } )}, function(d,i) { return d.id || (d.id || ++idx)}); //.style('display', 'table-row'); //TODO: see if this does anything
node.exit().remove();
- node.select('img.nv-treeicon') .attr('src', icon) .classed('folded', folded); @@ -2880,22 +3276,24 @@ nv.models.indentedTree = function() { .text(function(d) { return column.format ? column.format(d) : (d[column.key] || '-') });
- if (column.showCount) + if (column.showCount) { nodeName.append('span') - .attr('class', 'nv-childrenCount') - .text(function(d) { - return ((d.values && d.values.length) || (d._values && d._values.length)) ? - '(' + ((d.values && d.values.length) || (d._values && d._values.length)) + ')' - : '' - }); + .attr('class', 'nv-childrenCount');
+ node.selectAll('span.nv-childrenCount').text(function(d) { + return ((d.values && d.values.length) || (d._values && d._values.length)) ? //If this is a parent + '(' + ((d.values && (d.values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length)) //If children are in values check its children and filter + || (d._values && d._values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length) //Otherwise, do the same, but with the other name, _values... + || 0) + ')' //This is the catch-all in case there are no children after a filter + : '' //If this is not a parent, just give an empty string + }); + }
if (column.click) nodeName.select('span').on('click', column.click);
});
- node .order() .on('click', function(d) { @@ -3031,6 +3429,12 @@ nv.models.indentedTree = function() { return chart; };
+ chart.filterZero = function(_) { + if (!arguments.length) return filterZero; + filterZero = _; + return chart; + }; + chart.columns = function(_) { if (!arguments.length) return columns; columns = _; @@ -3059,8 +3463,7 @@ nv.models.indentedTree = function() {
return chart; -} -nv.models.legend = function() { +};nv.models.legend = function() {
//============================================================ // Public Variables with Default Settings @@ -3270,24 +3673,24 @@ nv.models.line = function() { // Public Variables with Default Settings //------------------------------------------------------------
+ var scatter = nv.models.scatter() + ; + var margin = {top: 0, right: 0, bottom: 0, left: 0} , width = 960 , height = 500 , color = nv.utils.defaultColor() // a function that returns a color - , id = Math.floor(Math.random() * 10000) //Create semi-unique ID incase user doesn't select one , getX = function(d) { return d.x } // accessor to get the x value from a data point , getY = function(d) { return d.y } // accessor to get the y value from a data point - , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continous when it is not defined + , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined , isArea = function(d) { return d.area } // decides if a line is an area or just a line , clipEdge = false // if true, masks lines within x and y scale , x //can be accessed via chart.xScale() , y //can be accessed via chart.yScale() , interpolate = "linear" // controls the line interpolation - , scatter = nv.models.scatter() ;
scatter - .id(id) .size(16) // default size .sizeDomain([16,256]) //set to speed up calculation, needs to be unset if there is a custom size accessor ; @@ -3354,16 +3757,16 @@ nv.models.line = function() {
defsEnter.append('clipPath') - .attr('id', 'nv-edge-clip-' + id) + .attr('id', 'nv-edge-clip-' + scatter.id()) .append('rect');
- wrap.select('#nv-edge-clip-' + id + ' rect') + wrap.select('#nv-edge-clip-' + scatter.id() + ' rect') .attr('width', availableWidth) .attr('height', availableHeight);
- g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : ''); + g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : ''); scatterWrap - .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : ''); + .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : '');
@@ -3474,7 +3877,7 @@ nv.models.line = function() { chart.dispatch = scatter.dispatch; chart.scatter = scatter;
- d3.rebind(chart, scatter, 'interactive', 'size', 'xScale', 'yScale', 'zScale', 'xDomain', 'yDomain', 'sizeDomain', 'forceX', 'forceY', 'forceSize', 'clipVoronoi', 'clipRadius'); + d3.rebind(chart, scatter, 'id', 'interactive', 'size', 'xScale', 'yScale', 'zScale', 'xDomain', 'yDomain', 'sizeDomain', 'forceX', 'forceY', 'forceSize', 'clipVoronoi', 'clipRadius', 'padData');
chart.margin = function(_) { if (!arguments.length) return margin; @@ -3524,12 +3927,6 @@ nv.models.line = function() { return chart; };
- chart.id = function(_) { - if (!arguments.length) return id; - id = _; - return chart; - }; - chart.interpolate = function(_) { if (!arguments.length) return interpolate; interpolate = _; @@ -3566,6 +3963,7 @@ nv.models.lineChart = function() { , legend = nv.models.legend() ;
+//set margin.right to 23 to fit dates on the x-axis within the chart var margin = {top: 30, right: 20, bottom: 50, left: 60} , color = nv.utils.defaultColor() , width = null @@ -3578,13 +3976,15 @@ nv.models.lineChart = function() { } , x , y + , state = {} + , defaultState = null , noData = 'No Data Available.' - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') ;
xAxis .orient('bottom') - .tickPadding(5) + .tickPadding(7) ; yAxis .orient('left') @@ -3637,6 +4037,19 @@ nv.models.lineChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display noData message if there's nothing to show. @@ -3770,6 +4183,9 @@ nv.models.lineChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -3789,6 +4205,20 @@ nv.models.lineChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + selection.call(chart); + }); + //============================================================
}); @@ -3876,6 +4306,18 @@ nv.models.lineChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -3917,16 +4359,23 @@ nv.models.linePlusBarChart = function() { , x , y1 , y2 + , state = {} + , defaultState = null , noData = "No Data Available." - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') ;
+ bars + .padData(true) + ; lines .clipEdge(false) + .padData(true) ; xAxis .orient('bottom') - .tickPadding(5) + .tickPadding(7) + .highlightZero(false) ; y1Axis .orient('left') @@ -3943,14 +4392,15 @@ nv.models.linePlusBarChart = function() { //------------------------------------------------------------
var showTooltip = function(e, offsetElement) { - var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ), - top = e.pos[1] + ( offsetElement.offsetTop || 0), - x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)), - y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point, e.pointIndex)), - content = tooltip(e.series.key, x, y, e, chart); + var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ), + top = e.pos[1] + ( offsetElement.offsetTop || 0), + x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)), + y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point, e.pointIndex)), + content = tooltip(e.series.key, x, y, e, chart);
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement); - }; + nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement); + } + ;
//------------------------------------------------------------
@@ -3969,6 +4419,19 @@ nv.models.linePlusBarChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display No Data message if there's nothing to show. @@ -3997,51 +4460,19 @@ nv.models.linePlusBarChart = function() { //------------------------------------------------------------ // Setup Scales
- x = xAxis.scale(); - y1 = bars.yScale(); - y2 = lines.yScale(); - var dataBars = data.filter(function(d) { return !d.disabled && d.bar }); var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240
+ //x = xAxis.scale(); + x = dataLines.filter(function(d) { return !d.disabled; }).length && dataLines.filter(function(d) { return !d.disabled; })[0].values.length ? lines.xScale() : bars.xScale(); + //x = dataLines.filter(function(d) { return !d.disabled; }).length ? lines.xScale() : bars.xScale(); //old code before change above + y1 = bars.yScale(); + y2 = lines.yScale();
- //TODO: try to remove x scale computation from this layer - - var series1 = data.filter(function(d) { return !d.disabled && d.bar }) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i) } - }) - }); + //------------------------------------------------------------
- var series2 = data.filter(function(d) { return !d.disabled && !d.bar }) - .map(function(d) { - return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i) } - }) - }); - - x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } )) - .range([0, availableWidth]); - - - - /* - x .domain(d3.extent(d3.merge(data.map(function(d) { return d.values })), getX )) - .range([0, availableWidth]); - - y1 .domain(d3.extent(d3.merge(dataBars), function(d) { return d.y } )) - .range([availableHeight, 0]); - - y2 .domain(d3.extent(d3.merge(dataLines), function(d) { return d.y } )) - .range([availableHeight, 0]); - */ - - //------------------------------------------------------------ - - - //------------------------------------------------------------ - // Setup containers and skeleton of chart + //------------------------------------------------------------ + // Setup containers and skeleton of chart
var wrap = d3.select(this).selectAll('g.nv-wrap.nv-linePlusBar').data([data]); var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g'); @@ -4111,7 +4542,7 @@ nv.models.linePlusBarChart = function() { .datum(dataBars.length ? dataBars : [{values:[]}])
var linesWrap = g.select('.nv-linesWrap') - .datum(!dataLines[0].disabled ? dataLines : [{values:[]}] ); + .datum(dataLines[0] && !dataLines[0].disabled ? dataLines : [{values:[]}] ); //.datum(!dataLines[0].disabled ? dataLines : [{values:dataLines[0].values.map(function(d) { return [d[0], null] }) }] );
d3.transition(barsWrap).call(bars); @@ -4124,6 +4555,7 @@ nv.models.linePlusBarChart = function() { // Setup Axes
xAxis + .scale(x) .ticks( availableWidth / 100 ) .tickSize(-availableHeight, 0);
@@ -4150,7 +4582,8 @@ nv.models.linePlusBarChart = function() {
g.select('.nv-y2.nv-axis') .style('opacity', dataLines.length ? 1 : 0) - .attr('transform', 'translate(' + x.range()[1] + ',0)'); + .attr('transform', 'translate(' + availableWidth + ',0)'); + //.attr('transform', 'translate(' + x.range()[1] + ',0)');
d3.transition(g.select('.nv-y2.nv-axis')) .call(y2Axis); @@ -4173,6 +4606,9 @@ nv.models.linePlusBarChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -4180,6 +4616,21 @@ nv.models.linePlusBarChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ + // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + selection.call(chart); + }); + //============================================================
@@ -4297,6 +4748,18 @@ nv.models.linePlusBarChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -4527,33 +4990,614 @@ nv.models.lineWithFocusChart = function() { //------------------------------------------------------------
- /* - var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') - .datum(data.filter(function(d) { return !d.disabled })) + /* + var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') + .datum(data.filter(function(d) { return !d.disabled })) + + d3.transition(focusLinesWrap).call(lines); + */ + + + //------------------------------------------------------------ + // Setup Main (Focus) Axes + + xAxis + .scale(x) + .ticks( availableWidth / 100 ) + .tickSize(-availableHeight1, 0); + + yAxis + .scale(y) + .ticks( availableHeight1 / 36 ) + .tickSize( -availableWidth, 0); + + g.select('.nv-focus .nv-x.nv-axis') + .attr('transform', 'translate(0,' + availableHeight1 + ')'); + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Setup Brush + + brush + .x(x2) + .on('brush', onBrush); + + if (brushExtent) brush.extent(brushExtent); + + var brushBG = g.select('.nv-brushBackground').selectAll('g') + .data([brushExtent || brush.extent()]) + + var brushBGenter = brushBG.enter() + .append('g'); + + brushBGenter.append('rect') + .attr('class', 'left') + .attr('x', 0) + .attr('y', 0) + .attr('height', availableHeight2); + + brushBGenter.append('rect') + .attr('class', 'right') + .attr('x', 0) + .attr('y', 0) + .attr('height', availableHeight2); + + gBrush = g.select('.nv-x.nv-brush') + .call(brush); + gBrush.selectAll('rect') + //.attr('y', -5) + .attr('height', availableHeight2); + gBrush.selectAll('.resize').append('path').attr('d', resizePath); + + onBrush(); + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Setup Secondary (Context) Axes + + x2Axis + .scale(x2) + .ticks( availableWidth / 100 ) + .tickSize(-availableHeight2, 0); + + g.select('.nv-context .nv-x.nv-axis') + .attr('transform', 'translate(0,' + y2.range()[0] + ')'); + d3.transition(g.select('.nv-context .nv-x.nv-axis')) + .call(x2Axis); + + + y2Axis + .scale(y2) + .ticks( availableHeight2 / 36 ) + .tickSize( -availableWidth, 0); + + d3.transition(g.select('.nv-context .nv-y.nv-axis')) + .call(y2Axis); + + g.select('.nv-context .nv-x.nv-axis') + .attr('transform', 'translate(0,' + y2.range()[0] + ')'); + + //------------------------------------------------------------ + + + //============================================================ + // Event Handling/Dispatching (in chart's scope) + //------------------------------------------------------------ + + legend.dispatch.on('legendClick', function(d,i) { + d.disabled = !d.disabled; + + if (!data.filter(function(d) { return !d.disabled }).length) { + data.map(function(d) { + d.disabled = false; + wrap.selectAll('.nv-series').classed('disabled', false); + return d; + }); + } + + selection.transition().call(chart); + }); + + dispatch.on('tooltipShow', function(e) { + if (tooltips) showTooltip(e, that.parentNode); + }); + + //============================================================ + + + //============================================================ + // Functions + //------------------------------------------------------------ + + // Taken from crossfilter (http://square.github.com/crossfilter/) + function resizePath(d) { + var e = +(d == 'e'), + x = e ? 1 : -1, + y = availableHeight2 / 3; + return 'M' + (.5 * x) + ',' + y + + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6) + + 'V' + (2 * y - 6) + + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y) + + 'Z' + + 'M' + (2.5 * x) + ',' + (y + 8) + + 'V' + (2 * y - 8) + + 'M' + (4.5 * x) + ',' + (y + 8) + + 'V' + (2 * y - 8); + } + + + function updateBrushBG() { + if (!brush.empty()) brush.extent(brushExtent); + brushBG + .data([brush.empty() ? x2.domain() : brushExtent]) + .each(function(d,i) { + var leftWidth = x2(d[0]) - x.range()[0], + rightWidth = x.range()[1] - x2(d[1]); + d3.select(this).select('.left') + .attr('width', leftWidth < 0 ? 0 : leftWidth); + + d3.select(this).select('.right') + .attr('x', x2(d[1])) + .attr('width', rightWidth < 0 ? 0 : rightWidth); + }); + } + + + function onBrush() { + brushExtent = brush.empty() ? null : brush.extent(); + extent = brush.empty() ? x2.domain() : brush.extent(); + + + dispatch.brush({extent: extent, brush: brush}); + + + updateBrushBG(); + + // Update Main (Focus) + var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') + .datum( + data + .filter(function(d) { return !d.disabled }) + .map(function(d,i) { + return { + key: d.key, + values: d.values.filter(function(d,i) { + return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1]; + }) + } + }) + ); + d3.transition(focusLinesWrap).call(lines); + + + // Update Main (Focus) Axes + d3.transition(g.select('.nv-focus .nv-x.nv-axis')) + .call(xAxis); + d3.transition(g.select('.nv-focus .nv-y.nv-axis')) + .call(yAxis); + } + + //============================================================ + + + }); + + return chart; + } + + + //============================================================ + // Event Handling/Dispatching (out of chart's scope) + //------------------------------------------------------------ + + lines.dispatch.on('elementMouseover.tooltip', function(e) { + e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top]; + dispatch.tooltipShow(e); + }); + + lines.dispatch.on('elementMouseout.tooltip', function(e) { + dispatch.tooltipHide(e); + }); + + dispatch.on('tooltipHide', function() { + if (tooltips) nv.tooltip.cleanup(); + }); + + //============================================================ + + + //============================================================ + // Expose Public Variables + //------------------------------------------------------------ + + // expose chart's sub-components + chart.dispatch = dispatch; + chart.legend = legend; + chart.lines = lines; + chart.lines2 = lines2; + chart.xAxis = xAxis; + chart.yAxis = yAxis; + chart.x2Axis = x2Axis; + chart.y2Axis = y2Axis; + + d3.rebind(chart, lines, 'defined', 'isArea', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id'); + + chart.x = function(_) { + if (!arguments.length) return lines.x; + lines.x(_); + lines2.x(_); + return chart; + }; + + chart.y = function(_) { + if (!arguments.length) return lines.y; + lines.y(_); + lines2.y(_); + return chart; + }; + + chart.margin = function(_) { + if (!arguments.length) return margin; + margin.top = typeof _.top != 'undefined' ? _.top : margin.top; + margin.right = typeof _.right != 'undefined' ? _.right : margin.right; + margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom; + margin.left = typeof _.left != 'undefined' ? _.left : margin.left; + return chart; + }; + + chart.margin2 = function(_) { + if (!arguments.length) return margin2; + margin2 = _; + return chart; + }; + + chart.width = function(_) { + if (!arguments.length) return width; + width = _; + return chart; + }; + + chart.height = function(_) { + if (!arguments.length) return height; + height = _; + return chart; + }; + + chart.height2 = function(_) { + if (!arguments.length) return height2; + height2 = _; + return chart; + }; + + chart.color = function(_) { + if (!arguments.length) return color; + color =nv.utils.getColor(_); + legend.color(color); + return chart; + }; + + chart.showLegend = function(_) { + if (!arguments.length) return showLegend; + showLegend = _; + return chart; + }; + + chart.tooltips = function(_) { + if (!arguments.length) return tooltips; + tooltips = _; + return chart; + }; + + chart.tooltipContent = function(_) { + if (!arguments.length) return tooltip; + tooltip = _; + return chart; + }; + + chart.interpolate = function(_) { + if (!arguments.length) return lines.interpolate(); + lines.interpolate(_); + lines2.interpolate(_); + return chart; + }; + + chart.noData = function(_) { + if (!arguments.length) return noData; + noData = _; + return chart; + }; + + // Chart has multiple similar Axes, to prevent code duplication, probably need to link all axis functions manually like below + chart.xTickFormat = function(_) { + if (!arguments.length) return xAxis.tickFormat(); + xAxis.tickFormat(_); + x2Axis.tickFormat(_); + return chart; + }; + + chart.yTickFormat = function(_) { + if (!arguments.length) return yAxis.tickFormat(); + yAxis.tickFormat(_); + y2Axis.tickFormat(_); + return chart; + }; + + //============================================================ + + + return chart; +} + +nv.models.linePlusBarWithFocusChart = function() { + + //============================================================ + // Public Variables with Default Settings + //------------------------------------------------------------ + + var lines = nv.models.line() + , lines2 = nv.models.line() + , bars = nv.models.historicalBar() + , bars2 = nv.models.historicalBar() + , xAxis = nv.models.axis() + , x2Axis = nv.models.axis() + , y1Axis = nv.models.axis() + , y2Axis = nv.models.axis() + , y3Axis = nv.models.axis() + , y4Axis = nv.models.axis() + , legend = nv.models.legend() + , brush = d3.svg.brush() + ; + + var margin = {top: 30, right: 30, bottom: 30, left: 60} + , margin2 = {top: 0, right: 30, bottom: 20, left: 60} + , width = null + , height = null + , height2 = 100 + , getX = function(d) { return d.x } + , getY = function(d) { return d.y } + , color = nv.utils.defaultColor() + , showLegend = true + , extent + , brushExtent = null + , tooltips = true + , tooltip = function(key, x, y, e, graph) { + return '<h3>' + key + '</h3>' + + '<p>' + y + ' at ' + x + '</p>'; + } + , x + , x2 + , y1 + , y2 + , y3 + , y4 + , noData = "No Data Available." + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'brush') + ; + + lines + .clipEdge(true) + ; + lines2 + .interactive(false) + ; + xAxis + .orient('bottom') + .tickPadding(5) + ; + y1Axis + .orient('left') + ; + y2Axis + .orient('right') + ; + x2Axis + .orient('bottom') + .tickPadding(5) + ; + y3Axis + .orient('left') + ; + y4Axis + .orient('right') + ; + + //============================================================ + + + //============================================================ + // Private Variables + //------------------------------------------------------------ + + var showTooltip = function(e, offsetElement) { + if (extent) { + e.pointIndex += Math.ceil(extent[0]); + } + var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ), + top = e.pos[1] + ( offsetElement.offsetTop || 0), + x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)), + y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point, e.pointIndex)), + content = tooltip(e.series.key, x, y, e, chart); + + nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement); + }; + + //------------------------------------------------------------ + + + + function chart(selection) { + selection.each(function(data) { + var container = d3.select(this), + that = this; + + var availableWidth = (width || parseInt(container.style('width')) || 960) + - margin.left - margin.right, + availableHeight1 = (height || parseInt(container.style('height')) || 400) + - margin.top - margin.bottom - height2, + availableHeight2 = height2 - margin2.top - margin2.bottom; + + chart.update = function() { chart(selection) }; + chart.container = this; + + + //------------------------------------------------------------ + // Display No Data message if there's nothing to show. + + if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) { + var noDataText = container.selectAll('.nv-noData').data([noData]); + + noDataText.enter().append('text') + .attr('class', 'nvd3 nv-noData') + .attr('dy', '-.7em') + .style('text-anchor', 'middle'); + + noDataText + .attr('x', margin.left + availableWidth / 2) + .attr('y', margin.top + availableHeight1 / 2) + .text(function(d) { return d }); + + return chart; + } else { + container.selectAll('.nv-noData').remove(); + } + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Setup Scales + + var dataBars = data.filter(function(d) { return !d.disabled && d.bar }); + var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240 + + x = bars.xScale(); + x2 = x2Axis.scale(); + y1 = bars.yScale(); + y2 = lines.yScale(); + y3 = bars2.yScale(); + y4 = lines2.yScale(); + + var series1 = data + .filter(function(d) { return !d.disabled && d.bar }) + .map(function(d) { + return d.values.map(function(d,i) { + return { x: getX(d,i), y: getY(d,i) } + }) + }); + + var series2 = data + .filter(function(d) { return !d.disabled && !d.bar }) + .map(function(d) { + return d.values.map(function(d,i) { + return { x: getX(d,i), y: getY(d,i) } + }) + }); + + x .range([0, availableWidth]); + + x2 .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } )) + .range([0, availableWidth]); + + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Setup containers and skeleton of chart + + var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]); + var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g'); + var g = wrap.select('g'); + + gEnter.append('g').attr('class', 'nv-legendWrap'); + + var focusEnter = gEnter.append('g').attr('class', 'nv-focus'); + focusEnter.append('g').attr('class', 'nv-x nv-axis'); + focusEnter.append('g').attr('class', 'nv-y1 nv-axis'); + focusEnter.append('g').attr('class', 'nv-y2 nv-axis'); + focusEnter.append('g').attr('class', 'nv-barsWrap'); + focusEnter.append('g').attr('class', 'nv-linesWrap'); + + var contextEnter = gEnter.append('g').attr('class', 'nv-context'); + contextEnter.append('g').attr('class', 'nv-x nv-axis'); + contextEnter.append('g').attr('class', 'nv-y1 nv-axis'); + contextEnter.append('g').attr('class', 'nv-y2 nv-axis'); + contextEnter.append('g').attr('class', 'nv-barsWrap'); + contextEnter.append('g').attr('class', 'nv-linesWrap'); + contextEnter.append('g').attr('class', 'nv-brushBackground'); + contextEnter.append('g').attr('class', 'nv-x nv-brush'); + + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Legend + + if (showLegend) { + legend.width( availableWidth / 2 ); + + g.select('.nv-legendWrap') + .datum(data.map(function(series) { + series.originalKey = series.originalKey === undefined ? series.key : series.originalKey; + series.key = series.originalKey + (series.bar ? ' (left axis)' : ' (right axis)'); + return series; + })) + .call(legend); + + if ( margin.top != legend.height()) { + margin.top = legend.height(); + availableHeight1 = (height || parseInt(container.style('height')) || 400) + - margin.top - margin.bottom - height2; + } + + g.select('.nv-legendWrap') + .attr('transform', 'translate(' + ( availableWidth / 2 ) + ',' + (-margin.top) +')'); + } + + //------------------------------------------------------------ +
- d3.transition(focusLinesWrap).call(lines); - */ + wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//------------------------------------------------------------ - // Setup Main (Focus) Axes + // Context Components
- xAxis - .scale(x) - .ticks( availableWidth / 100 ) - .tickSize(-availableHeight1, 0); + bars2 + .width(availableWidth) + .height(availableHeight2) + .color(data.map(function(d,i) { + return d.color || color(d, i); + }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));
- yAxis - .scale(y) - .ticks( availableHeight1 / 36 ) - .tickSize( -availableWidth, 0); + lines2 + .width(availableWidth) + .height(availableHeight2) + .color(data.map(function(d,i) { + return d.color || color(d, i); + }).filter(function(d,i) { return !data[i].disabled && !data[i].bar })); + + var bars2Wrap = g.select('.nv-context .nv-barsWrap') + .datum(dataBars.length ? dataBars : [{values:[]}]); + + var lines2Wrap = g.select('.nv-context .nv-linesWrap') + .datum(!dataLines[0].disabled ? dataLines : [{values:[]}]); + + g.select('.nv-context') + .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')')
- g.select('.nv-focus .nv-x.nv-axis') - .attr('transform', 'translate(0,' + availableHeight1 + ')'); + d3.transition(bars2Wrap).call(bars2); + d3.transition(lines2Wrap).call(lines2);
//------------------------------------------------------------
+ //------------------------------------------------------------ // Setup Brush
@@ -4581,51 +5625,60 @@ nv.models.lineWithFocusChart = function() { .attr('y', 0) .attr('height', availableHeight2);
- gBrush = g.select('.nv-x.nv-brush') + var gBrush = g.select('.nv-x.nv-brush') .call(brush); gBrush.selectAll('rect') //.attr('y', -5) .attr('height', availableHeight2); gBrush.selectAll('.resize').append('path').attr('d', resizePath);
- onBrush(); - //------------------------------------------------------------
- //------------------------------------------------------------ // Setup Secondary (Context) Axes
x2Axis - .scale(x2) .ticks( availableWidth / 100 ) .tickSize(-availableHeight2, 0);
g.select('.nv-context .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y2.range()[0] + ')'); + .attr('transform', 'translate(0,' + y3.range()[0] + ')'); d3.transition(g.select('.nv-context .nv-x.nv-axis')) .call(x2Axis);
- y2Axis - .scale(y2) + y3Axis + .scale(y3) .ticks( availableHeight2 / 36 ) .tickSize( -availableWidth, 0);
- d3.transition(g.select('.nv-context .nv-y.nv-axis')) - .call(y2Axis); + g.select('.nv-context .nv-y1.nv-axis') + .style('opacity', dataBars.length ? 1 : 0) + .attr('transform', 'translate(0,' + x2.range()[0] + ')'); + + d3.transition(g.select('.nv-context .nv-y1.nv-axis')) + .call(y3Axis); + + + y4Axis + .scale(y4) + .ticks( availableHeight2 / 36 ) + .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none
- g.select('.nv-context .nv-x.nv-axis') - .attr('transform', 'translate(0,' + y2.range()[0] + ')'); + g.select('.nv-context .nv-y2.nv-axis') + .style('opacity', dataLines.length ? 1 : 0) + .attr('transform', 'translate(' + x2.range()[1] + ',0)');
+ d3.transition(g.select('.nv-context .nv-y2.nv-axis')) + .call(y4Axis); + //------------------------------------------------------------
- //============================================================ // Event Handling/Dispatching (in chart's scope) //------------------------------------------------------------
- legend.dispatch.on('legendClick', function(d,i) { + legend.dispatch.on('legendClick', function(d,i) { d.disabled = !d.disabled;
if (!data.filter(function(d) { return !d.disabled }).length) { @@ -4636,7 +5689,7 @@ nv.models.lineWithFocusChart = function() { }); }
- selection.transition().call(chart); + selection.call(chart); });
dispatch.on('tooltipShow', function(e) { @@ -4672,8 +5725,8 @@ nv.models.lineWithFocusChart = function() { brushBG .data([brush.empty() ? x2.domain() : brushExtent]) .each(function(d,i) { - var leftWidth = x2(d[0]) - x.range()[0], - rightWidth = x.range()[1] - x2(d[1]); + var leftWidth = x2(d[0]) - x2.range()[0], + rightWidth = x2.range()[1] - x2(d[1]); d3.select(this).select('.left') .attr('width', leftWidth < 0 ? 0 : leftWidth);
@@ -4691,14 +5744,43 @@ nv.models.lineWithFocusChart = function() {
dispatch.brush({extent: extent, brush: brush});
- updateBrushBG();
- // Update Main (Focus) + + //------------------------------------------------------------ + // Prepare Main (Focus) Bars and Lines + + bars + .width(availableWidth) + .height(availableHeight1) + .color(data.map(function(d,i) { + return d.color || color(d, i); + }).filter(function(d,i) { return !data[i].disabled && data[i].bar })); + + + lines + .width(availableWidth) + .height(availableHeight1) + .color(data.map(function(d,i) { + return d.color || color(d, i); + }).filter(function(d,i) { return !data[i].disabled && !data[i].bar })); + + var focusBarsWrap = g.select('.nv-focus .nv-barsWrap') + .datum(!dataBars.length ? [{values:[]}] : + dataBars + .map(function(d,i) { + return { + key: d.key, + values: d.values.filter(function(d,i) { + return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <= extent[1]; + }) + } + }) + ); + var focusLinesWrap = g.select('.nv-focus .nv-linesWrap') - .datum( - data - .filter(function(d) { return !d.disabled }) + .datum(dataLines[0].disabled ? [{values:[]}] : + dataLines .map(function(d,i) { return { key: d.key, @@ -4707,19 +5789,75 @@ nv.models.lineWithFocusChart = function() { }) } }) - ); + ); + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Update Main (Focus) X Axis + + if (dataBars.length) { + x = bars.xScale(); + } else { + x = lines.xScale(); + } + + xAxis + .scale(x) + .ticks( availableWidth / 100 ) + .tickSize(-availableHeight1, 0); + + xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]); + + d3.transition(g.select('.nv-x.nv-axis')) + .call(xAxis); + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Update Main (Focus) Bars and Lines + + d3.transition(focusBarsWrap).call(bars); d3.transition(focusLinesWrap).call(lines); + + //------------------------------------------------------------ + + + //------------------------------------------------------------ + // Setup and Update Main (Focus) Y Axes + + g.select('.nv-focus .nv-x.nv-axis') + .attr('transform', 'translate(0,' + y1.range()[0] + ')');
- // Update Main (Focus) Axes - d3.transition(g.select('.nv-focus .nv-x.nv-axis')) - .call(xAxis); - d3.transition(g.select('.nv-focus .nv-y.nv-axis')) - .call(yAxis); + y1Axis + .scale(y1) + .ticks( availableHeight1 / 36 ) + .tickSize(-availableWidth, 0); + + g.select('.nv-focus .nv-y1.nv-axis') + .style('opacity', dataBars.length ? 1 : 0); + + + y2Axis + .scale(y2) + .ticks( availableHeight1 / 36 ) + .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none + + g.select('.nv-focus .nv-y2.nv-axis') + .style('opacity', dataLines.length ? 1 : 0) + .attr('transform', 'translate(' + x.range()[1] + ',0)'); + + d3.transition(g.select('.nv-focus .nv-y1.nv-axis')) + .call(y1Axis); + d3.transition(g.select('.nv-focus .nv-y2.nv-axis')) + .call(y2Axis); }
//============================================================
+ onBrush();
});
@@ -4740,6 +5878,15 @@ nv.models.lineWithFocusChart = function() { dispatch.tooltipHide(e); });
+ bars.dispatch.on('elementMouseover.tooltip', function(e) { + e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top]; + dispatch.tooltipShow(e); + }); + + bars.dispatch.on('elementMouseout.tooltip', function(e) { + dispatch.tooltipHide(e); + }); + dispatch.on('tooltipHide', function() { if (tooltips) nv.tooltip.cleanup(); }); @@ -4756,24 +5903,32 @@ nv.models.lineWithFocusChart = function() { chart.legend = legend; chart.lines = lines; chart.lines2 = lines2; + chart.bars = bars; + chart.bars2 = bars2; chart.xAxis = xAxis; - chart.yAxis = yAxis; chart.x2Axis = x2Axis; + chart.y1Axis = y1Axis; chart.y2Axis = y2Axis; + chart.y3Axis = y3Axis; + chart.y4Axis = y4Axis;
- d3.rebind(chart, lines, 'defined', 'isArea', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id'); + d3.rebind(chart, lines, 'defined', 'size', 'clipVoronoi', 'interpolate'); + //TODO: consider rebinding x, y and some other stuff, and simply do soemthign lile bars.x(lines.x()), etc. + //d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
chart.x = function(_) { - if (!arguments.length) return lines.x; + if (!arguments.length) return getX; + getX = _; lines.x(_); - lines2.x(_); + bars.x(_); return chart; };
chart.y = function(_) { - if (!arguments.length) return lines.y; + if (!arguments.length) return getY; + getY = _; lines.y(_); - lines2.y(_); + bars.y(_); return chart; };
@@ -4786,12 +5941,6 @@ nv.models.lineWithFocusChart = function() { return chart; };
- chart.margin2 = function(_) { - if (!arguments.length) return margin2; - margin2 = _; - return chart; - }; - chart.width = function(_) { if (!arguments.length) return width; width = _; @@ -4806,7 +5955,7 @@ nv.models.lineWithFocusChart = function() {
chart.color = function(_) { if (!arguments.length) return color; - color =nv.utils.getColor(_); + color = nv.utils.getColor(_); legend.color(color); return chart; }; @@ -4829,33 +5978,18 @@ nv.models.lineWithFocusChart = function() { return chart; };
- chart.interpolate = function(_) { - if (!arguments.length) return lines.interpolate(); - lines.interpolate(_); - lines2.interpolate(_); - return chart; - }; - chart.noData = function(_) { if (!arguments.length) return noData; noData = _; return chart; };
- // Chart has multiple similar Axes, to prevent code duplication, probably need to link all axis functions manually like below - chart.xTickFormat = function(_) { - if (!arguments.length) return xAxis.tickFormat(); - xAxis.tickFormat(_); - x2Axis.tickFormat(_); + chart.brushExtent = function(_) { + if (!arguments.length) return brushExtent; + brushExtent = _; return chart; };
- chart.yTickFormat = function(_) { - if (!arguments.length) return yAxis.tickFormat(); - yAxis.tickFormat(_); - y2Axis.tickFormat(_); - return chart; - };
//============================================================
@@ -4881,6 +6015,9 @@ nv.models.multiBar = function() { , clipEdge = true , stacked = false , color = nv.utils.defaultColor() + , hideable = false + , barColor = null // adding the ability to set the color for each rather than the whole group + , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled , delay = 1200 , xDomain , yDomain @@ -4906,12 +6043,22 @@ nv.models.multiBar = function() { availableHeight = height - margin.top - margin.bottom, container = d3.select(this);
+ if(hideable && data.length) hideable = [{ + values: data[0].values.map(function(d) { + return { + x: d.x, + y: 0, + series: d.series, + size: 0.01 + };} + )}]; + if (stacked) data = d3.layout.stack() .offset('zero') .values(function(d){ return d.values }) .y(getY) - (data); + (!data.length && hideable ? hideable : data);
//add series index to each data point for reference @@ -4925,23 +6072,42 @@ nv.models.multiBar = function() {
//------------------------------------------------------------ + // HACK for negative value stacking + if (stacked) + data[0].values.map(function(d,i) { + var posBase = 0, negBase = 0; + data.map(function(d) { + var f = d.values[i] + f.size = Math.abs(f.y); + if (f.y<0) { + f.y1 = negBase; + negBase = negBase - f.size; + } else + { + f.y1 = f.size + posBase; + posBase = posBase + f.size; + } + }); + }); + + //------------------------------------------------------------ // Setup Scales
// remap and flatten the data for use in calculating the scales' domains var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate data.map(function(d) { return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), y0: d.y0 } + return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 } }) });
x .domain(d3.merge(seriesData).map(function(d) { return d.x })) .rangeBands([0, availableWidth], .1);
- y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y + (stacked ? d.y0 : 0) }).concat(forceY))) + //y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y + (stacked ? d.y1 : 0) }).concat(forceY))) + y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return stacked ? (d.y > 0 ? d.y1 : d.y1 + d.y ) : d.y }).concat(forceY))) .range([availableHeight, 0]);
- // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint = true; if (x.domain()[0] === x.domain()[1]) @@ -5013,7 +6179,7 @@ nv.models.multiBar = function() {
var bars = groups.selectAll('rect.nv-bar') - .data(function(d) { return d.values }); + .data(function(d) { return (hideable && !data.length) ? hideable.values : d.values });
bars.exit().remove();
@@ -5079,14 +6245,28 @@ nv.models.multiBar = function() { bars .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'}) .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; }) + + if (barColor) { + if (!disabled) disabled = data.map(function() { return true }); + bars + //.style('fill', barColor) + //.style('stroke', barColor) + //.style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); }) + //.style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); }) + .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }) + .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }); + } + + if (stacked) d3.transition(bars) .delay(function(d,i) { return i * delay / data[0].values.length }) .attr('y', function(d,i) { - return y(getY(d,i) + (stacked ? d.y0 : 0)); + + return y((stacked ? d.y1 : 0)); }) .attr('height', function(d,i) { - return Math.abs(y(d.y + (stacked ? d.y0 : 0)) - y((stacked ? d.y0 : 0))) + return Math.max(Math.abs(y(d.y + (stacked ? d.y0 : 0)) - y((stacked ? d.y0 : 0))),1); }) .each('end', function() { d3.transition(d3.select(this)) @@ -5106,11 +6286,13 @@ nv.models.multiBar = function() { d3.transition(d3.select(this)) .attr('y', function(d,i) { return getY(d,i) < 0 ? - y(0) : - y(getY(d,i)) - }) - .attr('height', function(d,i) { - return Math.abs(y(getY(d,i)) - y(0)) + y(0) : + y(0) - y(getY(d,i)) < 1 ? + y(0) - 1 : + y(getY(d,i)) || 0; + }) + .attr('height', function(d,i) { + return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0; }); })
@@ -5212,12 +6394,30 @@ nv.models.multiBar = function() { return chart; };
+ chart.barColor = function(_) { + if (!arguments.length) return barColor; + barColor = nv.utils.getColor(_); + return chart; + }; + + chart.disabled = function(_) { + if (!arguments.length) return disabled; + disabled = _; + return chart; + }; + chart.id = function(_) { if (!arguments.length) return id; id = _; return chart; };
+ chart.hideable = function(_) { + if (!arguments.length) return hideable; + hideable = _; + return chart; + }; + chart.delay = function(_) { if (!arguments.length) return delay; delay = _; @@ -5258,8 +6458,11 @@ nv.models.multiBarChart = function() { } , x //can be accessed via chart.xScale() , y //can be accessed via chart.yScale() + , state = { stacked: false } + , defaultState = null , noData = "No Data Available." - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') + , controlWidth = function() { return showControls ? 180 : 0 } ;
multibar @@ -5267,7 +6470,7 @@ nv.models.multiBarChart = function() { ; xAxis .orient('bottom') - .tickPadding(5) + .tickPadding(7) .highlightZero(false) .showMaxMin(false) .tickFormat(function(d) { return d }) @@ -5310,7 +6513,19 @@ nv.models.multiBarChart = function() { chart.update = function() { selection.transition().call(chart) }; chart.container = this;
- + //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + } //------------------------------------------------------------ // Display noData message if there's nothing to show.
@@ -5364,7 +6579,12 @@ nv.models.multiBarChart = function() { // Legend
if (showLegend) { - legend.width(availableWidth / 2); + legend.width(availableWidth - controlWidth()); + + if (multibar.barColor()) + data.forEach(function(series,i) { + series.color = d3.rgb('#ccc').darker(i * 1.5).toString(); + })
g.select('.nv-legendWrap') .datum(data) @@ -5377,7 +6597,7 @@ nv.models.multiBarChart = function() { }
g.select('.nv-legendWrap') - .attr('transform', 'translate(' + (availableWidth / 2) + ',' + (-margin.top) +')'); + .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')'); }
//------------------------------------------------------------ @@ -5392,7 +6612,7 @@ nv.models.multiBarChart = function() { { key: 'Stacked', disabled: !multibar.stacked() } ];
- controls.width(180).color(['#444', '#444', '#444']); + controls.width(controlWidth()).color(['#444', '#444', '#444']); g.select('.nv-controlsWrap') .datum(controlsData) .attr('transform', 'translate(0,' + (-margin.top) +')') @@ -5409,6 +6629,7 @@ nv.models.multiBarChart = function() { // Main Chart Component(s)
multibar + .disabled(data.map(function(series) { return series.disabled })) .width(availableWidth) .height(availableHeight) .color(data.map(function(d,i) { @@ -5453,9 +6674,12 @@ nv.models.multiBarChart = function() {
if(rotateLabels) xTicks - .selectAll('text') - .attr('transform', function(d,i,j) { return 'rotate('+rotateLabels+' 0,0)' }) - .attr('text-transform', rotateLabels > 0 ? 'start' : 'end'); + .selectAll('text') + .attr('transform', 'rotate(' + rotateLabels + ' 0,0)') + .attr('text-anchor', rotateLabels > 0 ? 'start' : 'end'); + + g.select('.nv-x.nv-axis').selectAll('g.nv-axisMaxMin text') + .style('opacity', 1);
yAxis .scale(y) @@ -5484,6 +6708,9 @@ nv.models.multiBarChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -5504,6 +6731,9 @@ nv.models.multiBarChart = function() { break; }
+ state.stacked = multibar.stacked(); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -5511,6 +6741,25 @@ nv.models.multiBarChart = function() { if (tooltips) showTooltip(e, that.parentNode) });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + if (typeof e.stacked !== 'undefined') { + multibar.stacked(e.stacked); + state.stacked = e.stacked; + } + + selection.call(chart); + }); + //============================================================
@@ -5550,7 +6799,7 @@ nv.models.multiBarChart = function() { chart.xAxis = xAxis; chart.yAxis = yAxis;
- d3.rebind(chart, multibar, 'x', 'y', 'xDomain', 'yDomain', 'forceX', 'forceY', 'clipEdge', 'id', 'stacked', 'delay'); + d3.rebind(chart, multibar, 'x', 'y', 'xDomain', 'yDomain', 'forceX', 'forceY', 'clipEdge', 'id', 'stacked', 'delay', 'barColor');
chart.margin = function(_) { if (!arguments.length) return margin; @@ -5622,6 +6871,18 @@ nv.models.multiBarChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -5650,6 +6911,8 @@ nv.models.multiBarHorizontal = function() { , getY = function(d) { return d.y } , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove , color = nv.utils.defaultColor() + , barColor = null // adding the ability to set the color for each rather than the whole group + , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled , stacked = false , showValues = false , valuePadding = 60 @@ -5698,6 +6961,28 @@ nv.models.multiBarHorizontal = function() { });
+ + //------------------------------------------------------------ + // HACK for negative value stacking + if (stacked) + data[0].values.map(function(d,i) { + var posBase = 0, negBase = 0; + data.map(function(d) { + var f = d.values[i] + f.size = Math.abs(f.y); + if (f.y<0) { + f.y1 = negBase - f.size; + negBase = negBase - f.size; + } else + { + f.y1 = posBase; + posBase = posBase + f.size; + } + }); + }); + + + //------------------------------------------------------------ // Setup Scales
@@ -5705,14 +6990,15 @@ nv.models.multiBarHorizontal = function() { var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate data.map(function(d) { return d.values.map(function(d,i) { - return { x: getX(d,i), y: getY(d,i), y0: d.y0 } + return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 } }) });
x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x })) .rangeBands([0, availableHeight], .1);
- y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y + (stacked ? d.y0 : 0) }).concat(forceY))) + //y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y + (stacked ? d.y0 : 0) }).concat(forceY))) + y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return stacked ? (d.y > 0 ? d.y1 + d.y : d.y1 ) : d.y }).concat(forceY)))
if (showValues && !stacked) y.range([(y.domain()[0] < 0 ? valuePadding : 0), availableWidth - (y.domain()[1] > 0 ? valuePadding : 0) ]); @@ -5825,32 +7111,45 @@ nv.models.multiBarHorizontal = function() { d3.event.stopPropagation(); });
+ + barsEnter.append('text'); + if (showValues && !stacked) { - barsEnter.append('text') - .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' }) bars.select('text') - .attr('y', x.rangeBand() / 2) - .attr('dy', '-.32em') + .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' }) + .attr('y', x.rangeBand() / (data.length * 2)) + .attr('dy', '.32em') .text(function(d,i) { return valueFormat(getY(d,i)) }) d3.transition(bars) //.delay(function(d,i) { return i * delay / data[0].values.length }) .select('text') .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 : y(getY(d,i)) - y(0) + 4 }) } else { - bars.selectAll('text').remove(); + //bars.selectAll('text').remove(); + bars.selectAll('text').text(''); }
bars .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'}) - //.attr('transform', function(d,i,j) { - //return 'translate(' + y0(stacked ? d.y0 : 0) + ',' + x(getX(d,i)) + ')' - //}) + + if (barColor) { + if (!disabled) disabled = data.map(function() { return true }); + bars + //.style('fill', barColor) + //.style('stroke', barColor) + //.style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); }) + //.style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(j).toString(); }) + .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }) + .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker( disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j] ).toString(); }); + } + if (stacked) d3.transition(bars) //.delay(function(d,i) { return i * delay / data[0].values.length }) .attr('transform', function(d,i) { //return 'translate(' + y(d.y0) + ',0)' - return 'translate(' + y(d.y0) + ',' + x(getX(d,i)) + ')' + //return 'translate(' + y(d.y0) + ',' + x(getX(d,i)) + ')' + return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) + ')' }) .select('rect') .attr('width', function(d,i) { @@ -5873,7 +7172,7 @@ nv.models.multiBarHorizontal = function() { .select('rect') .attr('height', x.rangeBand() / data.length ) .attr('width', function(d,i) { - return Math.abs(y(getY(d,i)) - y(0)) + return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) });
@@ -5968,6 +7267,18 @@ nv.models.multiBarHorizontal = function() { return chart; };
+ chart.barColor = function(_) { + if (!arguments.length) return barColor; + barColor = nv.utils.getColor(_); + return chart; + }; + + chart.disabled = function(_) { + if (!arguments.length) return disabled; + disabled = _; + return chart; + }; + chart.id = function(_) { if (!arguments.length) return id; id = _; @@ -6031,8 +7342,11 @@ nv.models.multiBarHorizontalChart = function() { } , x //can be accessed via chart.xScale() , y //can be accessed via chart.yScale() + , state = { stacked: stacked } + , defaultState = null , noData = 'No Data Available.' - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') + , controlWidth = function() { return showControls ? 180 : 0 } ;
multibar @@ -6083,6 +7397,19 @@ nv.models.multiBarHorizontalChart = function() { chart.update = function() { selection.transition().call(chart) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display No Data message if there's nothing to show. @@ -6137,7 +7464,12 @@ nv.models.multiBarHorizontalChart = function() { // Legend
if (showLegend) { - legend.width(availableWidth / 2); + legend.width(availableWidth - controlWidth()); + + if (multibar.barColor()) + data.forEach(function(series,i) { + series.color = d3.rgb('#ccc').darker(i * 1.5).toString(); + })
g.select('.nv-legendWrap') .datum(data) @@ -6150,7 +7482,7 @@ nv.models.multiBarHorizontalChart = function() { }
g.select('.nv-legendWrap') - .attr('transform', 'translate(' + (availableWidth / 2) + ',' + (-margin.top) +')'); + .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')'); }
//------------------------------------------------------------ @@ -6165,7 +7497,7 @@ nv.models.multiBarHorizontalChart = function() { { key: 'Stacked', disabled: !multibar.stacked() } ];
- controls.width(180).color(['#444', '#444', '#444']); + controls.width(controlWidth()).color(['#444', '#444', '#444']); g.select('.nv-controlsWrap') .datum(controlsData) .attr('transform', 'translate(0,' + (-margin.top) +')') @@ -6182,6 +7514,7 @@ nv.models.multiBarHorizontalChart = function() { // Main Chart Component(s)
multibar + .disabled(data.map(function(series) { return series.disabled })) .width(availableWidth) .height(availableHeight) .color(data.map(function(d,i) { @@ -6244,6 +7577,9 @@ nv.models.multiBarHorizontalChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -6264,6 +7600,9 @@ nv.models.multiBarHorizontalChart = function() { break; }
+ state.stacked = multibar.stacked(); + dispatch.stateChange(state); + selection.transition().call(chart); });
@@ -6271,6 +7610,24 @@ nv.models.multiBarHorizontalChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + if (typeof e.stacked !== 'undefined') { + multibar.stacked(e.stacked); + state.stacked = e.stacked; + } + + selection.call(chart); + }); //============================================================
@@ -6310,7 +7667,7 @@ nv.models.multiBarHorizontalChart = function() { chart.xAxis = xAxis; chart.yAxis = yAxis;
- d3.rebind(chart, multibar, 'x', 'y', 'xDomain', 'yDomain', 'forceX', 'forceY', 'clipEdge', 'id', 'delay', 'showValues', 'valueFormat', 'stacked'); + d3.rebind(chart, multibar, 'x', 'y', 'xDomain', 'yDomain', 'forceX', 'forceY', 'clipEdge', 'id', 'delay', 'showValues', 'valueFormat', 'stacked', 'barColor');
chart.margin = function(_) { if (!arguments.length) return margin; @@ -6370,6 +7727,18 @@ nv.models.multiBarHorizontalChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -6427,7 +7796,7 @@ nv.models.multiChart = function() { var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ), top = e.pos[1] + ( offsetElement.offsetTop || 0), x = xAxis.tickFormat()(lines1.x()(e.point, e.pointIndex)), - y = (e.series.bar ? yAxis1 : yAxis2).tickFormat()(lines1.y()(e.point, e.pointIndex)), + y = ((e.series.yAxis == 2) ? yAxis2 : yAxis1).tickFormat()(lines1.y()(e.point, e.pointIndex)), content = tooltip(e.series.key, x, y, e, chart);
nv.tooltip.show([left, top], content, undefined, undefined, offsetElement.offsetParent); @@ -6846,6 +8215,7 @@ nv.models.ohlcBar = function() { , getLow = function(d) { return d.low } , forceX = [] , forceY = [] + , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart , clipEdge = true , color = nv.utils.defaultColor() , xDomain @@ -6874,8 +8244,12 @@ nv.models.ohlcBar = function() { //------------------------------------------------------------ // Setup Scales
- x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )) - .range([0, availableWidth]); + x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) )); + + if (padData) + x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); + else + x.range([0, availableWidth]);
y .domain(yDomain || [ d3.min(data[0].values.map(getLow).concat(forceY)), @@ -7156,6 +8530,12 @@ nv.models.ohlcBar = function() { return chart; };
+ chart.padData = function(_) { + if (!arguments.length) return padData; + padData = _; + return chart; + }; + chart.clipEdge = function(_) { if (!arguments.length) return clipEdge; clipEdge = _; @@ -7179,7 +8559,6 @@ nv.models.ohlcBar = function() {
return chart; } - nv.models.pie = function() {
//============================================================ @@ -7192,13 +8571,19 @@ nv.models.pie = function() { , getValues = function(d) { return d.values } , getX = function(d) { return d.x } , getY = function(d) { return d.y } + , getDescription = function(d) { return d.description } , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one , color = nv.utils.defaultColor() , valueFormat = d3.format(',.2f') , showLabels = true + , pieLabelsOutside = true , donutLabelsOutside = false , labelThreshold = .02 //if slice percentage is under this, don't show label , donut = false + , labelSunbeamLayout = false + , startAngle = false + , endAngle = false + , donutRatio = 0.5 , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout') ;
@@ -7210,6 +8595,7 @@ nv.models.pie = function() { var availableWidth = width - margin.left - margin.right, availableHeight = height - margin.top - margin.bottom, radius = Math.min(availableWidth, availableHeight) / 2, + arcRadius = radius-(radius / 5), container = d3.select(this);
@@ -7242,10 +8628,11 @@ nv.models.pie = function() {
var arc = d3.svg.arc() - .outerRadius((radius-(radius / 5))); - - if (donut) arc.innerRadius(radius / 2); + .outerRadius(arcRadius);
+ if (startAngle) arc.startAngle(startAngle) + if (endAngle) arc.endAngle(endAngle); + if (donut) arc.innerRadius(radius * donutRatio);
// Setup the Pie chart and choose the data element var pie = d3.layout.pie() @@ -7317,10 +8704,11 @@ nv.models.pie = function() {
if (showLabels) { // This does the normal label - var labelsArc = arc; - if (donutLabelsOutside) { - labelsArc = d3.svg.arc().outerRadius(arc.outerRadius()) - } + var labelsArc = d3.svg.arc().innerRadius(0); + + if (pieLabelsOutside){ labelsArc = arc; } + + if (donutLabelsOutside) { labelsArc = d3.svg.arc().outerRadius(arc.outerRadius()); }
ae.append("g").classed("nv-label", true) .each(function(d, i) { @@ -7328,9 +8716,21 @@ nv.models.pie = function() {
group .attr('transform', function(d) { - d.outerRadius = radius + 10; // Set Outer Coordinate - d.innerRadius = radius + 15; // Set Inner Coordinate - return 'translate(' + labelsArc.centroid(d) + ')' + if (labelSunbeamLayout) { + d.outerRadius = arcRadius + 10; // Set Outer Coordinate + d.innerRadius = arcRadius + 15; // Set Inner Coordinate + var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI); + if ((d.startAngle+d.endAngle)/2 < Math.PI) { + rotateAngle -= 90; + } else { + rotateAngle += 90; + } + return 'translate(' + labelsArc.centroid(d) + ') rotate(' + rotateAngle + ')'; + } else { + d.outerRadius = radius + 10; // Set Outer Coordinate + d.innerRadius = radius + 15; // Set Inner Coordinate + return 'translate(' + labelsArc.centroid(d) + ')' + } });
group.append('rect') @@ -7340,7 +8740,7 @@ nv.models.pie = function() { .attr("ry", 3);
group.append('text') - .style('text-anchor', 'middle') //center the text on it's origin + .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned .style('fill', '#000')
@@ -7348,9 +8748,21 @@ nv.models.pie = function() {
slices.select(".nv-label").transition() .attr('transform', function(d) { - d.outerRadius = radius + 10; // Set Outer Coordinate - d.innerRadius = radius + 15; // Set Inner Coordinate - return 'translate(' + labelsArc.centroid(d) + ')'; + if (labelSunbeamLayout) { + d.outerRadius = arcRadius + 10; // Set Outer Coordinate + d.innerRadius = arcRadius + 15; // Set Inner Coordinate + var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI); + if ((d.startAngle+d.endAngle)/2 < Math.PI) { + rotateAngle -= 90; + } else { + rotateAngle += 90; + } + return 'translate(' + labelsArc.centroid(d) + ') rotate(' + rotateAngle + ')'; + } else { + d.outerRadius = radius + 10; // Set Outer Coordinate + d.innerRadius = radius + 15; // Set Inner Coordinate + return 'translate(' + labelsArc.centroid(d) + ')' + } });
slices.each(function(d, i) { @@ -7358,6 +8770,7 @@ nv.models.pie = function() {
slice .select(".nv-label text") + .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned .text(function(d, i) { var percent = (d.endAngle - d.startAngle) / (2 * Math.PI); return (d.value && percent > labelThreshold) ? getX(d.data) : ''; @@ -7447,24 +8860,60 @@ nv.models.pie = function() { getY = d3.functor(_); return chart; }; + + chart.description = function(_) { + if (!arguments.length) return getDescription; + getDescription = _; + return chart; + };
chart.showLabels = function(_) { if (!arguments.length) return showLabels; showLabels = _; return chart; }; + + chart.labelSunbeamLayout = function(_) { + if (!arguments.length) return labelSunbeamLayout; + labelSunbeamLayout = _; + return chart; + };
chart.donutLabelsOutside = function(_) { if (!arguments.length) return donutLabelsOutside; donutLabelsOutside = _; return chart; }; + + chart.pieLabelsOutside = function(_) { + if (!arguments.length) return pieLabelsOutside; + pieLabelsOutside = _; + return chart; + };
chart.donut = function(_) { if (!arguments.length) return donut; donut = _; return chart; }; + + chart.donutRatio = function(_) { + if (!arguments.length) return donutRatio; + donutRatio = _; + return chart; + }; + + chart.startAngle = function(_) { + if (!arguments.length) return startAngle; + startAngle = _; + return chart; + }; + + chart.endAngle = function(_) { + if (!arguments.length) return endAngle; + endAngle = _; + return chart; + };
chart.id = function(_) { if (!arguments.length) return id; @@ -7489,13 +8938,11 @@ nv.models.pie = function() { labelThreshold = _; return chart; }; - //============================================================
return chart; } - nv.models.pieChart = function() {
//============================================================ @@ -7516,8 +8963,10 @@ nv.models.pieChart = function() { return '<h3>' + key + '</h3>' + '<p>' + y + '</p>' } + , state = {} + , defaultState = null , noData = "No Data Available." - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') ;
//============================================================ @@ -7528,10 +8977,11 @@ nv.models.pieChart = function() { //------------------------------------------------------------
var showTooltip = function(e, offsetElement) { + var tooltipLabel = pie.description()(e.point) || pie.x()(e.point) var left = e.pos[0] + ( (offsetElement && offsetElement.offsetLeft) || 0 ), top = e.pos[1] + ( (offsetElement && offsetElement.offsetTop) || 0), y = pie.valueFormat()(pie.y()(e.point)), - content = tooltip(pie.x()(e.point), y, e, chart); + content = tooltip(tooltipLabel, y, e, chart);
nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's', null, offsetElement); }; @@ -7544,7 +8994,7 @@ nv.models.pieChart = function() { var container = d3.select(this), that = this;
- var availableWidth = (width || parseInt(container.style('width')) || 960) + var availableWidth = (width || parseInt(container.style('width')) || 960) - margin.left - margin.right, availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom; @@ -7552,11 +9002,24 @@ nv.models.pieChart = function() { chart.update = function() { chart(selection); }; chart.container = this;
+ //set state.disabled + state.disabled = data[0].map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display No Data message if there's nothing to show.
- if (!data || !data.length) { + if (!data[0] || !data[0].length) { var noDataText = container.selectAll('.nv-noData').data([noData]);
noDataText.enter().append('text') @@ -7649,6 +9112,9 @@ nv.models.pieChart = function() { }); }
+ state.disabled = data[0].map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + selection.transition().call(chart) });
@@ -7656,6 +9122,20 @@ nv.models.pieChart = function() { dispatch.tooltipHide(e); });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data[0].forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + selection.call(chart); + }); + //============================================================
@@ -7689,10 +9169,11 @@ nv.models.pieChart = function() { //------------------------------------------------------------
// expose chart's sub-components + chart.legend = legend; chart.dispatch = dispatch; chart.pie = pie;
- d3.rebind(chart, pie, 'valueFormat', 'values', 'x', 'y', 'id', 'showLabels', 'donutLabelsOutside', 'donut', 'labelThreshold'); + d3.rebind(chart, pie, 'valueFormat', 'values', 'x', 'y', 'description', 'id', 'showLabels', 'donutLabelsOutside', 'pieLabelsOutside', 'donut', 'donutRatio', 'labelThreshold');
chart.margin = function(_) { if (!arguments.length) return margin; @@ -7741,6 +9222,18 @@ nv.models.pieChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -7759,33 +9252,36 @@ nv.models.scatter = function() { // Public Variables with Default Settings //------------------------------------------------------------
- var margin = {top: 0, right: 0, bottom: 0, left: 0} - , width = 960 - , height = 500 - , color = nv.utils.defaultColor() // chooses color - , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't selet one - , x = d3.scale.linear() - , y = d3.scale.linear() - , z = d3.scale.linear() //linear because d3.svg.shape.size is treated as area - , getX = function(d) { return d.x } // accessor to get the x value - , getY = function(d) { return d.y } // accessor to get the y value - , getSize = function(d) { return d.size } // accessor to get the point size - , getShape = function(d) { return d.shape || 'circle' } // accessor to get point shape - , forceX = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) - , forceY = [] // List of numbers to Force into the Y scale - , forceSize = [] // List of numbers to Force into the Size scale - , interactive = true // If true, plots a voronoi overlay for advanced point interection - , pointActive = function(d) { return !d.notActive } // any points that return false will be filtered out - , clipEdge = false // if true, masks points within x and y scale - , clipVoronoi = true // if true, masks each point with a circle... can turn off to slightly increase performance - , clipRadius = function() { return 25 } // function to get the radius for voronoi point clips - , xDomain = null // Override x domain (skips the calculation from data) - , yDomain = null // Override y domain - , sizeDomain = null // Override point size domain - , sizeRange = null - , singlePoint = false - , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout') - , useVoronoi = true + var margin = {top: 0, right: 0, bottom: 0, left: 0} + , width = 960 + , height = 500 + , color = nv.utils.defaultColor() // chooses color + , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't select one + , x = d3.scale.linear() + , y = d3.scale.linear() + , z = d3.scale.linear() //linear because d3.svg.shape.size is treated as area + , getX = function(d) { return d.x } // accessor to get the x value + , getY = function(d) { return d.y } // accessor to get the y value + , getSize = function(d) { return d.size || 1} // accessor to get the point size + , getShape = function(d) { return d.shape || 'circle' } // accessor to get point shape + , onlyCircles = true // Set to false to use shapes + , forceX = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.) + , forceY = [] // List of numbers to Force into the Y scale + , forceSize = [] // List of numbers to Force into the Size scale + , interactive = true // If true, plots a voronoi overlay for advanced point intersection + , pointActive = function(d) { return !d.notActive } // any points that return false will be filtered out + , padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart + , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding + , clipEdge = false // if true, masks points within x and y scale + , clipVoronoi = true // if true, masks each point with a circle... can turn off to slightly increase performance + , clipRadius = function() { return 25 } // function to get the radius for voronoi point clips + , xDomain = null // Override x domain (skips the calculation from data) + , yDomain = null // Override y domain + , sizeDomain = null // Override point size domain + , sizeRange = null + , singlePoint = false + , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout') + , useVoronoi = true ;
//============================================================ @@ -7797,6 +9293,7 @@ nv.models.scatter = function() {
var x0, y0, z0 // used to store previous scales , timeoutID + , needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips ;
//============================================================ @@ -7831,7 +9328,12 @@ nv.models.scatter = function() { );
x .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x }).concat(forceX))) - .range([0, availableWidth]); + + if (padData && data[0]) + x.range([(availableWidth * padDataOuter + availableWidth) / (2 *data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 * data[0].values.length) ]); + //x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]); + else + x.range([0, availableWidth]);
y .domain(yDomain || d3.extent(seriesData.map(function(d) { return d.y }).concat(forceY))) .range([availableHeight, 0]); @@ -7907,45 +9409,109 @@ nv.models.scatter = function() { );
- if (clipVoronoi) { - defsEnter.append('clipPath').attr('id', 'nv-points-clip-' + id);
- var pointClips = wrap.select('#nv-points-clip-' + id).selectAll('circle') - .data(vertices); - pointClips.enter().append('circle') - .attr('r', clipRadius); - pointClips.exit().remove(); - pointClips - .attr('cx', function(d) { return d[0] }) - .attr('cy', function(d) { return d[1] }); + //inject series and point index for reference into voronoi + if (useVoronoi === true) { + + if (clipVoronoi) { + var pointClipsEnter = wrap.select('defs').selectAll('.nv-point-clips') + .data([id]) + .enter(); + + pointClipsEnter.append('clipPath') + .attr('class', 'nv-point-clips') + .attr('id', 'nv-points-clip-' + id); + + var pointClips = wrap.select('#nv-points-clip-' + id).selectAll('circle') + .data(vertices); + pointClips.enter().append('circle') + .attr('r', clipRadius); + pointClips.exit().remove(); + pointClips + .attr('cx', function(d) { return d[0] }) + .attr('cy', function(d) { return d[1] }); + + wrap.select('.nv-point-paths') + .attr('clip-path', 'url(#nv-points-clip-' + id + ')'); + }
- wrap.select('.nv-point-paths') - .attr('clip-path', 'url(#nv-points-clip-' + id + ')'); - }
+ // if(vertices.length < 3) { + // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work + vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]); + vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]); + vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]); + vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]); + // } + + var bounds = d3.geom.polygon([ + [-10,-10], + [-10,height + 10], + [width + 10,height + 10], + [width + 10,-10] + ]);
- //inject series and point index for reference into voronoi - if (useVoronoi === true) { var voronoi = d3.geom.voronoi(vertices).map(function(d, i) { return { - 'data': d, + 'data': bounds.clip(d), 'series': vertices[i][2], 'point': vertices[i][3] } });
+ var pointPaths = wrap.select('.nv-point-paths').selectAll('path') .data(voronoi); pointPaths.enter().append('path') .attr('class', function(d,i) { return 'nv-path-'+i; }); pointPaths.exit().remove(); pointPaths - .attr('d', function(d) { return 'M' + d.data.join(',') + 'Z'; }); + .attr('d', function(d) { return 'M' + d.data.join('L') + 'Z'; }); + + pointPaths + .on('click', function(d) { + if (needsUpdate) return 0; + var series = data[d.series], + point = series.values[d.point]; + + dispatch.elementClick({ + point: point, + series: series, + pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top], + seriesIndex: d.series, + pointIndex: d.point + }); + }) + .on('mouseover', function(d) { + if (needsUpdate) return 0; + var series = data[d.series], + point = series.values[d.point]; + + dispatch.elementMouseover({ + point: point, + series: series, + pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top], + seriesIndex: d.series, + pointIndex: d.point + }); + }) + .on('mouseout', function(d, i) { + if (needsUpdate) return 0; + var series = data[d.series], + point = series.values[d.point]; + + dispatch.elementMouseout({ + point: point, + series: series, + seriesIndex: d.series, + pointIndex: d.point + }); + });
- eventElements = pointPaths;
} else { + /* // bring data in form needed for click handlers var dataWithPoints = vertices.map(function(d, i) { return { @@ -7954,54 +9520,58 @@ nv.models.scatter = function() { 'point': vertices[i][3] } }); + */
// add event handlers to points instead voronoi paths - eventElements = wrap.select('.nv-groups').selectAll('.nv-group') - .selectAll('path.nv-point') - .data(dataWithPoints) - .style('pointer-events', 'auto'); // recativate events, disabled by css - } + wrap.select('.nv-groups').selectAll('.nv-group') + .selectAll('.nv-point') + //.data(dataWithPoints) + //.style('pointer-events', 'auto') // recativate events, disabled by css + .on('click', function(d,i) { + //nv.log('test', d, i); + if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point + var series = data[d.series], + point = series.values[i];
- eventElements - .on('click', function(d) { - var series = data[d.series], - point = series.values[d.point]; - - dispatch.elementClick({ - point: point, - series: series, - pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top], - seriesIndex: d.series, - pointIndex: d.point - }); - }) - .on('mouseover', function(d) { - var series = data[d.series], - point = series.values[d.point]; + dispatch.elementClick({ + point: point, + series: series, + pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], + seriesIndex: d.series, + pointIndex: i + }); + }) + .on('mouseover', function(d,i) { + if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point + var series = data[d.series], + point = series.values[i];
- dispatch.elementMouseover({ - point: point, - series: series, - pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top], - seriesIndex: d.series, - pointIndex: d.point - }); - }) - .on('mouseout', function(d, i) { - var series = data[d.series], - point = series.values[d.point]; + dispatch.elementMouseover({ + point: point, + series: series, + pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], + seriesIndex: d.series, + pointIndex: i + }); + }) + .on('mouseout', function(d,i) { + if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy point + var series = data[d.series], + point = series.values[i];
- dispatch.elementMouseout({ - point: point, - series: series, - seriesIndex: d.series, - pointIndex: d.point + dispatch.elementMouseout({ + point: point, + series: series, + seriesIndex: d.series, + pointIndex: i + }); }); - }); + }
+ needsUpdate = false; }
- + needsUpdate = true;
var groups = wrap.select('.nv-groups').selectAll('.nv-group') .data(function(d) { return d }, function(d) { return d.key }); @@ -8022,38 +9592,62 @@ nv.models.scatter = function() { .style('fill-opacity', .5);
- var points = groups.selectAll('path.nv-point') - .data(function(d) { return d.values }); - points.enter().append('path') - .attr('transform', function(d,i) { - return 'translate(' + x0(getX(d,i)) + ',' + y0(getY(d,i)) + ')' - }) - .attr('d', - d3.svg.symbol() - .type(getShape) - .size(function(d,i) { return z(getSize(d,i)) }) - ); - points.exit().remove(); - d3.transition(groups.exit().selectAll('path.nv-point')) - .attr('transform', function(d,i) { - return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')' - }) - .remove(); - points.attr('class', function(d,i) { return 'nv-point nv-point-' + i }); - d3.transition(points) - .attr('transform', function(d,i) { - return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')' - }) - .attr('d', - d3.svg.symbol() - .type(getShape) - .size(function(d,i) { return z(getSize(d,i)) }) - ); + if (onlyCircles) { + + var points = groups.selectAll('circle.nv-point') + .data(function(d) { return d.values }); + points.enter().append('circle') + .attr('cx', function(d,i) { return x0(getX(d,i)) }) + .attr('cy', function(d,i) { return y0(getY(d,i)) }) + .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) }); + points.exit().remove(); + d3.transition(groups.exit().selectAll('path.nv-point')) + .attr('cx', function(d,i) { return x(getX(d,i)) }) + .attr('cy', function(d,i) { return y(getY(d,i)) }) + .remove(); + points.attr('class', function(d,i) { return 'nv-point nv-point-' + i }); + d3.transition(points) + .attr('cx', function(d,i) { return x(getX(d,i)) }) + .attr('cy', function(d,i) { return y(getY(d,i)) }) + .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) }); + + } else { + + var points = groups.selectAll('path.nv-point') + .data(function(d) { return d.values }); + points.enter().append('path') + .attr('transform', function(d,i) { + return 'translate(' + x0(getX(d,i)) + ',' + y0(getY(d,i)) + ')' + }) + .attr('d', + d3.svg.symbol() + .type(getShape) + .size(function(d,i) { return z(getSize(d,i)) }) + ); + points.exit().remove(); + d3.transition(groups.exit().selectAll('path.nv-point')) + .attr('transform', function(d,i) { + return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')' + }) + .remove(); + points.attr('class', function(d,i) { return 'nv-point nv-point-' + i }); + d3.transition(points) + .attr('transform', function(d,i) { + //nv.log(d,i,getX(d,i), x(getX(d,i))); + return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')' + }) + .attr('d', + d3.svg.symbol() + .type(getShape) + .size(function(d,i) { return z(getSize(d,i)) }) + ); + }
// Delay updating the invisible interactive layer for smoother animation clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer - timeoutID = setTimeout(updateInteractiveLayer, 1000); + timeoutID = setTimeout(updateInteractiveLayer, 300); + //updateInteractiveLayer();
//store old scales for use in transitions on update x0 = x.copy(); @@ -8202,6 +9796,18 @@ nv.models.scatter = function() { return chart; };
+ chart.padData = function(_) { + if (!arguments.length) return padData; + padData = _; + return chart; + }; + + chart.padDataOuter = function(_) { + if (!arguments.length) return padDataOuter; + padDataOuter = _; + return chart; + }; + chart.clipEdge = function(_) { if (!arguments.length) return clipEdge; clipEdge = _; @@ -8241,6 +9847,12 @@ nv.models.scatter = function() { return chart; };
+ chart.onlyCircles = function(_) { + if (!arguments.length) return onlyCircles; + onlyCircles = _; + return chart; + }; + chart.id = function(_) { if (!arguments.length) return id; id = _; @@ -8274,7 +9886,7 @@ nv.models.scatterChart = function() { , distY = nv.models.distribution() ;
- var margin = {top: 30, right: 20, bottom: 50, left: 60} + var margin = {top: 30, right: 20, bottom: 50, left: 75} , width = null , height = null , color = nv.utils.defaultColor() @@ -8293,7 +9905,9 @@ nv.models.scatterChart = function() { , tooltipY = function(key, x, y) { return '<strong>' + y + '</strong>' } //, tooltip = function(key, x, y) { return '<h3>' + key + '</h3>' } , tooltip = null - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , state = {} + , defaultState = null + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') , noData = "No Data Available." ;
@@ -8365,6 +9979,19 @@ nv.models.scatterChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display noData message if there's nothing to show. @@ -8405,10 +10032,10 @@ nv.models.scatterChart = function() { var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]); var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatterChart nv-chart-' + scatter.id()); var gEnter = wrapEnter.append('g'); - var g = wrap.select('g') + var g = wrap.select('g');
// background for pointer events - gEnter.append('rect').attr('class', 'nvd3 nv-background') + gEnter.append('rect').attr('class', 'nvd3 nv-background');
gEnter.append('g').attr('class', 'nv-x nv-axis'); gEnter.append('g').attr('class', 'nv-y nv-axis'); @@ -8417,8 +10044,6 @@ nv.models.scatterChart = function() { gEnter.append('g').attr('class', 'nv-legendWrap'); gEnter.append('g').attr('class', 'nv-controlsWrap');
- wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - //------------------------------------------------------------
@@ -8459,6 +10084,9 @@ nv.models.scatterChart = function() { //------------------------------------------------------------
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + + //------------------------------------------------------------ // Main Chart Component(s)
@@ -8493,7 +10121,7 @@ nv.models.scatterChart = function() {
xAxis .scale(x) - .ticks( xAxis.ticks() ? xAxis.ticks() : availableWidth / 100 ) + .ticks( xAxis.ticks() && xAxis.ticks().length ? xAxis.ticks() : availableWidth / 100 ) .tickSize( -availableHeight , 0);
g.select('.nv-x.nv-axis') @@ -8503,7 +10131,7 @@ nv.models.scatterChart = function() {
yAxis .scale(y) - .ticks( yAxis.ticks() ? yAxis.ticks() : availableHeight / 36 ) + .ticks( yAxis.ticks() && yAxis.ticks().length ? yAxis.ticks() : availableHeight / 36 ) .tickSize( -availableWidth, 0);
g.select('.nv-y.nv-axis') @@ -8623,6 +10251,9 @@ nv.models.scatterChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + chart(selection); });
@@ -8652,6 +10283,20 @@ nv.models.scatterChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + selection.call(chart); + }); + //============================================================
@@ -8797,6 +10442,18 @@ nv.models.scatterChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -8824,7 +10481,7 @@ nv.models.scatterPlusLineChart = function() { , distY = nv.models.distribution() ;
- var margin = {top: 30, right: 20, bottom: 50, left: 60} + var margin = {top: 30, right: 20, bottom: 50, left: 75} , width = null , height = null , color = nv.utils.defaultColor() @@ -8839,9 +10496,12 @@ nv.models.scatterPlusLineChart = function() { , tooltips = true , tooltipX = function(key, x, y) { return '<strong>' + x + '</strong>' } , tooltipY = function(key, x, y) { return '<strong>' + y + '</strong>' } - //, tooltip = function(key, x, y) { return '<h3>' + key + '</h3>' } - , tooltip = null - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , tooltip = function(key, x, y, date) { return '<h3>' + key + '</h3>' + + '<p>' + date + '</p>' } + //, tooltip = null + , state = {} + , defaultState = null + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') , noData = "No Data Available." ;
@@ -8890,7 +10550,7 @@ nv.models.scatterPlusLineChart = function() { if( tooltipY != null ) nv.tooltip.show([leftY, topY], tooltipY(e.series.key, xVal, yVal, e, chart), 'e', 1, offsetElement, 'y-nvtooltip'); if( tooltip != null ) - nv.tooltip.show([left, top], tooltip(e.series.key, xVal, yVal, e, chart), e.value < 0 ? 'n' : 's', null, offsetElement); + nv.tooltip.show([left, top], tooltip(e.series.key, xVal, yVal, e.point.tooltip, e, chart), e.value < 0 ? 'n' : 's', null, offsetElement); };
var controlsData = [ @@ -8913,6 +10573,19 @@ nv.models.scatterPlusLineChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + }
//------------------------------------------------------------ // Display noData message if there's nothing to show. @@ -9187,6 +10860,9 @@ nv.models.scatterPlusLineChart = function() { }); }
+ state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + chart(selection); });
@@ -9216,6 +10892,20 @@ nv.models.scatterPlusLineChart = function() { if (tooltips) showTooltip(e, that.parentNode); });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + selection.call(chart); + }); + //============================================================
@@ -9349,6 +11039,18 @@ nv.models.scatterPlusLineChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -9429,15 +11131,32 @@ nv.models.sparkline = function() {
// TODO: Add CURRENT data point (Need Min, Mac, Current / Most recent) var points = wrap.selectAll('circle.nv-point') - .data(function(d) { return d.filter(function(p,i) { return y.domain().indexOf(getY(p,i)) != -1 || getX(p,i) == x.domain()[1] }) }); - points.enter().append('circle').attr('class', 'nv-point'); + .data(function(data) { + var yValues = data.map(function(d, i) { return getY(d,i); }); + function pointIndex(index) { + if (index != -1) { + var result = data[index]; + result.pointIndex = index; + return result; + } else { + return null; + } + } + var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])), + minPoint = pointIndex(yValues.indexOf(y.domain()[0])), + currentPoint = pointIndex(yValues.length - 1); + return [minPoint, maxPoint, currentPoint].filter(function (d) {return d != null;}); + }); + points.enter().append('circle'); points.exit().remove(); points - .attr('cx', function(d,i) { return x(getX(d,i)) }) - .attr('cy', function(d,i) { return y(getY(d,i)) }) + .attr('cx', function(d,i) { return x(getX(d,d.pointIndex)) }) + .attr('cy', function(d,i) { return y(getY(d,d.pointIndex)) }) .attr('r', 2) - .style('stroke', function(d,i) { return d.x == x.domain()[1] ? '#444' : d.y == y.domain()[0] ? '#d62728' : '#2ca02c' }) - .style('fill', function(d,i) { return d.x == x.domain()[1] ? '#444' : d.y == y.domain()[0] ? '#d62728' : '#2ca02c' }); + .attr('class', function(d,i) { + return getX(d, d.pointIndex) == x.domain()[1] ? 'nv-point nv-currentValue' : + getY(d, d.pointIndex) == y.domain()[0] ? 'nv-point nv-minValue' : 'nv-point nv-maxValue' + }); });
return chart; @@ -9531,16 +11250,18 @@ nv.models.sparklinePlus = function() {
var sparkline = nv.models.sparkline();
- var margin = {top: 15, right: 40, bottom: 3, left: 40} + var margin = {top: 15, right: 100, bottom: 10, left: 50} , width = null , height = null , x , y - , color = nv.utils.defaultColor() - , index + , index = [] , paused = false , xTickFormat = d3.format(',r') , yTickFormat = d3.format(',.2f') + , showValue = true + , alignValue = true + , rightAlignValue = false , noData = "No Data Available." ;
@@ -9556,6 +11277,7 @@ nv.models.sparklinePlus = function() { availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;
+ var currentValue = sparkline.y()(data[data.length-1], data.length-1);
chart.update = function() { chart(selection) }; chart.container = this; @@ -9604,6 +11326,7 @@ nv.models.sparklinePlus = function() { var g = wrap.select('g');
gEnter.append('g').attr('class', 'nv-sparklineWrap'); + gEnter.append('g').attr('class', 'nv-valueWrap'); gEnter.append('g').attr('class', 'nv-hoverArea');
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); @@ -9621,81 +11344,99 @@ nv.models.sparklinePlus = function() { .height(availableHeight);
sparklineWrap - .style('stroke', function(d, i){ return d.color || color(d, i) }) .call(sparkline);
//------------------------------------------------------------
+ var valueWrap = g.select('.nv-valueWrap'); + + var value = valueWrap.selectAll('.nv-currentValue') + .data([currentValue]); + + value.enter().append('text').attr('class', 'nv-currentValue') + .attr('dx', rightAlignValue ? -8 : 8) + .attr('dy', '.9em') + .style('text-anchor', rightAlignValue ? 'end' : 'start'); + + value + .attr('x', availableWidth + (rightAlignValue ? margin.right : 0)) + .attr('y', alignValue ? function(d) { return y(d) } : 0) + .style('fill', sparkline.color()(data[data.length-1], data.length-1)) + .text(yTickFormat(currentValue)); + +
gEnter.select('.nv-hoverArea').append('rect') .on('mousemove', sparklineHover) .on('click', function() { paused = !paused }) - .on('mouseout', function() { index = null; updateValueLine(); }); + .on('mouseout', function() { index = []; updateValueLine(); }); + //.on('mouseout', function() { index = null; updateValueLine(); });
g.select('.nv-hoverArea rect') .attr('transform', function(d) { return 'translate(' + -margin.left + ',' + -margin.top + ')' }) .attr('width', availableWidth + margin.left + margin.right) .attr('height', availableHeight + margin.top);
- // if index is not set, default to last point - //index = typeof index == 'undefined' ? data.length - 1 : index; - // if index is not set, default to null - index = typeof index == 'undefined' ? null : index;
- var hoverValue = g.selectAll('.nv-hoverValue').data([index]);
- var hoverG = hoverValue.enter().append('g').attr('class', 'nv-hoverValue'); + function updateValueLine() { //index is currently global (within the chart), may or may not keep it that way + if (paused) return;
- var hoverLine = hoverG.append('line') - .attr('x1', 0) - .attr('y1', -margin.top) - .attr('x2', 0) - .attr('y2', availableHeight); + var hoverValue = g.selectAll('.nv-hoverValue').data(index)
- var hoverX = hoverG.append('text').attr('class', 'nv-xValue') - .attr('x', -6) - .attr('y', -margin.top) - .attr('text-anchor', 'end') - .attr('dy', '.9em'); + var hoverEnter = hoverValue.enter() + .append('g').attr('class', 'nv-hoverValue') + .style('stroke-opacity', 0) + .style('fill-opacity', 0);
- var hoverY = hoverG.append('text').attr('class', 'nv-yValue') - .attr('x', 6) - .attr('y', -margin.top) - .attr('text-anchor', 'start') - .attr('dy', '.9em'); + hoverValue.exit() + .transition().duration(250) + .style('stroke-opacity', 0) + .style('fill-opacity', 0) + .remove();
- updateValueLine(); + hoverValue + .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' }) + .transition().duration(250) + .style('stroke-opacity', 1) + .style('fill-opacity', 1);
+ if (!index.length) return;
- function updateValueLine() { //index is currently global (within the chart), may or may not keep it that way - if (paused) return; + hoverEnter.append('line') + .attr('x1', 0) + .attr('y1', -margin.top) + .attr('x2', 0) + .attr('y2', availableHeight);
- hoverValue.data([index])
- //d3.transition(hoverValue) - hoverValue - .transition().duration(250) - .style('stroke-opacity', function(d) { return d === null ? 0 : 1 }) - .style('fill-opacity', function(d) { return d === null ? 0 : 1 }); + hoverEnter.append('text').attr('class', 'nv-xValue') + .attr('x', -6) + .attr('y', -margin.top) + .attr('text-anchor', 'end') + .attr('dy', '.9em')
- if (index == null) return;
- hoverValue - .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' }) + g.select('.nv-hoverValue .nv-xValue') + .text(xTickFormat(sparkline.x()(data[index[0]], index[0]))); + + hoverEnter.append('text').attr('class', 'nv-yValue') + .attr('x', 6) + .attr('y', -margin.top) + .attr('text-anchor', 'start') + .attr('dy', '.9em')
- hoverValue.select('.nv-xValue') - .text(xTickFormat(sparkline.x()(data[index], index))); + g.select('.nv-hoverValue .nv-yValue') + .text(yTickFormat(sparkline.y()(data[index[0]], index[0])));
- hoverValue.select('.nv-yValue') - .text(yTickFormat(sparkline.y()(data[index], index))); }
function sparklineHover() { if (paused) return;
- var pos = d3.event.offsetX - margin.left; + var pos = d3.mouse(this)[0] - margin.left;
function getClosestIndex(data, x) { var distance = Math.abs(sparkline.x()(data[0], 0) - x); @@ -9709,7 +11450,7 @@ nv.models.sparklinePlus = function() { return closestIndex; }
- index = getClosestIndex(data, Math.round(x.invert(pos))); + index = [getClosestIndex(data, Math.round(x.invert(pos)))];
updateValueLine(); } @@ -9727,7 +11468,7 @@ nv.models.sparklinePlus = function() { // expose chart's sub-components chart.sparkline = sparkline;
- d3.rebind(chart, sparkline, 'x', 'y', 'xScale', 'yScale'); + d3.rebind(chart, sparkline, 'x', 'y', 'xScale', 'yScale', 'color');
chart.margin = function(_) { if (!arguments.length) return margin; @@ -9762,6 +11503,24 @@ nv.models.sparklinePlus = function() { return chart; };
+ chart.showValue = function(_) { + if (!arguments.length) return showValue; + showValue = _; + return chart; + }; + + chart.alignValue = function(_) { + if (!arguments.length) return alignValue; + alignValue = _; + return chart; + }; + + chart.rightAlignValue = function(_) { + if (!arguments.length) return rightAlignValue; + rightAlignValue = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -9800,7 +11559,7 @@ nv.models.stackedArea = function() {
scatter .size(2.2) // default size - .sizeDomain([2.2]) // all the same size by default + .sizeDomain([2.2,2.2]) // all the same size by default ;
/************************************ @@ -9891,7 +11650,8 @@ nv.models.stackedArea = function() { var scatterWrap = g.select('.nv-scatterWrap') .datum(data.filter(function(d) { return !d.disabled }))
- d3.transition(scatterWrap).call(scatter); + //d3.transition(scatterWrap).call(scatter); + scatterWrap.call(scatter);
@@ -9953,13 +11713,15 @@ nv.models.stackedArea = function() { seriesIndex: i }); }) - d3.transition(path.exit()) + //d3.transition(path.exit()) + path.exit() .attr('d', function(d,i) { return zeroArea(d.values,i) }) .remove(); path .style('fill', function(d,i){ return d.color || color(d, i) }) .style('stroke', function(d,i){ return d.color || color(d, i) }); - d3.transition(path) + //d3.transition(path) + path .attr('d', function(d,i) { return area(d.values,i) })
@@ -10134,13 +11896,16 @@ nv.models.stackedAreaChart = function() { , x //can be accessed via chart.xScale() , y //can be accessed via chart.yScale() , yAxisTickFormat = d3.format(',.2f') + , state = { style: stacked.style() } + , defaultState = null , noData = 'No Data Available.' - , dispatch = d3.dispatch('tooltipShow', 'tooltipHide') + , dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState') + , controlWidth = 250 ;
xAxis .orient('bottom') - .tickPadding(5) + .tickPadding(7) ; yAxis .orient('left') @@ -10185,6 +11950,20 @@ nv.models.stackedAreaChart = function() { chart.update = function() { chart(selection) }; chart.container = this;
+ //set state.disabled + state.disabled = data.map(function(d) { return !!d.disabled }); + + if (!defaultState) { + var key; + defaultState = {}; + for (key in state) { + if (state[key] instanceof Array) + defaultState[key] = state[key].slice(0); + else + defaultState[key] = state[key]; + } + } + //------------------------------------------------------------ // Display No Data message if there's nothing to show.
@@ -10239,7 +12018,7 @@ nv.models.stackedAreaChart = function() {
if (showLegend) { legend - .width( availableWidth * 2 / 3 ); + .width( availableWidth - controlWidth );
g.select('.nv-legendWrap') .datum(data) @@ -10252,7 +12031,7 @@ nv.models.stackedAreaChart = function() { }
g.select('.nv-legendWrap') - .attr('transform', 'translate(' + ( availableWidth * 1 / 3 ) + ',' + (-margin.top) +')'); + .attr('transform', 'translate(' + controlWidth + ',' + (-margin.top) +')'); }
//------------------------------------------------------------ @@ -10269,7 +12048,7 @@ nv.models.stackedAreaChart = function() { ];
controls - .width( Math.min(280, availableWidth * 1 / 3) ) + .width( controlWidth ) .color(['#444', '#444', '#444']);
g.select('.nv-controlsWrap') @@ -10303,7 +12082,8 @@ nv.models.stackedAreaChart = function() {
var stackedWrap = g.select('.nv-stackedWrap') .datum(data); - d3.transition(stackedWrap).call(stacked); + //d3.transition(stackedWrap).call(stacked); + stackedWrap.call(stacked);
//------------------------------------------------------------
@@ -10318,7 +12098,9 @@ nv.models.stackedAreaChart = function() {
g.select('.nv-x.nv-axis') .attr('transform', 'translate(0,' + availableHeight + ')'); - d3.transition(g.select('.nv-x.nv-axis')) + //d3.transition(g.select('.nv-x.nv-axis')) + g.select('.nv-x.nv-axis') + .transition().duration(0) .call(xAxis);
yAxis @@ -10327,7 +12109,9 @@ nv.models.stackedAreaChart = function() { .tickSize(-availableWidth, 0) .setTickFormat(stacked.offset() == 'expand' ? d3.format('%') : yAxisTickFormat);
- d3.transition(g.select('.nv-y.nv-axis')) + //d3.transition(g.select('.nv-y.nv-axis')) + g.select('.nv-y.nv-axis') + .transition().duration(0) .call(yAxis);
//------------------------------------------------------------ @@ -10349,7 +12133,11 @@ nv.models.stackedAreaChart = function() { return d });
- selection.transition().call(chart); + state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + + //selection.transition().call(chart); + chart(selection); });
legend.dispatch.on('legendClick', function(d,i) { @@ -10362,7 +12150,11 @@ nv.models.stackedAreaChart = function() { }); }
- selection.transition().call(chart); + state.disabled = data.map(function(d) { return !!d.disabled }); + dispatch.stateChange(state); + + //selection.transition().call(chart); + chart(selection); });
controls.dispatch.on('legendClick', function(d,i) { @@ -10386,13 +12178,35 @@ nv.models.stackedAreaChart = function() { break; }
- selection.transition().call(chart); + state.style = stacked.style(); + dispatch.stateChange(state); + + //selection.transition().call(chart); + chart(selection); });
dispatch.on('tooltipShow', function(e) { if (tooltips) showTooltip(e, that.parentNode); });
+ // Update chart from a state object passed to event handler + dispatch.on('changeState', function(e) { + + if (typeof e.disabled !== 'undefined') { + data.forEach(function(series,i) { + series.disabled = e.disabled[i]; + }); + + state.disabled = e.disabled; + } + + if (typeof e.style !== 'undefined') { + stacked.style(e.style); + } + + selection.call(chart); + }); + });
@@ -10502,6 +12316,18 @@ nv.models.stackedAreaChart = function() { return chart; };
+ chart.state = function(_) { + if (!arguments.length) return state; + state = _; + return chart; + }; + + chart.defaultState = function(_) { + if (!arguments.length) return defaultState; + defaultState = _; + return chart; + }; + chart.noData = function(_) { if (!arguments.length) return noData; noData = _; @@ -10509,6 +12335,7 @@ nv.models.stackedAreaChart = function() { };
yAxis.setTickFormat = yAxis.tickFormat; + yAxis.tickFormat = function(_) { if (!arguments.length) return yAxisTickFormat; yAxisTickFormat = _;
commit d81ef0a6ec22ddc6ce32eeb2a47754a6f9abb01b Author: Mike Thompson mithomps@redhat.com Date: Fri May 3 13:42:29 2013 -0700
[BZ 958938] - Dashboard graphs need refresh when switching View/Edit portlet modes.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java index 779c795..9c310ca 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/DashboardView.java @@ -784,6 +784,7 @@ public class DashboardView extends EnhancedVLayout { } this.editForm.markForRedraw(); this.portalLayout.show(); + redraw(); this.portalLayout.markForRedraw(); }
commit 8737595774416a54383483fdd1678a436226af05 Author: Thomas Segismont tsegismo@redhat.com Date: Fri May 3 16:38:56 2013 +0200
Bug 911321 - [EAP 6.1] Reload operation fails in standalone mode
EAP can close the management http connection when receiving a reload operation request. In this case, we will set a specific error message in ASConnection which BaseServerComponent code will be able to detect.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java index 729201f..662d6ef 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java @@ -33,6 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; +import org.apache.http.NoHttpResponseException; import org.apache.http.StatusLine; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; @@ -82,6 +83,8 @@ public class ASConnection { @Deprecated public static final String MANAGEMENT = MANAGEMENT_URI;
+ static final String FAILURE_NO_RESPONSE = "The server closed the connection before sending the response"; + private static final Log LOG = LogFactory.getLog(ASConnection.class);
private static final int MAX_POOLED_CONNECTIONS = 10; @@ -367,6 +370,16 @@ public class ASConnection {
return operationResult;
+ } catch (NoHttpResponseException e) { + // For some operations like reload or shutdown, the server closes the connection before sending the + // response. We use a specific description here so that callers can write code to decide what to do + // in this situation. + Result failure = new Result(); + failure.setFailureDescription(FAILURE_NO_RESPONSE); + failure.setOutcome("failure"); + failure.setRhqThrowable(e); + JsonNode ret = mapper.valueToTree(failure); + return ret; } catch (IOException e) { Result failure = new Result(); failure.setFailureDescription(e.getMessage()); 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 6d889c5..b80a39a 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 @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2012 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -13,13 +13,12 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.modules.plugins.jbossas7;
import java.io.File; -import java.net.ConnectException; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; @@ -54,6 +53,7 @@ import org.rhq.core.system.ProcessExecutionResults; import org.rhq.core.system.ProcessInfo; import org.rhq.core.system.SystemInfo; import org.rhq.core.util.PropertiesFileUpdate; +import org.rhq.core.util.StringUtil; import org.rhq.modules.plugins.jbossas7.helper.HostConfiguration; import org.rhq.modules.plugins.jbossas7.helper.HostPort; import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration; @@ -492,26 +492,23 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend return operationResult; }
- if (name.equals("shutdown") || name.equals("restart")) { + if (name.equals("shutdown") || name.equals("restart") || name.equals("reload")) { /* - * Shutdown needs a special treatment, because after sending the operation, if shutdown succeeds, - * the server connection is closed and we can't read from it. So if we get connection refused for - * reading, this is a good sign. + * Shutdown, restart and reload need a special treatment, because after sending the operation, event if + * it succeeds, the server connection is sometimes closed and we can't read from it. */ if (!res.isSuccess()) { - if (res.getRhqThrowable() != null - && (res.getRhqThrowable() instanceof ConnectException || res.getRhqThrowable().getMessage() - .equals("Connection refused"))) { + if (StringUtil.isNotBlank(res.getFailureDescription()) + && res.getFailureDescription().startsWith(ASConnection.FAILURE_NO_RESPONSE)) { operationResult.setSimpleResult("Success"); - log.debug("Got a ConnectionRefused for operation " - + name - + " this is considered ok, as the remote server sometimes closes the communications channel before sending a reply"); - } - if (res.getFailureDescription().contains("Socket closed")) { // See https://issues.jboss.org/browse/AS7-4192 - operationResult.setSimpleResult("Success"); - log.debug("Got a 'Socket closed' result from AS for operation " + name); - } else + if (log.isDebugEnabled()) { + log.debug("Got no response for operation '" + name + "'. " + + "This is considered ok, as the remote server sometimes closes the communications " + + "channel before sending a reply"); + } + } else { operationResult.setErrorMessage(res.getFailureDescription()); + } } else { operationResult.setSimpleResult("Success"); } 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 778d127..d399d1b 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 @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2012 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,8 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.modules.plugins.jbossas7;
@@ -213,7 +213,9 @@ public class StandaloneASComponent<T extends ResourceComponent<?>> extends BaseS count++; }
- log.debug("waitUntilReloaded: Used " + count + " delay round(s) to reload. Reload=" + reloaded); + if (log.isDebugEnabled()) { + log.debug("waitUntilReloaded: Used " + count + " delay round(s) to reload. Reload=" + reloaded); + }
return reloaded; }
commit 1ad9d648c0c90774d4a3379d54802c7ecd771b97 Author: Thomas Segismont tsegismo@redhat.com Date: Fri May 3 10:44:30 2013 +0200
as7plugin: LD_LIBRARY_PATH is not necessarily discovered in Linux environment
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java index 7aa92b6..f34a554 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2012 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,8 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.modules.plugins.jbossas7.itest;
@@ -205,14 +205,6 @@ public abstract class AbstractServerComponentTest extends AbstractJBossAS7Plugin String[] pathElements = path.split(File.pathSeparator); Assert.assertTrue(pathElements.length >= 1); Assert.assertTrue(new File(pathElements[0]).isDirectory()); - - if (File.separatorChar == '/') { - String ldLibraryPath = env.get("LD_LIBRARY_PATH"); - Assert.assertNotNull(ldLibraryPath); - String[] ldLibraryPathElements = ldLibraryPath.split(File.pathSeparator); - Assert.assertTrue(ldLibraryPathElements.length >= 1); - Assert.assertTrue(new File(ldLibraryPathElements[0]).isDirectory()); - } }
protected abstract String getBindAddressSystemPropertyName();
commit 059c8c96f82bf1c20863fde8ba334b95b5a98687 Author: Mike Thompson mithomps@redhat.com Date: Thu May 2 11:46:26 2013 -0700
[BZ 958734] - Add autogroup metric to dashboard fails for d3 graphs. Turned off the autogroups right click menu to create dashboard graphs from resource tree as the full fix for this is risky given we are releasing 4.7 straightaway.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java index 87c73c2..0fe3cd9 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupContextMenu.java @@ -247,156 +247,161 @@ public class ResourceGroupContextMenu extends Menu { addItem(operations);
// Metric graph addition menu - addItem(buildMetricsMenu(resourceType)); + addItem(buildMetricsMenu(resourceType, group)); }
- private MenuItem buildMetricsMenu(final ResourceType type) { + private MenuItem buildMetricsMenu(final ResourceType type, final ResourceGroup resourceGroup) { MenuItem measurements = new MenuItem(MSG.view_tree_common_contextMenu_measurements()); final Menu measurementsSubMenu = new Menu();
DashboardCriteria criteria = new DashboardCriteria(); - GWTServiceLookup.getDashboardService().findDashboardsByCriteria(criteria, - new AsyncCallback<PageList<Dashboard>>() { - public void onFailure(Throwable caught) { - CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_contextMenu_loadFail_dashboards(), - caught); - } - - public void onSuccess(PageList<Dashboard> result) { - - if (type.getMetricDefinitions() != null) { - //sort the display items alphabetically - TreeSet<String> ordered = new TreeSet<String>(); - Map<String, MeasurementDefinition> definitionMap = new HashMap<String, MeasurementDefinition>(); - for (MeasurementDefinition m : type.getMetricDefinitions()) { - ordered.add(m.getDisplayName()); - definitionMap.put(m.getDisplayName(), m); - } - - for (String displayName : ordered) { - final MeasurementDefinition def = definitionMap.get(displayName); - //only add menu items for Measurement - if (def.getDataType().equals(DataType.MEASUREMENT)) { - MenuItem defItem = new MenuItem(def.getDisplayName()); - measurementsSubMenu.addItem(defItem); - Menu defSubItem = new Menu(); - defItem.setSubmenu(defSubItem); - - for (final Dashboard d : result) { - MenuItem addToDBItem = new MenuItem(MSG - .view_tree_common_contextMenu_addChartToDashboard(d.getName())); - defSubItem.addItem(addToDBItem); - - addToDBItem.addClickHandler(new ClickHandler() { - public void onClick(MenuItemClickEvent menuItemClickEvent) { - - DashboardPortlet p = new DashboardPortlet(MSG - .view_tree_common_contextMenu_groupGraph(), - ResourceGroupD3GraphPortlet.KEY, 250); - p.getConfiguration().put( - new PropertySimple(ResourceGroupD3GraphPortlet.CFG_RESOURCE_GROUP_ID, - group.getId())); - p.getConfiguration().put( - new PropertySimple(ResourceGroupD3GraphPortlet.CFG_DEFINITION_ID, def - .getId())); - - d.addPortlet(p); - - GWTServiceLookup.getDashboardService().storeDashboard(d, - new AsyncCallback<Dashboard>() { - public void onFailure(Throwable caught) { - CoreGUI - .getErrorHandler() - .handleError( - MSG.view_tree_common_contextMenu_saveChartToDashboardFailure(), - caught); - } - - public void onSuccess(Dashboard result) { - String msg = MSG - .view_tree_common_contextMenu_saveChartToDashboardSuccessful(result - .getName()); - CoreGUI.getMessageCenter().notify( - new Message(msg, Message.Severity.Info)); - } - }); - - } - }); - - //add new menu item for adding current graphable element to view if on Monitor/Graphs tab - String currentViewPath = History.getToken(); - if (currentViewPath.indexOf("Monitoring/NewGraphs") > -1) { - MenuItem addGraphItem = new MenuItem(MSG.common_title_add_graph_to_view()); - defSubItem.addItem(addGraphItem); + final EntityContext context = EntityContext.forGroup(resourceGroup); + if(!context.isAutoGroup()){ + + GWTServiceLookup.getDashboardService().findDashboardsByCriteria(criteria, + new AsyncCallback<PageList<Dashboard>>() { + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_contextMenu_loadFail_dashboards(), + caught); + }
- addGraphItem.addClickHandler(new ClickHandler() { + public void onSuccess(PageList<Dashboard> result) { + + if (type.getMetricDefinitions() != null) { + //sort the display items alphabetically + TreeSet<String> ordered = new TreeSet<String>(); + Map<String, MeasurementDefinition> definitionMap = new HashMap<String, MeasurementDefinition>(); + for (MeasurementDefinition m : type.getMetricDefinitions()) { + ordered.add(m.getDisplayName()); + definitionMap.put(m.getDisplayName(), m); + } + + for (String displayName : ordered) { + final MeasurementDefinition def = definitionMap.get(displayName); + //only add menu items for Measurement + if (def.getDataType().equals(DataType.MEASUREMENT)) { + MenuItem defItem = new MenuItem(def.getDisplayName()); + measurementsSubMenu.addItem(defItem); + Menu defSubItem = new Menu(); + defItem.setSubmenu(defSubItem); + + for (final Dashboard d : result) { + + MenuItem addToDBItem = new MenuItem(MSG + .view_tree_common_contextMenu_addChartToDashboard(d.getName())); + defSubItem.addItem(addToDBItem); + + addToDBItem.addClickHandler(new ClickHandler() { public void onClick(MenuItemClickEvent menuItemClickEvent) { - //generate javascript to call out to. - //Ex. menuLayers.hide();addMetric('${metric.resourceId},${metric.scheduleId}') - String grpGraphElements = ""; - if (isAutoGroup) { - grpGraphElements += "ag,"; - } else { - grpGraphElements += "cg,"; - } - grpGraphElements += group.getId() + "," + def.getId(); - if (isAutoGroup) {//need to postpend the resource type as third element - grpGraphElements += "," + group.getResourceType().getId(); - } - //construct portal.war url to access - String baseUrl = "/resource/common/monitor/visibility/IndicatorCharts.do"; - //No need to rebuild the autogroup url as everything handled as a compatible group now - // if (isAutoGroup) { - // //Ex. ?parent=10001&ctype=1013&view=Default - // baseUrl += "?parent=" + group.getAutoGroupParentResource().getId() - // + "&ctype=" - // + group.getResourceType().getId(); - // jsCode = "ag," + group.getAutoGroupParentResource().getId() + "," - // + def.getId() + "," - // + group.getResourceType().getId(); - // } else { - //Ex. ?groupId=10001&view=Default - baseUrl += "?groupId=" + group.getId(); - baseUrl += "&view=Default"; - baseUrl += "&action=addChart&metric=" + grpGraphElements; - baseUrl += "&view=Default"; - final String url = baseUrl; - //initiate HTTP request - final RequestBuilder b = new RequestBuilder(RequestBuilder.GET, baseUrl); - - try { - b.setCallback(new RequestCallback() { - public void onResponseReceived(final Request request, - final Response response) { - Log.trace("Successfully submitted request to add graph to view:" - + url); - - //kick off a page reload. - String currentViewPath = History.getToken(); - CoreGUI.goToView(currentViewPath, true); + + DashboardPortlet p = new DashboardPortlet(MSG + .view_tree_common_contextMenu_groupGraph(), + ResourceGroupD3GraphPortlet.KEY, 250); + p.getConfiguration().put( + new PropertySimple(ResourceGroupD3GraphPortlet.CFG_RESOURCE_GROUP_ID, + group.getId())); + p.getConfiguration().put( + new PropertySimple(ResourceGroupD3GraphPortlet.CFG_DEFINITION_ID, def + .getId())); + + d.addPortlet(p); + + GWTServiceLookup.getDashboardService().storeDashboard(d, + new AsyncCallback<Dashboard>() { + public void onFailure(Throwable caught) { + CoreGUI + .getErrorHandler() + .handleError( + MSG.view_tree_common_contextMenu_saveChartToDashboardFailure(), + caught); }
- @Override - public void onError(Request request, Throwable t) { - Log.trace("Error adding Metric:" + url, t); + public void onSuccess(Dashboard result) { + String msg = MSG + .view_tree_common_contextMenu_saveChartToDashboardSuccessful(result + .getName()); + CoreGUI.getMessageCenter().notify( + new Message(msg, Message.Severity.Info)); } }); - b.send(); - } catch (RequestException e) { - Log.trace("Error adding Metric:" + url, e); - } - }//end of onClick definition - });//end of onClick Handler definition - }//end of Monitoring/Graphs view check - }//end of dashabord iteration - }//end of check for Measurement - }//end of metric definition iteration - }
- } - }); + } + }); + + //add new menu item for adding current graphable element to view if on Monitor/Graphs tab + String currentViewPath = History.getToken(); + if (currentViewPath.contains("Monitoring/NewGraphs")) { + MenuItem addGraphItem = new MenuItem(MSG.common_title_add_graph_to_view()); + defSubItem.addItem(addGraphItem); + + addGraphItem.addClickHandler(new ClickHandler() { + public void onClick(MenuItemClickEvent menuItemClickEvent) { + //generate javascript to call out to. + //Ex. menuLayers.hide();addMetric('${metric.resourceId},${metric.scheduleId}') + String grpGraphElements = ""; + if (isAutoGroup) { + grpGraphElements += "ag,"; + } else { + grpGraphElements += "cg,"; + } + grpGraphElements += group.getId() + "," + def.getId(); + if (isAutoGroup) {//need to postpend the resource type as third element + grpGraphElements += "," + group.getResourceType().getId(); + } + //construct portal.war url to access + String baseUrl = "/resource/common/monitor/visibility/IndicatorCharts.do"; + //No need to rebuild the autogroup url as everything handled as a compatible group now + // if (isAutoGroup) { + // //Ex. ?parent=10001&ctype=1013&view=Default + // baseUrl += "?parent=" + group.getAutoGroupParentResource().getId() + // + "&ctype=" + // + group.getResourceType().getId(); + // jsCode = "ag," + group.getAutoGroupParentResource().getId() + "," + // + def.getId() + "," + // + group.getResourceType().getId(); + // } else { + //Ex. ?groupId=10001&view=Default + baseUrl += "?groupId=" + group.getId(); + baseUrl += "&view=Default"; + baseUrl += "&action=addChart&metric=" + grpGraphElements; + baseUrl += "&view=Default"; + final String url = baseUrl; + //initiate HTTP request + final RequestBuilder b = new RequestBuilder(RequestBuilder.GET, baseUrl); + + try { + b.setCallback(new RequestCallback() { + public void onResponseReceived(final Request request, + final Response response) { + Log.trace("Successfully submitted request to add graph to view:" + + url); + + //kick off a page reload. + String currentViewPath = History.getToken(); + CoreGUI.goToView(currentViewPath, true); + } + + @Override + public void onError(Request request, Throwable t) { + Log.trace("Error adding Metric:" + url, t); + } + }); + b.send(); + } catch (RequestException e) { + Log.trace("Error adding Metric:" + url, e); + } + }//end of onClick definition + });//end of onClick Handler definition + }//end of Monitoring/Graphs view check + }//end of dashabord iteration + }//end of check for Measurement + }//end of metric definition iteration + } + + } + }); + } measurements.setSubmenu(measurementsSubMenu); return measurements; } 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 72a46a8..071f831 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 @@ -757,7 +757,7 @@ public class ResourceTreeView extends EnhancedVLayout { defItem.setSubmenu(defSubItem);
for (final Dashboard d : result) { - MenuItem addToDBItem = new MenuItem("d3-"+MSG + MenuItem addToDBItem = new MenuItem(MSG .view_tree_common_contextMenu_addChartToDashboard(d.getName())); defSubItem.addItem(addToDBItem);
@@ -802,7 +802,7 @@ public class ResourceTreeView extends EnhancedVLayout {
//add new menu item for adding current graphable element to view if on Monitor/Graphs tab String currentViewPath = History.getToken(); - if (currentViewPath.indexOf("Monitoring/Graphs") > -1) { + if (currentViewPath.contains("Monitoring/NewGraphs")) { MenuItem addGraphItem = new MenuItem(MSG.common_title_add_graph_to_view()); defSubItem.addItem(addGraphItem);
commit d6ff5eb184fb65c358c2af40e42d0156f69c1475 Author: Mike Thompson mithomps@redhat.com Date: Thu May 2 07:47:04 2013 -0700
[BZ 924300] - Time range start date and the date picker disappears on clicking 'Advanced' button on time range selector.
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 406a4fe..328112f 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 @@ -257,7 +257,7 @@ public abstract class AbstractMeasurementRangeEditor extends DynamicForm impleme protected void update() { if (advanced) { advancedSimpleButton.setTitle(MSG.view_measureRange_simple()); - showItem(ADVANCED_END_ITEM); + showItem(ADVANCED_START_ITEM); showItem(ADVANCED_END_ITEM); hideItem(SIMPLE_VALUE_ITEM); hideItem(SIMPLE_UNIT_ITEM);
commit 8e62d50b8edd576ca3b53ecb9c198d9df288b35d Author: Thomas Segismont tsegismo@redhat.com Date: Thu May 2 12:55:57 2013 +0200
Bug 952652 - Unable to delete a user who has saved searches objects in the database
Now deleting saved searches prior to deleting the user. Merged delete methods. Fail fast if caller tries to delete a superuser. Added itest for the BZ
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/auth/test/SubjectManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/auth/test/SubjectManagerBeanTest.java index 4b17dc5..9f204dd 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/auth/test/SubjectManagerBeanTest.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/auth/test/SubjectManagerBeanTest.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,8 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.server.auth.test;
@@ -41,6 +41,8 @@ import org.rhq.core.domain.authz.Role; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.criteria.SubjectCriteria; +import org.rhq.core.domain.search.SavedSearch; +import org.rhq.core.domain.search.SearchSubsystem; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PageOrdering; @@ -50,6 +52,7 @@ import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.authz.AuthorizationManagerLocal; import org.rhq.enterprise.server.authz.PermissionException; import org.rhq.enterprise.server.authz.RoleManagerLocal; +import org.rhq.enterprise.server.search.SavedSearchManagerLocal; import org.rhq.enterprise.server.test.AbstractEJB3Test; import org.rhq.enterprise.server.test.TransactionCallback; import org.rhq.enterprise.server.util.LookupUtil; @@ -70,12 +73,14 @@ public class SubjectManagerBeanTest extends AbstractEJB3Test { private SubjectManagerLocal subjectManager; private AuthorizationManagerLocal authorizationManager; private RoleManagerLocal roleManager; + private SavedSearchManagerLocal savedSearchManager;
@Override protected void beforeMethod() { subjectManager = LookupUtil.getSubjectManager(); authorizationManager = LookupUtil.getAuthorizationManager(); roleManager = LookupUtil.getRoleManager(); + savedSearchManager = LookupUtil.getSavedSearchManager(); createITestSubject(); }
@@ -756,4 +761,24 @@ public class SubjectManagerBeanTest extends AbstractEJB3Test { } }); } -} \ No newline at end of file + + public void shouldBeAbleToDeleteASubjectWhoOwnsASavedSearch() { + // See https://bugzilla.redhat.com/show_bug.cgi?id=952652 + SavedSearch savedSearch = new SavedSearch(SearchSubsystem.GROUP, "fake saved search", "pipo", subjectManager.getSubjectByName(ITEST_USER)); + Integer savedSearchId = savedSearchManager.createSavedSearch(subjectManager.getOverlord(), savedSearch); + boolean subjectDeleted = false; + try { + deleteITestSubject(); + subjectDeleted = true; + } catch (Exception e) { + LOG.error("Failed to delete a subject who owns a saved search", e); + fail("Failed to delete a subject who owns a saved search"); + } finally { + // This is only necessary if we failed to delete subject + if (!subjectDeleted) { + savedSearchManager.deleteSavedSearch(subjectManager.getOverlord(), savedSearchId); + } + } + } + +} diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java index c78a1bd..43d955f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java @@ -1,6 +1,6 @@ /* * RHQ Management Platform - * Copyright (C) 2005-2012 Red Hat, Inc. + * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,8 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.server.auth;
@@ -59,8 +59,10 @@ import org.rhq.core.domain.common.composite.SystemSettings; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.criteria.RoleCriteria; +import org.rhq.core.domain.criteria.SavedSearchCriteria; import org.rhq.core.domain.criteria.SubjectCriteria; import org.rhq.core.domain.resource.group.ResourceGroup; +import org.rhq.core.domain.search.SavedSearch; import org.rhq.core.domain.server.PersistenceUtility; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; @@ -75,6 +77,7 @@ import org.rhq.enterprise.server.core.CustomJaasDeploymentServiceMBean; import org.rhq.enterprise.server.exception.LoginException; import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal; import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal; +import org.rhq.enterprise.server.search.SavedSearchManagerLocal; import org.rhq.enterprise.server.system.SystemManagerLocal; import org.rhq.enterprise.server.util.CriteriaQueryGenerator; import org.rhq.enterprise.server.util.CriteriaQueryRunner; @@ -117,6 +120,9 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe //@IgnoreDependency private RepoManagerLocal repoManager;
+ @EJB + private SavedSearchManagerLocal savedSearchManager; + @Resource private TimerService timerService;
@@ -661,6 +667,10 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe throw new PermissionException("You cannot remove yourself: " + doomedSubject.getName()); }
+ if (authorizationManager.isSystemSuperuser(doomedSubject)) { + throw new PermissionException("You cannot delete a system root user - they must always exist"); + } + Set<Role> roles = doomedSubject.getRoles(); doomedSubject.setRoles(new HashSet<Role>()); // clean out roles
@@ -694,7 +704,20 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe } }
- deleteSubject(doomedSubject); + // Delete searches saved by this user + SavedSearchCriteria savedSearchCriteria = new SavedSearchCriteria(); + savedSearchCriteria.addFilterSubjectId(doomedSubjectId); + savedSearchCriteria.clearPaging(); + PageList<SavedSearch> savedSearches = savedSearchManager.findSavedSearchesByCriteria(subject, savedSearchCriteria); + for (SavedSearch savedSearch : savedSearches) { + savedSearchManager.deleteSavedSearch(subject, savedSearch.getId()); + } + + alertNotificationManager.cleanseAlertNotificationBySubject(doomedSubject.getId()); + + repoManager.removeOwnershipOfSubject(doomedSubject.getId()); + + entityManager.remove(doomedSubject); }
return; @@ -709,27 +732,6 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe }
/** - * Deletes the given {@link Subject} from the database. - * - * - * @param doomedSubject identifies the subject to delete - * - * @throws PermissionException if caller tried to delete a system superuser - */ - private void deleteSubject(Subject doomedSubject) throws PermissionException { - if (authorizationManager.isSystemSuperuser(doomedSubject)) { - throw new PermissionException("You cannot delete a system root user - they must always exist"); - } - - alertNotificationManager.cleanseAlertNotificationBySubject(doomedSubject.getId()); - repoManager.removeOwnershipOfSubject(doomedSubject.getId()); - - entityManager.remove(doomedSubject); - - return; - } - - /** * Delete a user's principal from the internal database. * * @@ -883,4 +885,4 @@ public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRe return; }
-} \ No newline at end of file +}
commit 248cb85b93eadfe328fc4f8e0ab708239a813610 Author: Mike Thompson mithomps@redhat.com Date: Wed May 1 16:50:11 2013 -0700
Javascript console object is not valid under IE8 removing console.log statement.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphIE8Impl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphIE8Impl.java index 7390349..75ce6e3 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphIE8Impl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphIE8Impl.java @@ -20,6 +20,7 @@ package org.rhq.enterprise.gui.coregui.client.inventory.common.charttype;
/** * Contains the javascript chart definition for an IE8 d3 Stacked Bar graph chart. + * Curr * * @author Mike Thompson */ @@ -39,8 +40,7 @@ public final class StackedBarMetricGraphIE8Impl extends StackedBarMetricGraphImp */ @Override public native void drawJsniChart() /*-{ - console.log("Using StackedBarMetricGraphIE8Impl for IE8."); - + // no-op implementation for ie8 }-*/;
}
commit 339eb402b41277d45bb32b8b6da837cb02c2f38e Author: Mike Thompson mithomps@redhat.com Date: Wed May 1 14:59:58 2013 -0700
Fix to keep IE9 from behaving like IE8 with respect to charting.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractD3GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractD3GraphListView.java index d682a24..d942b8c 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractD3GraphListView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractD3GraphListView.java @@ -38,8 +38,8 @@ import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout; * and User Preferences pickers for the date range. */ public abstract class AbstractD3GraphListView extends EnhancedVLayout implements AutoRefresh { - protected static int SINGLE_CHART_HEIGHT = 225; - protected static int MULTI_CHART_HEIGHT = 195; + protected final static int SINGLE_CHART_HEIGHT = 225; + protected final static int MULTI_CHART_HEIGHT = 195; protected List<Availability> availabilityList; protected List<ResourceGroupAvailability> groupAvailabilityList; protected AvailabilityD3Graph availabilityGraph; 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 f3c93be..d5ae804 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 @@ -36,6 +36,10 @@ </any> </replace-with>
+ <replace-with class="org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphImpl"> + <when-type-is class="org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphImpl"/> + </replace-with> + <replace-with class="org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphIE8Impl"> <when-type-is class="org.rhq.enterprise.gui.coregui.client.inventory.common.charttype.StackedBarMetricGraphImpl"/> <when-property-is name="user.agent" value="ie8"/>
commit 93a7c3264c30a6ea08d2c767fa6f087a3a86aa1d Author: Mike Thompson mithomps@redhat.com Date: Wed May 1 07:54:40 2013 -0700
Fix IE issues with "Move jquery(1.7.2) library out of CoreGUI.gwt.xml now that we don't have GFlot dependency (GFlot was removed with addition of d3 charts)."
This reverts commit 8c54ef01abaa6790f49f96c492fe6649a0245a6f.
Revert "UI Performance - Move non-essential javascripts (like charting) out of CoreGUI.gwt.xml to CoreGUI.html and add the 'defer' script evaluation attribute for faster page load time. Also moved stylesheets to load ahead of javascripts as they load faster and provide less blocking time than the external javascripts. This shaved about 0.5 sec on my box will probably save more on slower hardware/connection/mobile. The *.gwt.xml prevents race conditions at the expense of speed so moving out increases startup speed." This commit has unintended consequences for IE9 browser. Javascript libraries that are supposed to be loaded are not (although this works in other browsers).
This reverts commit e4ac4b1b628ae5e577510045ead7967a603d4c1c.
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 7d50e87..f3c93be 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,6 +46,17 @@ <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/> </generate-with>
+ <!-- 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 2.4.2 requires + the version of jquery (1.7.2). + --> + <script src="/coregui/js/jquery-1.7.2.min.js"/> + <script src="/coregui/js/jquery.sparkline-2.1.min.js"/> + <script src="/coregui/js/d3.v3.js"/> + <script src="/coregui/js/nv.d3.js"/> + <script src="/coregui/js/jquery.tipsy.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 1b69b53..206b586 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html +++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html @@ -10,19 +10,7 @@ <!-- support internationalized characters --> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
- <link rel="stylesheet" href="CoreGUI.css"> - <link rel="stylesheet" href="css/nv.d3.css"> - <link rel="stylesheet" href="css/tipsy.css"> - <link rel="stylesheet" href="css/charts.css"> - - <script defer="defer" type="text/javascript" src="/coregui/js/rhq.js"></script> - <script defer="defer" type="text/javascript" src="/coregui/js/d3.v3.js"></script> - <script defer="defer" type="text/javascript" src="/coregui/js/nv.d3.js"></script> - <!-- jquery dependent js libs --> - <script defer="defer" type="text/javascript" src="/coregui/js/jquery-1.7.2.min.js"></script> - <script defer="defer" type="text/javascript" src="/coregui/js/jquery.sparkline-2.1.min.js"></script> - <script defer="defer" type="text/javascript" src="/coregui/js/jquery.tipsy.js"></script> - + <script type="text/javascript" src="js/rhq.js"></script> <script type="text/javascript"> var search = location.search; // only do this if you have not specified locale as query param @@ -42,6 +30,12 @@ var isomorphicDir = "org.rhq.enterprise.gui.coregui.CoreGUI/sc/"; </script>
+ + <link rel="stylesheet" href="CoreGUI.css"> + <link rel="stylesheet" href="css/nv.d3.css"> + <link rel="stylesheet" href="css/tipsy.css"> + <link rel="stylesheet" href="css/charts.css"> + </head> <body>
commit 4c50679d28c84c2d0057c2438bb985c562fc8ac5 Author: John Mazzitelli mazz@redhat.com Date: Wed May 1 12:14:40 2013 -0400
BZ 893609 - remove temp workaround code now that we are on a newer EAP that doesn't have the bad issues anymore
diff --git a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java index 9a766f4..8cef6e1 100644 --- a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java +++ b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java @@ -46,6 +46,29 @@ public class CoreJBossASClient extends JBossASClient { }
/** + * Given a string with possible ${x} expressions in it, this will resolve that expression + * using system property values that are set within the AS JVM itself. If the string + * to resolve has no expressions, or has no expressions that are resolveable, the expression + * string itself is returned as-is (this includes if <code>expression</code> is <code>null</code>). + * + * @param expression string containing zero, one or more ${x} expressions to be resolved + * @return the expression with the expressions resolved using system properties of the AS JVM + * @throws Exception if failed to resolve the expression. + */ + public String resolveExpression(String expression) throws Exception { + if (expression == null || expression.length() == 0) { + return expression; + } + final ModelNode request = createRequest("resolve-expression", Address.root()); + request.get("expression").set(expression); + final ModelNode response = execute(request); + if (!isSuccess(response)) { + throw new FailureException(response); + } + return getResults(response).asString(); + } + + /** * This returns the system properties that are set in the AS JVM. This is not the system properties * in the JVM of this client object - it is actually the system properties in the remote * JVM of the AS instance that the client is talking to. diff --git a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/LoggingJBossASClient.java b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/LoggingJBossASClient.java index babe373..ee7466e 100644 --- a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/LoggingJBossASClient.java +++ b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/LoggingJBossASClient.java @@ -72,7 +72,7 @@ public class LoggingJBossASClient extends JBossASClient { final ModelNode request;
if (isLogger(loggerName)) { - request = createWriteAttributeRequest("level", level.toUpperCase(), addr); + request = createWriteAttributeRequest("level", level, addr); } else { final String dmrTemplate = "" // + "{" // @@ -80,7 +80,7 @@ public class LoggingJBossASClient extends JBossASClient { + ", "level" => "%s" " // + ", "use-parent-handlers" => "true" " // + "}"; - final String dmr = String.format(dmrTemplate, loggerName, level.toUpperCase()); + final String dmr = String.format(dmrTemplate, loggerName, level);
request = ModelNode.fromString(dmr); request.get(OPERATION).set(ADD); diff --git a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java index f977f0a..5caa45e 100644 --- a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java +++ b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/SecurityDomainJBossASClient.java @@ -26,6 +26,7 @@ import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType;
/** * Provides convenience methods associated with security domain management. @@ -71,49 +72,6 @@ public class SecurityDomainJBossASClient extends JBossASClient { * Create a new security domain using the SecureIdentity authentication method. * This is used when you want to obfuscate a database password in the configuration. * - * @param securityDomainName the name of the new security domain - * @param username the username associated with the security domain - * @param password the value of the password to store in the configuration (e.g. the obfuscated password itself) - * - * @throws Exception if failed to create security domain - */ - public void createNewSecureIdentitySecurityDomain71(String securityDomainName, String username, String password) - throws Exception { - - Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_SECURITY, SECURITY_DOMAIN, securityDomainName); - ModelNode addTopNode = createRequest(ADD, addr); - addTopNode.get(CACHE_TYPE).set("default"); - - ModelNode addAuthNode = createRequest(ADD, addr.clone().add(AUTHENTICATION, CLASSIC)); - ModelNode loginModulesNode = addAuthNode.get(LOGIN_MODULES); - ModelNode loginModule = new ModelNode(); - loginModule.get(CODE).set("SecureIdentity"); - loginModule.get(FLAG).set("required"); - ModelNode moduleOptions = loginModule.get(MODULE_OPTIONS); - moduleOptions.setEmptyList(); - // TODO: we really want to use addExpression (e.g. ${rhq.server.database.user-name}) - // for username and password so rhq-server.properties can be used to set these. - // However, AS7.1 doesn't support this yet - see https://issues.jboss.org/browse/AS7-5177 - moduleOptions.add(USERNAME, username); - moduleOptions.add(PASSWORD, password); - loginModulesNode.add(loginModule); - - ModelNode batch = createBatchRequest(addTopNode, addAuthNode); - - System.err.println("== security domain ==> " + batch.toJSONString(false)); - - ModelNode results = execute(batch); - if (!isSuccess(results)) { - throw new FailureException(results, "Failed to create security domain [" + securityDomainName + "]"); - } - - return; - } - - /** - * Create a new security domain using the SecureIdentity authentication method. - * This is used when you want to obfuscate a database password in the configuration. - * * This is the version for as7.2+ (e.g. eap 6.1) * * @param securityDomainName the name of the new security domain @@ -139,11 +97,8 @@ public class SecurityDomainJBossASClient extends JBossASClient { loginModule.get(FLAG).set("required"); ModelNode moduleOptions = loginModule.get(MODULE_OPTIONS); moduleOptions.setEmptyList(); - // TODO: we really want to use addExpression (e.g. ${rhq.server.database.user-name}) - // for username and password so rhq-server.properties can be used to set these. - // However, AS7.1 doesn't support this yet - see https://issues.jboss.org/browse/AS7-5177 - moduleOptions.add(USERNAME, username); - moduleOptions.add(PASSWORD, password); + addPossibleExpression(moduleOptions, USERNAME, username); + addPossibleExpression(moduleOptions, PASSWORD, password);
ModelNode batch = createBatchRequest(addTopNode, addAuthNode, loginModule);
@@ -178,11 +133,8 @@ public class SecurityDomainJBossASClient extends JBossASClient { loginModule.get(FLAG).set("required"); ModelNode moduleOptions = loginModule.get(MODULE_OPTIONS); moduleOptions.setEmptyList(); - // TODO: we really want to use addExpression (e.g. ${rhq.server.database.user-name}) - // for username and password so rhq-server.properties can be used to set these. - // However, AS7.1 doesn't support this yet - see https://issues.jboss.org/browse/AS7-5177 - moduleOptions.add(USERNAME, username); - moduleOptions.add(PASSWORD, password); + addPossibleExpression(moduleOptions, USERNAME, username); + addPossibleExpression(moduleOptions, PASSWORD, password);
// login modules attribute must be a list - we only have one item in it, the loginModule ModelNode loginModuleList = new ModelNode(); @@ -202,6 +154,14 @@ public class SecurityDomainJBossASClient extends JBossASClient { return; }
+ private void addPossibleExpression(ModelNode node, String name, String value) { + if (value != null && value.contains("${")) { + node.add(name, new ModelNode(ModelType.EXPRESSION).setExpression(value)); + } else { + node.add(name, value); + } + } + /** * Given the name of an existing security domain that uses the SecureIdentity authentication method, * this returns the module options for that security domain authentication method. This includes @@ -231,49 +191,6 @@ public class SecurityDomainJBossASClient extends JBossASClient { /** * Create a new security domain using the database server authentication method. * This is used when you want to directly authenticate against a db entry. - * - * @param securityDomainName the name of the new security domain - * @param dsJndiName the jndi name for the datasource to query against - * @param principalsQuery the SQL query for selecting password info for a principal - * @param rolesQuery the SQL query for selecting role info for a principal - * @param hashAlgorithm if null defaults to "MD5" - * @param hashEncoding if null defaults to "base64" - * @throws Exception if failed to create security domain - */ - public void createNewDatabaseServerSecurityDomain71(String securityDomainName, String dsJndiName, - String principalsQuery, String rolesQuery, String hashAlgorithm, - String hashEncoding) throws Exception { - - Address addr = Address.root().add(SUBSYSTEM, SUBSYSTEM_SECURITY, SECURITY_DOMAIN, securityDomainName); - ModelNode addTopNode = createRequest(ADD, addr); - addTopNode.get(CACHE_TYPE).set("default"); - - ModelNode addAuthNode = createRequest(ADD, addr.clone().add(AUTHENTICATION, CLASSIC)); - ModelNode loginModulesNode = addAuthNode.get(LOGIN_MODULES); - ModelNode loginModule = new ModelNode(); - loginModule.get(CODE).set("Database"); - loginModule.get(FLAG).set("required"); - ModelNode moduleOptions = loginModule.get(MODULE_OPTIONS); - moduleOptions.setEmptyList(); - moduleOptions.add(DS_JNDI_NAME, dsJndiName); - moduleOptions.add(PRINCIPALS_QUERY, principalsQuery); - moduleOptions.add(ROLES_QUERY, rolesQuery); - moduleOptions.add(HASH_ALGORITHM, (null == hashAlgorithm ? "MD5" : hashAlgorithm)); - moduleOptions.add(HASH_ENCODING, (null == hashEncoding ? "base64" : hashEncoding)); - loginModulesNode.add(loginModule); - - ModelNode batch = createBatchRequest(addTopNode, addAuthNode); - ModelNode results = execute(batch); - if (!isSuccess(results)) { - throw new FailureException(results, "Failed to create security domain [" + securityDomainName + "]"); - } - - return; - } - - /** - * Create a new security domain using the database server authentication method. - * This is used when you want to directly authenticate against a db entry. * This is for AS 7.2+ (e.g. EAP 6.1) and works around https://issues.jboss.org/browse/AS7-6527 * * @param securityDomainName the name of the new security domain diff --git a/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-autoinstall.sh b/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-autoinstall.sh index fbbc397..5369ab2 100755 --- a/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-autoinstall.sh +++ b/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-autoinstall.sh @@ -18,8 +18,6 @@ do eval ${_INSTALLER_SCRIPT} if [ "$?" -eq "0" ]; then echo Installer finished - # most times, the installation was already done, but see if changes to rhq-server.properties requires a reconfiguration - eval ${_INSTALLER_SCRIPT} --reconfig break; elif [ "$?" -eq "1" ]; then echo The installer has been disabled - please fix rhq-server.properties diff --git a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml index 20ff84b..05619cb 100644 --- a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml @@ -495,16 +495,17 @@ rhq.communications.multicast-detector.port=16162 # Server-side SSL Security Configuration for HTTPS thru Tomcat # These are used for browser https access and # for incoming messages from agents over sslservlet transport. -# Relative filenames are relative to jboss.server.config.dir. -# [you cannot use ${x} variables in these rhq.server.tomcat settings] +# [Due to issue https://issues.jboss.org/browse/WFLY-1177, you cannot change +# rhq.server.tomcat.security.keystore.file or rhq.server.tomcat.security.truststore.file +# after you install RHQ. If you need to change those again, you must manually do so in standalone-full.xml.] rhq.server.tomcat.security.client-auth-mode=false rhq.server.tomcat.security.secure-socket-protocol=TLS rhq.server.tomcat.security.algorithm=SunX509 rhq.server.tomcat.security.keystore.alias=RHQ -rhq.server.tomcat.security.keystore.file=rhq.keystore +rhq.server.tomcat.security.keystore.file=${jboss.server.config.dir}/rhq.keystore rhq.server.tomcat.security.keystore.password=RHQManagement rhq.server.tomcat.security.keystore.type=JKS -rhq.server.tomcat.security.truststore.file=rhq.truststore +rhq.server.tomcat.security.truststore.file=${jboss.server.config.dir}/rhq.truststore rhq.server.tomcat.security.truststore.password=RHQManagement rhq.server.tomcat.security.truststore.type=JKS
@@ -637,32 +638,11 @@ rhq.sync.endpoint-address=false </replace> </target>
- <!-- This is so we can work around all the issues due to https://issues.jboss.org/browse/AS7-6120 - so once that is fixed, we don't have to run the installer "reconfig" automatically on startup of the server. - Note that if we predeploy (i.e. are doing a dev build), rather than jump through more hoops for this, - just assume the developer knows that if they change rhq-server.properties, they have to reconfig the server. - We don't do anything in this target if we are building a dev build. --> - <target name="add-auto-reconfig" unless="predeploy"> - <echo>Add auto-reconfig to rhq-server scripts so users don't have to when changing rhq-server.properties</echo> - <replace file="${project.build.outputDirectory}/bin/rhq-server.sh"> - <replacefilter> - <replacetoken># START SERVER</replacetoken> - <replacevalue><![CDATA[export RHQ_SERVER_HOME; ${RHQ_SERVER_HOME}/bin/rhq-installer.sh --reconfig &]]></replacevalue> - </replacefilter> - </replace> - <replace file="${project.build.outputDirectory}/bin/rhq-server.bat"> - <replacefilter> - <replacetoken>rem START SERVER</replacetoken> - <replacevalue><![CDATA[start /B %RHQ_SERVER_HOME%\bin\rhq-installer.bat --reconfig < nul > nul]]></replacevalue> - </replacefilter> - </replace> - </target> <target name="prepare-release" description="If this is a release build, make sure it is properly prepared." depends="initialize, developer-release-message, copy-dev-resources, - add-auto-reconfig, fix-perms, deploy-postgres-ds, deploy-oracle-ds"> diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java index 26bc2f6..36da859 100644 --- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java +++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java @@ -47,7 +47,7 @@ public class Installer { private InstallerConfiguration installerConfig;
private enum WhatToDo { - DISPLAY_USAGE, DO_NOTHING, RECONFIGURE, TEST, SETUPDB, LIST_SERVERS, INSTALL + DISPLAY_USAGE, DO_NOTHING, TEST, SETUPDB, LIST_SERVERS, INSTALL }
public static void main(String[] args) { @@ -108,20 +108,6 @@ public class Installer { } continue; } - case RECONFIGURE: { - try { - final InstallerService installerService = new InstallerServiceImpl(installerConfig); - final HashMap<String, String> serverProperties = installerService.getServerProperties(); - final boolean reconfigured = installerService.reconfigure(serverProperties); - if (reconfigured) { - LOG.info("Reconfiguration is complete."); - } - } catch (Exception e) { - LOG.error(ThrowableUtil.getAllMessages(e)); - System.exit(EXIT_CODE_INSTALLATION_ERROR); - } - continue; - } case INSTALL: { try { final InstallerService installerService = new InstallerServiceImpl(installerConfig); @@ -159,28 +145,25 @@ public class Installer { usage.append("\t--force, -f: force the installer to try to install everything").append("\n"); usage.append("\t--listservers, -l: show list of known installed servers (install not performed)").append("\n"); usage.append("\t--setupdb, -b: only perform database schema creation or update").append("\n"); - usage.append("\t--reconfig, -r: resets some configuration settings in an installed server").append("\n"); usage.append("\t--dbpassword, -d: encodes a DB password for rhq-server.properties (install not performed)") .append("\n"); LOG.info(usage); }
private WhatToDo[] processArguments(String[] args) throws Exception { - String sopts = "-:HD:h:p:d:bflrt"; + String sopts = "-:HD:h:p:d:bflt"; LongOpt[] lopts = { new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'H'), new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'h'), new LongOpt("port", LongOpt.REQUIRED_ARGUMENT, null, 'p'), new LongOpt("dbpassword", LongOpt.REQUIRED_ARGUMENT, null, 'd'), new LongOpt("setupdb", LongOpt.NO_ARGUMENT, null, 'b'), new LongOpt("listservers", LongOpt.NO_ARGUMENT, null, 'l'), - new LongOpt("reconfig", LongOpt.NO_ARGUMENT, null, 'r'), new LongOpt("force", LongOpt.NO_ARGUMENT, null, 'f'), new LongOpt("test", LongOpt.NO_ARGUMENT, null, 't') };
boolean test = false; boolean listservers = false; boolean setupdb = false; - boolean reconfig = false; String dbpassword = null;
Getopt getopt = new Getopt("installer", args, sopts, lopts); @@ -267,11 +250,6 @@ public class Installer { break; // don't return, we need to allow more args to be processed, like -p or -h }
- case 'r': { - reconfig = true; - break; // don't return, we need to allow more args to be processed, like -p or -h - } - case 't': { test = true; break; // don't return, we need to allow more args to be processed, like -p or -h @@ -286,10 +264,6 @@ public class Installer { return new WhatToDo[] { WhatToDo.DO_NOTHING }; }
- if (reconfig) { - return new WhatToDo[] { WhatToDo.RECONFIGURE }; - } - if (test || setupdb || listservers) { ArrayList<WhatToDo> whatToDo = new ArrayList<WhatToDo>(); if (test) { diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerService.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerService.java index c1ffa48..6eff4b7 100644 --- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerService.java +++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerService.java @@ -121,23 +121,6 @@ public interface InstallerService { String existingSchemaOption) throws Exception;
/** - * This will take server properties and reconfigure an already-installed server - * with those values if the settings were previously hardcoded to old values (as opposed to being - * set to expressions that allow them to be overridden with system property settings). - * Note that is function is here only to workaround various bugs in AS7 - * that force us to not be able to use expressions in certain app server subsystem attribute - * settings - see https://issues.jboss.org/browse/AS7-6120. Once this issues are fixed, this - * method will go away. - * - * @param serverProperties the new server properties - * @return true if the reconfigure was at least attempted; false if the server isn't ready to be reconfigured - * such as when it hasn't been fully installed yet - * @throws Exception - */ - @Deprecated - boolean reconfigure(HashMap<String, String> serverProperties) throws Exception; - - /** * Returns a list of all registered servers in the database. * * @param connectionUrl diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java index 95b4bc3..8173e68 100644 --- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java +++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java @@ -563,81 +563,6 @@ public class InstallerServiceImpl implements InstallerService { return map; }
- // This is here only to help users workaround https://issues.jboss.org/browse/AS7-6120. - // It will go away once all the issues with expression support in AS7 are fixed. - // Notice in this method we only reconfigure some things - only the subsystems/services - // that didn't support expressions in their attributes are reconfigured here since it - // is those whose values are hardcoded and we must alter to pick up changes to - // rhq-server.properties. All other services can pick up the property value changes - // make to rhq-server.properties on restart (since rhq-server.properties are system - // properties set in the AS7 instance via -P option to AS7). - @Override - public boolean reconfigure(HashMap<String, String> serverProperties) throws Exception { - - // make sure we can connect using our configuration - testModelControllerClient(serverProperties, 30); - - if (null == getInstallationResults()) { - log("Run the installer on this server."); - return false; - } - - String appServerConfigDir = getAppServerConfigDir(); - ModelControllerClient mcc = null; - - try { - mcc = getModelControllerClient(); - - // Before we do anything, let's first make sure we really do need to reconfigure something. - // Check to see if everything that didn't use expressions is still the same. If so, - // just skip everything else and return immediate since there is nothing to do. We don't - // even need to reload/restart the server in this case. - try { - if (ServerInstallUtil.isSameDatasourceSecurityDomainExisting(mcc, serverProperties)) { - if (ServerInstallUtil.isSameMailServiceExisting(mcc, serverProperties)) { - if (ServerInstallUtil.isSameWebConnectorsExisting(mcc, appServerConfigDir, serverProperties)) { - if (ServerInstallUtil.isSameLoggingExisting(mcc, serverProperties)) { - log("Nothing in the configuration changed that requires a reconfig - everything looks OK"); - return true; // nothing to do, return immediately - } - } - } - } - } catch (Exception e) { - log("Cannot determine if the config is the same, will reconfigure just in case", e); - } - - // first, put the server in admin-only mode so we can start changing things around - CoreJBossASClient coreClient = new CoreJBossASClient(mcc); - coreClient.reload(true); - - // not sure if we have to, but see if we need to wait for the reload to finish - testModelControllerClient(30); - - mcc = getModelControllerClient(); // get a new controller - - // create the security domain needed by the datasources - ServerInstallUtil.createDatasourceSecurityDomain(mcc, serverProperties); - - // setup the email service - ServerInstallUtil.setupMailService(mcc, serverProperties); - - // setup the secure Tomcat web connectors - ServerInstallUtil.setupWebConnectors(mcc, appServerConfigDir, serverProperties); - - // setup the logging level - ServerInstallUtil.configureLogging(mcc, serverProperties); - - // now restart - don't just reload, some of our stuff won't restart properly if we just reload - coreClient = new CoreJBossASClient(mcc); - coreClient.restart(); - } finally { - safeClose(mcc); - } - - return true; - } - /** * Makes sure the data is at least in the correct format (booleans are true/false, integers are valid numbers). * diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java index 687e496..d6e0d10 100644 --- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java +++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java @@ -167,7 +167,7 @@ public class ServerInstallUtil { LoggingJBossASClient client = new LoggingJBossASClient(mcc);
// we want to create our own category - String val = buildExpression(ServerProperties.PROP_LOG_LEVEL, serverProperties, false); // enable when AS7-5321 is fixed + String val = buildExpression(ServerProperties.PROP_LOG_LEVEL, serverProperties, true); client.setLoggerLevel("org.rhq", val); LOG.info("Logging category org.rhq set to [" + val + "]"); } @@ -209,7 +209,7 @@ public class ServerInstallUtil { throws Exception {
String fromAddressExpr = buildExpression(ServerProperties.PROP_EMAIL_FROM_ADDRESS, serverProperties, true); - String smtpHostExpr = buildExpression(ServerProperties.PROP_EMAIL_SMTP_HOST, serverProperties, false); // enable when AS7-5321 is fixed + String smtpHostExpr = buildExpression(ServerProperties.PROP_EMAIL_SMTP_HOST, serverProperties, true); String smtpPortExpr = buildExpression(ServerProperties.PROP_EMAIL_SMTP_PORT, serverProperties, true);
// Tweek the mail configuration that comes out of box. Setup a batch request to write the proper attributes. @@ -283,19 +283,13 @@ public class ServerInstallUtil { public static void createDatasourceSecurityDomain(ModelControllerClient mcc, HashMap<String, String> serverProperties) throws Exception {
- final String dbUsername = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME); - final String obfuscatedPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD); + final String dbUsername = buildExpression(ServerProperties.PROP_DATABASE_USERNAME, serverProperties, true); + final String obfuscatedPassword = buildExpression(ServerProperties.PROP_DATABASE_PASSWORD, serverProperties, + true); final SecurityDomainJBossASClient client = new SecurityDomainJBossASClient(mcc); - final CoreJBossASClient coreClient = new CoreJBossASClient(mcc); - String asVersion = coreClient.getAppServerVersion(); final String securityDomain = RHQ_DS_SECURITY_DOMAIN; if (!client.isSecurityDomain(securityDomain)) { - if (asVersion.startsWith("7.2")) { - client.createNewSecureIdentitySecurityDomain72(securityDomain, dbUsername, obfuscatedPassword); - } - else { - client.createNewSecureIdentitySecurityDomain71(securityDomain, dbUsername, obfuscatedPassword); - } + client.createNewSecureIdentitySecurityDomain72(securityDomain, dbUsername, obfuscatedPassword); LOG.info("Security domain [" + securityDomain + "] created"); } else { LOG.info("Security domain [" + securityDomain + "] already exists, skipping the creation request"); @@ -384,21 +378,12 @@ public class ServerInstallUtil { throws Exception {
final SecurityDomainJBossASClient client = new SecurityDomainJBossASClient(mcc); - final CoreJBossASClient coreClient = new CoreJBossASClient(mcc); - String asRelase = coreClient.getAppServerVersion(); final String securityDomain = RHQ_REST_SECURITY_DOMAIN; if (!client.isSecurityDomain(securityDomain)) { String dsJndiName = "java:jboss/datasources/" + RHQ_DATASOURCE_NAME_XA; - if (asRelase.startsWith("7.2")) { - client.createNewDatabaseServerSecurityDomain72(securityDomain, dsJndiName, - "SELECT PASSWORD FROM RHQ_PRINCIPAL WHERE principal=?", - "SELECT 'all', 'Roles' FROM RHQ_PRINCIPAL WHERE principal=?", null, null); - } - else { - client.createNewDatabaseServerSecurityDomain71(securityDomain, dsJndiName, - "SELECT PASSWORD FROM RHQ_PRINCIPAL WHERE principal=?", - "SELECT 'all', 'Roles' FROM RHQ_PRINCIPAL WHERE principal=?", null, null); - } + client.createNewDatabaseServerSecurityDomain72(securityDomain, dsJndiName, + "SELECT PASSWORD FROM RHQ_PRINCIPAL WHERE principal=?", + "SELECT 'all', 'Roles' FROM RHQ_PRINCIPAL WHERE principal=?", null, null); LOG.info("Security domain [" + securityDomain + "] created"); } else { LOG.info("Security domain [" + securityDomain + "] already exists, skipping the creation request"); @@ -1256,15 +1241,24 @@ public class ServerInstallUtil { LOG.info("Creating https connector..."); ConnectorConfiguration connector = buildSecureConnectorConfiguration(configDirStr, serverProperties);
- // verify that we have a truststore file - if user is relying on our self-signed certs, we'll have to create one for them + // https://issues.jboss.org/browse/WFLY-1177 - we need to resolve the paths right now. the user won't be able + // to change these again in the future unless they go directly into standalone.xml and change it manually String truststoreFileString = connector.getSslConfiguration().getCaCertificateFile(); + truststoreFileString = resolveExpression(mcc, truststoreFileString); + connector.getSslConfiguration().setCaCertificateFile(truststoreFileString); + + String keystoreFileString = connector.getSslConfiguration().getCertificateKeyFile(); + keystoreFileString = resolveExpression(mcc, keystoreFileString); + connector.getSslConfiguration().setCertificateKeyFile(keystoreFileString); + + // verify that we have a truststore file - if user is relying on our self-signed certs, we'll have to create one for them if (truststoreFileString == null) { LOG.warn("Missing a valid truststore location - you must specify a valid truststore location!"); } else { File truststoreFile = new File(truststoreFileString); if (!truststoreFile.exists()) { // user didn't provide a truststore file, copy the keystore and use it as the truststore; tell the user about this - File keystoreFile = new File(connector.getSslConfiguration().getCertificateKeyFile()); + File keystoreFile = new File(keystoreFileString); if (!keystoreFile.isFile()) { LOG.warn("Missing both keystore [" + keystoreFile + "] and truststore [" + truststoreFile + "]"); } else { @@ -1283,41 +1277,64 @@ public class ServerInstallUtil { LOG.info("https connector created.");
if (client.isConnector(connectorName)) { + client.changeConnector(connectorName, "max-connections", + buildExpression("rhq.server.startup.web.max-connections", serverProperties, true)); client.changeConnector(connectorName, "redirect-port", - buildExpression("rhq.server.socket.binding.port.https", serverProperties, false)); + buildExpression("rhq.server.socket.binding.port.https", serverProperties, true)); } else { LOG.warn("There doesn't appear to be a http connector configured already - this is strange."); } }
+ private static String resolveExpression(ModelControllerClient mcc, String expression) { + if (expression == null) { + return null; + } + + CoreJBossASClient client = new CoreJBossASClient(mcc); + String resolvedExpression; + try { + resolvedExpression = client.resolveExpression(expression); + + // https://issues.jboss.org/browse/WFLY-1177 - app server doesn't do recursive resolving, we have to do it here + while (resolvedExpression != null && resolvedExpression.contains("${") + && !resolvedExpression.equals(expression)) { + expression = resolvedExpression; + resolvedExpression = client.resolveExpression(expression); + } + } catch (Exception e) { + LOG.warn("Cannot resolve expression [" + expression + "]; will use it as-is but errors may occur later."); + resolvedExpression = expression; + } + return resolvedExpression; + } + private static ConnectorConfiguration buildSecureConnectorConfiguration(String configDirStr, HashMap<String, String> serverProperties) {
SSLConfiguration ssl = new SSLConfiguration();
// truststore - ssl.setCaCertificateFile(getAbsoluteFileLocation("rhq.server.tomcat.security.truststore.file", - serverProperties, configDirStr)); // this cannot be an expression - AS7 doesn't support that now + ssl.setCaCertificateFile(buildExpression("rhq.server.tomcat.security.truststore.file", serverProperties, true)); ssl.setCaCertificationPassword(buildExpression("rhq.server.tomcat.security.truststore.password", - serverProperties, false)); - ssl.setTruststoreType(buildExpression("rhq.server.tomcat.security.truststore.type", serverProperties, false)); + serverProperties, true)); + ssl.setTruststoreType(buildExpression("rhq.server.tomcat.security.truststore.type", serverProperties, true));
// keystore - ssl.setCertificateKeyFile(getAbsoluteFileLocation("rhq.server.tomcat.security.keystore.file", serverProperties, - configDirStr)); // this cannot be an expression - AS7 doesn't support that now - ssl.setPassword(buildExpression("rhq.server.tomcat.security.keystore.password", serverProperties, false)); - ssl.setKeyAlias(buildExpression("rhq.server.tomcat.security.keystore.alias", serverProperties, false)); - ssl.setKeystoreType(buildExpression("rhq.server.tomcat.security.keystore.type", serverProperties, false)); + ssl.setCertificateKeyFile(buildExpression("rhq.server.tomcat.security.keystore.file", serverProperties, true)); + ssl.setPassword(buildExpression("rhq.server.tomcat.security.keystore.password", serverProperties, true)); + ssl.setKeyAlias(buildExpression("rhq.server.tomcat.security.keystore.alias", serverProperties, true)); + ssl.setKeystoreType(buildExpression("rhq.server.tomcat.security.keystore.type", serverProperties, true));
// SSL protocol config - ssl.setProtocol(buildExpression("rhq.server.tomcat.security.secure-socket-protocol", serverProperties, false)); - ssl.setVerifyClient(buildExpression("rhq.server.tomcat.security.client-auth-mode", serverProperties, false)); + ssl.setProtocol(buildExpression("rhq.server.tomcat.security.secure-socket-protocol", serverProperties, true)); + ssl.setVerifyClient(buildExpression("rhq.server.tomcat.security.client-auth-mode", serverProperties, true));
// note: there doesn't appear to be a way for AS7 to support algorithm, like SunX509 or IbmX509 // so I think it just uses the JVM's default. This means "rhq.server.tomcat.security.algorithm" is unused
ConnectorConfiguration connector = new ConnectorConfiguration(); - connector.setMaxConnections(buildExpression("rhq.server.startup.web.max-connections", serverProperties, false)); + connector.setMaxConnections(buildExpression("rhq.server.startup.web.max-connections", serverProperties, true)); connector.setScheme("https"); connector.setSocketBinding("https"); connector.setSslConfiguration(ssl); @@ -1502,159 +1519,4 @@ public class ServerInstallUtil { } } } - - /** - * This checks to see if the logging settings have the same values as those found in the given properties. - * - * THIS IS ONLY HERE TO SUPPORT INSTALLER --reconfig OPTION WHICH SHOULD - * GO AWAY ONCE AS7 SUPPORTS EXPRESSIONS WHERE WE NEED THEM - JIRA AS7-5321. - * ONCE AS7 DOES THIS, THIS METHOD CAN GO AWAY. - * - * @param mcc the JBossAS management client - * @param serverProperties contains the logging settings - * @return true if the logging settings have the same values - * @throws Exception - */ - public static boolean isSameLoggingExisting(ModelControllerClient mcc, HashMap<String, String> serverProperties) { - try { - LoggingJBossASClient client = new LoggingJBossASClient(mcc); - String currentLevel = client.getLoggerLevel("org.rhq"); - String newLevel = serverProperties.get(ServerProperties.PROP_LOG_LEVEL); - return !isEmpty(currentLevel) && currentLevel.equalsIgnoreCase(newLevel); - } catch (Exception e) { - return false; // assume they aren't the same - this may be due to the category org.rhq just missing - } - } - - /** - * This checks to see if the mail service already exists - * and has the same settings as those found in the given properties. - * - * THIS IS ONLY HERE TO SUPPORT INSTALLER --reconfig OPTION WHICH SHOULD - * GO AWAY ONCE AS7 SUPPORTS EXPRESSIONS WHERE WE NEED THEM - JIRA AS7-5321. - * ONCE AS7 DOES THIS, THIS METHOD CAN GO AWAY. - * - * @param mcc the JBossAS management client - * @param serverProperties contains the mail service settings - * @return true if the mail service exists with the same settings - * @throws Exception - */ - public static boolean isSameMailServiceExisting(ModelControllerClient mcc, HashMap<String, String> serverProperties) - throws Exception { - // we know the only problem attribute we care about is the smtp host - that's the only - // one we use that doesn't support expressions. So we only need to check this one - Address addr = Address.root().add("socket-binding-group", "standard-sockets", - "remote-destination-outbound-socket-binding", "mail-smtp"); - JBossASClient client = new JBossASClient(mcc); - String currentHost = client.getStringAttribute("host", addr); - String host = serverProperties.get(ServerProperties.PROP_EMAIL_SMTP_HOST); - return !isEmpty(currentHost) && currentHost.equals(host); - } - - /** - * This checks to see if the security domain for the datasources already exists - * and has the same username/password as those found in the given properties - * - * THIS IS ONLY HERE TO SUPPORT INSTALLER --reconfig OPTION WHICH SHOULD - * GO AWAY ONCE AS7 SUPPORTS EXPRESSIONS WHERE WE NEED THEM - JIRA AS7-5321. - * ONCE AS7 DOES THIS, THIS METHOD CAN GO AWAY. - * - * @param mcc the JBossAS management client - * @param serverProperties contains the obfuscated password and username to compare - * @return true if the domain exists with the same username and password - * @throws Exception - */ - public static boolean isSameDatasourceSecurityDomainExisting(ModelControllerClient mcc, - HashMap<String, String> serverProperties) throws Exception { - - final String dbUsername = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME); - final String obfuscatedPassword = serverProperties.get(ServerProperties.PROP_DATABASE_PASSWORD); - final SecurityDomainJBossASClient client = new SecurityDomainJBossASClient(mcc); - final String securityDomain = RHQ_DS_SECURITY_DOMAIN; - boolean sameUsernamePassword = false; - if (client.isSecurityDomain(securityDomain)) { - boolean sameUsername = false; - boolean samePassword = false; - ModelNode opts; - opts = client.getSecureIdentitySecurityDomainModuleOptions(securityDomain); - if (opts != null) { - List<ModelNode> optsList = opts.asList(); - for (ModelNode opt : optsList) { - if (opt.has(SecurityDomainJBossASClient.USERNAME)) { - sameUsername = dbUsername.equals(opt.get(SecurityDomainJBossASClient.USERNAME).asString()); - } - if (opt.has(SecurityDomainJBossASClient.PASSWORD)) { - samePassword = obfuscatedPassword.equals(opt.get(SecurityDomainJBossASClient.PASSWORD) - .asString()); - } - } - } - sameUsernamePassword = sameUsername & samePassword; - } - return sameUsernamePassword; - } - - /** - * This checks to see if the web connectors already exist - * and have the same settings as those found in the given properties - * - * THIS IS ONLY HERE TO SUPPORT INSTALLER --reconfig OPTION WHICH SHOULD - * GO AWAY ONCE AS7 SUPPORTS EXPRESSIONS WHERE WE NEED THEM - JIRA AS7-5321. - * ONCE AS7 DOES THIS, THIS METHOD CAN GO AWAY. - * - * @param mcc the JBossAS management client - * @param configDirStr location of a configuration directory where the keystore is to be stored - * @param serverProperties contains the obfuscated password and username to compare - * @return true if the domain exists with the same username and password - * @throws Exception - */ - public static boolean isSameWebConnectorsExisting(ModelControllerClient mcc, String appServerConfigDir, - HashMap<String, String> serverProperties) throws Exception { - - HashMap<String, String> settingsToCheck = new HashMap<String, String>(); - WebJBossASClient client = new WebJBossASClient(mcc); - - // FIRST check the https connector - ModelNode httpsNode = client.getConnector("https"); - - ConnectorConfiguration connectorConfig = buildSecureConnectorConfiguration(appServerConfigDir, serverProperties); - SSLConfiguration sslConfig = connectorConfig.getSslConfiguration(); - - // check the https connector's main config - settingsToCheck.clear(); - settingsToCheck.put("max-connections", connectorConfig.getMaxConnections()); - for (Map.Entry<String, String> propToCheck : settingsToCheck.entrySet()) { - if (!httpsNode.get(propToCheck.getKey()).asString().equals(propToCheck.getValue())) { - return false; // something is different, no need to check further, return false to say we are different - } - } - - // now check the https connector's ssl config - ModelNode sslNode = httpsNode.get("ssl").get("configuration"); - settingsToCheck.clear(); - settingsToCheck.put("ca-certificate-file", sslConfig.getCaCertificateFile()); - settingsToCheck.put("ca-certificate-password", sslConfig.getCaCertificatePassword()); - settingsToCheck.put("certificate-key-file", sslConfig.getCertificateKeyFile()); - settingsToCheck.put("key-alias", sslConfig.getKeyAlias()); - settingsToCheck.put("keystore-type", sslConfig.getKeystoreType()); - settingsToCheck.put("password", sslConfig.getPassword()); - settingsToCheck.put("protocol", sslConfig.getProtocol()); - settingsToCheck.put("truststore-type", sslConfig.getTruststoreType()); - settingsToCheck.put("verify-client", sslConfig.getVerifyClient()); - for (Map.Entry<String, String> propToCheck : settingsToCheck.entrySet()) { - if (!sslNode.get(propToCheck.getKey()).asString().equals(propToCheck.getValue())) { - return false; // something is different, no need to check further, return false to say we are different - } - } - - // SECOND check the http connector - ModelNode httpNode = client.getConnector("http"); - String nodeString = httpNode.get("redirect-port").asString(); - String propString = serverProperties.get("rhq.server.socket.binding.port.https"); - if (!nodeString.equals(propString)) { - return false; // something is different, no need to check further, return false to say we are different - } - - return true; - } }
commit c430d28ff07adb87cccc8823a3b24d598867c462 Author: Mike Thompson mithomps@redhat.com Date: Tue Apr 30 14:47:27 2013 -0700
[BZ 950701] Fix SVG text fonts in d3 graphs so that they dont look fuzzy.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java index 2693772..d9a4205 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/charttype/StackedBarMetricGraphImpl.java @@ -31,13 +31,6 @@ public class StackedBarMetricGraphImpl extends AbstractGraph { public StackedBarMetricGraphImpl() { super(); } - /** - * General constructor for stacked bar graph when you have all the data needed to produce the graph. (This is true - * for all cases but the dashboard portlet). - */ -// public StackedBarMetricGraphImpl(MetricGraphData metricGraphData) { -// setMetricGraphData(metricGraphData); -// }
/** diff --git a/modules/enterprise/gui/coregui/src/main/webapp/css/charts.css b/modules/enterprise/gui/coregui/src/main/webapp/css/charts.css index 099f23a..8728026 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/css/charts.css +++ b/modules/enterprise/gui/coregui/src/main/webapp/css/charts.css @@ -27,11 +27,11 @@ }
.y.axis text, .x.axis text { - font-family: 'Liberation Sans', Arial, Helvetica, sans-serif; + font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-weight: normal; font-style: normal; - stroke: #50505a; + fill: #50505a; text-rendering: optimize-legibility;
} @@ -47,8 +47,8 @@ .minLabel, .avgLabel, .highLabel { font-family: Arial, Verdana, sans-serif; font-size: 12px; + font-weight: bold; text-anchor: start; - stroke: #003168; fill: #003168; text-rendering: optimize-legibility; } @@ -57,7 +57,6 @@ font-family: Arial, Verdana, sans-serif; font-size: 12px; text-anchor: start; - stroke: #003168; fill: #003168; text-rendering: optimize-legibility; }
commit 813c49855969171406f638a9d32112b722b99d19 Author: Mike Thompson mithomps@redhat.com Date: Tue Apr 30 13:37:35 2013 -0700
[BZ 955760] Syntax fix for gzip compression enablement.
diff --git a/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh b/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh index 29a6d76..4e90c62 100755 --- a/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh +++ b/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh @@ -348,7 +348,7 @@ fi
# Add the JVM opts that we always want to specify, whether or not the user set RHQ_SERVER_JAVA_OPTS. # Note that the double equals for the policy file specification IS INTENTIONAL -_HTTP_COMPRESSION="-Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION=on org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES=text/javascript,text/css,text/html" +_HTTP_COMPRESSION="-Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION=on -Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES=text/javascript,text/css,text/html" RHQ_SERVER_JAVA_OPTS="-Dapp.name=rhq-server ${RHQ_SERVER_JAVA_OPTS} -Drhq.server.home=${RHQ_SERVER_HOME} -Djboss.server.log.dir=${_LOG_DIR_PATH} -Djava.awt.headless=true -Dsun.lang.ClassLoader.allowArraySyntax=true -Djboss.server.default.config=standalone-full.xml -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.security.manager -Djava.security.policy==${RHQ_SERVER_HOME}/bin/rhq-server.security-policy ${_HTTP_COMPRESSION} ${_JBOSS_DEBUG_LOGGING}"
debug_msg "RHQ_SERVER_JAVA_OPTS: $RHQ_SERVER_JAVA_OPTS"
commit 8c54ef01abaa6790f49f96c492fe6649a0245a6f Author: Mike Thompson mithomps@redhat.com Date: Tue Apr 30 09:06:23 2013 -0700
Move jquery(1.7.2) library out of CoreGUI.gwt.xml now that we don't have GFlot dependency (GFlot was removed with addition of d3 charts).
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 3d5ae84..7d50e87 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,14 +46,6 @@ <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/> </generate-with>
- <!-- 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 2.4.2 requires - the version of jquery (1.7.2). - --> - <script src="/coregui/js/jquery-1.7.2.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 8722614..1b69b53 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html +++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html @@ -15,10 +15,12 @@ <link rel="stylesheet" href="css/tipsy.css"> <link rel="stylesheet" href="css/charts.css">
- <script defer="defer" type="text/javascript" src="/coregui/js/jquery.sparkline-2.1.min.js"></script> <script defer="defer" type="text/javascript" src="/coregui/js/rhq.js"></script> <script defer="defer" type="text/javascript" src="/coregui/js/d3.v3.js"></script> <script defer="defer" type="text/javascript" src="/coregui/js/nv.d3.js"></script> + <!-- jquery dependent js libs --> + <script defer="defer" type="text/javascript" src="/coregui/js/jquery-1.7.2.min.js"></script> + <script defer="defer" type="text/javascript" src="/coregui/js/jquery.sparkline-2.1.min.js"></script> <script defer="defer" type="text/javascript" src="/coregui/js/jquery.tipsy.js"></script>
<script type="text/javascript">
commit bcda4cd317f159f335aa544604ed9a0b0b3842a8 Author: John Mazzitelli mazz@redhat.com Date: Tue Apr 30 15:41:46 2013 -0400
BZ 955760 - pass in the http compression sysprops to the RHQ Server at startup
diff --git a/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh b/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh index 42c8e45..29a6d76 100755 --- a/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh +++ b/modules/enterprise/server/appserver/src/main/bin-resources/bin/rhq-server.sh @@ -348,7 +348,8 @@ fi
# Add the JVM opts that we always want to specify, whether or not the user set RHQ_SERVER_JAVA_OPTS. # Note that the double equals for the policy file specification IS INTENTIONAL -RHQ_SERVER_JAVA_OPTS="-Dapp.name=rhq-server ${RHQ_SERVER_JAVA_OPTS} -Drhq.server.home=${RHQ_SERVER_HOME} -Djboss.server.log.dir=${_LOG_DIR_PATH} -Djava.awt.headless=true -Dsun.lang.ClassLoader.allowArraySyntax=true -Djboss.server.default.config=standalone-full.xml -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.security.manager -Djava.security.policy==${RHQ_SERVER_HOME}/bin/rhq-server.security-policy ${_JBOSS_DEBUG_LOGGING}" +_HTTP_COMPRESSION="-Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION=on org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES=text/javascript,text/css,text/html" +RHQ_SERVER_JAVA_OPTS="-Dapp.name=rhq-server ${RHQ_SERVER_JAVA_OPTS} -Drhq.server.home=${RHQ_SERVER_HOME} -Djboss.server.log.dir=${_LOG_DIR_PATH} -Djava.awt.headless=true -Dsun.lang.ClassLoader.allowArraySyntax=true -Djboss.server.default.config=standalone-full.xml -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.security.manager -Djava.security.policy==${RHQ_SERVER_HOME}/bin/rhq-server.security-policy ${_HTTP_COMPRESSION} ${_JBOSS_DEBUG_LOGGING}"
debug_msg "RHQ_SERVER_JAVA_OPTS: $RHQ_SERVER_JAVA_OPTS" debug_msg "RHQ_SERVER_ADDITIONAL_JAVA_OPTS: $RHQ_SERVER_ADDITIONAL_JAVA_OPTS" diff --git a/modules/enterprise/server/appserver/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf b/modules/enterprise/server/appserver/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf index 3780f90..c5afd1b 100644 --- a/modules/enterprise/server/appserver/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf +++ b/modules/enterprise/server/appserver/src/main/bin-resources/bin/wrapper/rhq-server-wrapper.conf @@ -82,11 +82,14 @@ wrapper.java.additional.18=-Dsun.lang.ClassLoader.allowArraySyntax=true wrapper.java.additional.19=-Djava.security.manager # the double equals for the policy file specification IS INTENTIONAL wrapper.java.additional.20="-Djava.security.policy==%RHQ_SERVER_HOME%/bin/rhq-server.security-policy" +wrapper.java.additional.21="-Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION=on" +wrapper.java.additional.22="-Dorg.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES=text/javascript,text/css,text/html" + # use these if your JVM supports it -#wrapper.java.additional.21=-XX:+TieredCompilation -#wrapper.java.additional.22=-XX:+UseCompressedOops +#wrapper.java.additional.23=-XX:+TieredCompilation +#wrapper.java.additional.24=-XX:+UseCompressedOops # Don't need these now, but this is commented out in case we need to add an endorsed dir in the future -#wrapper.java.additional.23="-Djava.endorsed.dirs=%RHQ_SERVER_HOME%/jbossas/lib/endorsed" +#wrapper.java.additional.25="-Djava.endorsed.dirs=%RHQ_SERVER_HOME%/jbossas/lib/endorsed"
# We want to make sure the Server starts in the JBossAS bin directory wrapper.working.dir=%RHQ_SERVER_HOME%/jbossas/bin diff --git a/modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc b/modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc index b76cd2f..8094241 100644 --- a/modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc +++ b/modules/enterprise/server/appserver/src/main/dev-resources/bin/wrapper/rhq-server-wrapper.inc @@ -4,12 +4,12 @@ #
# enable remote debugging -wrapper.java.additional.9=-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n +wrapper.java.additional.23=-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n
# enable jprofiler #set.PATH=%PATH%;<jprofiler-install-dir>\bin\windows -#wrapper.java.additional.10=-agentlib:jprofilerti=port=8849 -#wrapper.java.additional.11=-Xbootclasspath/a:<jprofiler-install-dir>\bin\agent.jar +#wrapper.java.additional.23=-agentlib:jprofilerti=port=8849 +#wrapper.java.additional.24=-Xbootclasspath/a:<jprofiler-install-dir>\bin\agent.jar
# disable JVM startup timeout wrapper.startup.timeout=0
commit 9a4c406425741f4dc3ecc546c27aec5d558fa37b Author: John Mazzitelli mazz@redhat.com Date: Tue Apr 30 14:25:36 2013 -0400
BZ 917085 fix test to hopefully run on windows
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 f0605a2..76742e8 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 @@ -530,8 +530,21 @@ public class AntBundlePluginComponentTest { assert winDirs.size() == 1 : "should only have 1 ext backup dir on windows: " + winDirs; backupDir = winDirs.values().iterator().next().getAbsoluteFile(); } - File file3Backup = new File(backupDir, file3Dest.getAbsolutePath()); - File file4Backup = new File(backupDir, file4Dest.getAbsolutePath()); + + File file3Backup; + File file4Backup; + boolean isWindows = (File.separatorChar == '\'); + if (isWindows) { + StringBuilder file3AbsPath = new StringBuilder(file3Dest.getAbsolutePath()); + StringBuilder file4AbsPath = new StringBuilder(file4Dest.getAbsolutePath()); + FileUtil.stripDriveLetter(file3AbsPath); + FileUtil.stripDriveLetter(file4AbsPath); + file3Backup = new File(backupDir, file3AbsPath.toString()); + file4Backup = new File(backupDir, file4AbsPath.toString()); + } else { + file3Backup = new File(backupDir, file3Dest.getAbsolutePath()); + file4Backup = new File(backupDir, file4Dest.getAbsolutePath()); + } assert file3Backup.isFile() : "should have been backed up: " + file3Backup; assert file4Backup.isFile() : "should have been backed up: " + file4Backup; assert (TEST3 + "modified").equals(readFile(file3Backup)) : "bad backup file: " + file3Backup;
commit 03caa3d61d59d2e041750b0581a31098acf61f10 Author: John Mazzitelli mazz@redhat.com Date: Tue Apr 30 09:47:25 2013 -0400
these methods' @TranAttrib annotations are unused. Also, spoke to lukas, he said these methods should be made private
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java index bfe9f32..6689de5 100644 --- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java +++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java @@ -21,8 +21,6 @@ package org.rhq.enterprise.server.test;
import javax.ejb.Singleton; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType;
import org.rhq.enterprise.server.core.StartupBean; import org.rhq.enterprise.server.naming.NamingHack; @@ -34,8 +32,7 @@ import org.rhq.enterprise.server.naming.NamingHack; @Singleton public class StrippedDownStartupBean {
- @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) - public void secureNaming() { + private void secureNaming() { NamingHack.bruteForceInitialContextFactoryBuilder(); }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java index 5b5aa8c..90ffbaf 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/StartupBean.java @@ -146,11 +146,8 @@ public class StartupBean implements StartupLocal {
/** * Modifies the naming subsystem to be able to check for Java security permissions on JNDI lookup. - * <p> - * Made public so that this can be reused in tests. */ - @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) - public void secureNaming() { + private void secureNaming() { NamingHack.bruteForceInitialContextFactoryBuilder(); }
rhq-commits@lists.fedorahosted.org