.classpath
| 1
modules/core/dbutils/pom.xml
| 2
modules/core/dbutils/src/main/scripts/dbsetup-build.xml
| 2
modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
| 25
modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
| 23
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
| 51 ++
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
| 142 +++++
modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
| 2
modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
| 253 ++++++++++
modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
| 38 +
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
| 2
modules/enterprise/server/jar/pom.xml
| 47 +
modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
| 181 +++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
| 1
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
| 66 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
| 120 ++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
| 31 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
| 119 ++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
| 17
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
| 6
modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
| 126 ++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
| 171 ++++++
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
| 12
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
| 8
modules/plugins/grub/src/main/java/org/rhq/plugins/grub/GrubDiscoveryComponent.java
| 5
modules/plugins/grub/src/main/resources/META-INF/rhq-plugin.xml
| 3
modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISServerDiscoveryComponent.java
| 2
modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISVHostDiscoveryComponent.java
| 2
modules/plugins/jira/src/main/java/org/rhq/plugins/jira/JiraServerDiscoveryComponent.java
| 2
modules/plugins/oracle/src/main/java/org/rhq/plugins/oracle/OracleDiscoveryComponent.java
| 2
modules/plugins/oracle/src/main/resources/META-INF/rhq-plugin.xml
| 2
modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemDiscoveryComponent.java
| 5
modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDatabaseDiscoveryComponent.java
| 2
modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDiscoveryComponent.java
| 76 ++-
modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresUserDiscoveryComponent.java
| 2
modules/plugins/rhq-agent/src/main/java/org/rhq/plugins/agent/AgentDiscoveryComponent.java
| 3
modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
| 3
modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
| 12
modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java
| 2
modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java
| 10
modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationBlockDeviceDiscoveryComponent.java
| 2
modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationInterfaceDiscoveryComponent.java
| 2
42 files changed, 1501 insertions(+), 82 deletions(-)
New commits:
commit 71e2d920463a909506ffee19dfa73c26f074578a
Merge: 308b9d3... 6445fb2...
Author: Partha Aji <paji(a)redhat.com>
Date: Mon Mar 1 09:49:24 2010 -0500
Merge branch 'linux-config' into ldap
commit 6445fb2b8895d354c5621ff8a5c9fa26f1189672
Merge: 589df77... 6278e70...
Author: Partha Aji <paji(a)redhat.com>
Date: Mon Mar 1 09:49:07 2010 -0500
Merge branch 'master' into linux-config
commit 308b9d3b2caa2f344368d713551c12f879448171
Author: Partha Aji <paji(a)redhat.com>
Date: Mon Mar 1 09:48:27 2010 -0500
whateve
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
index 029a2b9..ad8ae65 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
@@ -47,6 +47,7 @@ public class AuthorizationManagerBean implements
AuthorizationManagerLocal {
@SuppressWarnings("unchecked")
public Set<Permission> getExplicitGlobalPermissions(Subject subject) {
+ entityManager.flush();
Query query =
entityManager.createNamedQuery(Subject.QUERY_GET_GLOBAL_PERMISSIONS);
query.setParameter("subject", subject);
List<Permission> results = query.getResultList();
commit 589df77934ed96b0361db10481a2dc61d4424c16
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 26 18:14:49 2010 +0100
Postgres plugin resources renamed.
diff --git
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDatabaseDiscoveryComponent.java
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDatabaseDiscoveryComponent.java
index 060ee03..5236fd3 100644
---
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDatabaseDiscoveryComponent.java
+++
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDatabaseDiscoveryComponent.java
@@ -45,7 +45,7 @@ public class PostgresDatabaseDiscoveryComponent implements
ResourceDiscoveryComp
while (resultSet.next()) {
String databaseName = resultSet.getString("datname");
DiscoveredResourceDetails database = new
DiscoveredResourceDetails(context.getResourceType(),
- databaseName, databaseName + " Database", null, "The
" + databaseName
+ databaseName, databaseName, null, "The " + databaseName
+ " Postgres Database Instance", null, null);
database.getPluginConfiguration().put(new
PropertySimple("databaseName", databaseName));
databases.add(database);
diff --git
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDiscoveryComponent.java
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDiscoveryComponent.java
index 5e0a83d..825a4a3 100644
---
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDiscoveryComponent.java
+++
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresDiscoveryComponent.java
@@ -26,14 +26,19 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.pluginapi.inventory.*;
import org.rhq.core.system.ProcessInfo;
+import org.rhq.core.util.jdbc.JDBCUtil;
import org.rhq.plugins.postgres.util.PostgresqlConfFile;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -56,6 +61,8 @@ public class PostgresDiscoveryComponent implements
ResourceDiscoveryComponent, M
private static final String PGDATA_ENV_VAR = "PGDATA";
private static final String DEFAULT_RESOURCE_DESCRIPTION = "Postgres relational
database server";
+ private static final String POSTGRES_DEFAULT_DATABASE_NAME = "postgres";
+
public Set<DiscoveredResourceDetails>
discoverResources(ResourceDiscoveryContext context) {
Set<DiscoveredResourceDetails> servers = new
LinkedHashSet<DiscoveredResourceDetails>();
@@ -140,9 +147,10 @@ public class PostgresDiscoveryComponent implements
ResourceDiscoveryComponent, M
Configuration
pluginConfiguration, @Nullable
ProcessInfo processInfo) {
String key = buildUrl(pluginConfiguration);
- String db =
pluginConfiguration.getSimple(DB_CONFIGURATION_PROPERTY).getStringValue();
- String name = "Postgres [" + db + "]";
- String version = getVersion(pluginConfiguration);
+ Connection conn = getConnection(pluginConfiguration);
+ String name = getServerResourceName(pluginConfiguration, conn);
+ String version = getVersion(pluginConfiguration, conn);
+ JDBCUtil.safeClose(conn);
return new DiscoveredResourceDetails(discoveryContext.getResourceType(), key,
name, version,
DEFAULT_RESOURCE_DESCRIPTION, pluginConfiguration, processInfo);
}
@@ -155,11 +163,12 @@ public class PostgresDiscoveryComponent implements
ResourceDiscoveryComponent, M
return url;
}
- protected static String getVersion(Configuration config) {
+ protected static String getVersion(Configuration config, Connection conn) {
String version = null;
try {
- Connection conn = buildConnection(config);
- version = conn.getMetaData().getDatabaseProductVersion();
+ if (conn != null) {
+ version = conn.getMetaData().getDatabaseProductVersion();
+ }
} catch (SQLException e) {
// TODO GH: How to put this back to the server while inventorying this
resource in an unconfigured state
log.info("Exception detecting postgres instance", e);
@@ -182,7 +191,12 @@ public class PostgresDiscoveryComponent implements
ResourceDiscoveryComponent, M
String principal =
configuration.getSimple(PRINCIPAL_CONFIGURATION_PROPERTY).getStringValue();
String credentials =
configuration.getSimple(CREDENTIALS_CONFIGURATION_PROPERTY).getStringValue();
- return DriverManager.getConnection(url, principal, credentials);
+ try {
+ return DriverManager.getConnection(url, principal, credentials);
+ } catch (SQLException e) {
+ log.info("Failed to connect to the database", e);
+ return null;
+ }
}
@Nullable
@@ -239,4 +253,52 @@ public class PostgresDiscoveryComponent implements
ResourceDiscoveryComponent, M
return configFilePath;
}
+
+ private static Connection getConnection(Configuration config) {
+ try {
+ return buildConnection(config);
+ } catch (SQLException e) {
+ log.info("Failed to connect to postgres database.", e);
+
+ return null;
+ }
+ }
+
+ public static List<String> getDatabases(Configuration pluginConfiguration) {
+ return getDatabaseNames(pluginConfiguration,
getConnection(pluginConfiguration));
+ }
+
+ private static List<String> getDatabaseNames(Configuration config, Connection
conn) {
+ Statement statement = null;
+ ResultSet resultSet = null;
+ try {
+ List<String> ret = new ArrayList<String>();
+
+ statement = conn.createStatement();
+ resultSet = statement
+ .executeQuery("SELECT *, pg_database_size(datname) FROM pg_database
where datistemplate = false");
+ while (resultSet.next()) {
+ String databaseName = resultSet.getString("datname");
+ ret.add(databaseName);
+ }
+
+ return ret;
+ } catch (SQLException e) {
+ log.info("Failed to obtain the list of databases in a postgres
instance", e);
+ return Collections.emptyList();
+ } finally {
+ JDBCUtil.safeClose(statement, resultSet);
+ }
+ }
+
+ private static String getServerResourceName(Configuration config, Connection conn) {
+ List<String> schemas = getDatabaseNames(config, conn);
+ if (schemas.size() > 0 && schemas.size() < 3) {
+ String firstDatabase = schemas.get(0);
+ String secondDatabase = schemas.get(1);
+ return POSTGRES_DEFAULT_DATABASE_NAME.equals(firstDatabase) ? secondDatabase
: firstDatabase;
+ } else {
+ return config.getSimpleValue(DB_CONFIGURATION_PROPERTY,
POSTGRES_DEFAULT_DATABASE_NAME);
+ }
+ }
}
\ No newline at end of file
diff --git
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresUserDiscoveryComponent.java
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresUserDiscoveryComponent.java
index a48deb1..c0d0273 100644
---
a/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresUserDiscoveryComponent.java
+++
b/modules/plugins/postgres/src/main/java/org/rhq/plugins/postgres/PostgresUserDiscoveryComponent.java
@@ -61,7 +61,7 @@ public class PostgresUserDiscoveryComponent implements
ResourceDiscoveryComponen
while (resultSet.next()) {
String userName = resultSet.getString("rolname");
DiscoveredResourceDetails service = new
DiscoveredResourceDetails(context.getResourceType(), userName,
- userName + " User", null, "A Postgres user",
null, null);
+ userName, null, "A Postgres user", null, null);
service.getPluginConfiguration().put(new
PropertySimple("userName", userName));
discoveredUsers.add(service);
}
commit 6602a4542a782cec37f434b97cfe6089277e0eae
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Feb 25 09:39:07 2010 +0100
IIS plugin resources renamed.
diff --git
a/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISServerDiscoveryComponent.java
b/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISServerDiscoveryComponent.java
index 50b9448..f4cbceb 100644
---
a/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISServerDiscoveryComponent.java
+++
b/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISServerDiscoveryComponent.java
@@ -78,7 +78,7 @@ public class IISServerDiscoveryComponent implements
ResourceDiscoveryComponent {
Configuration pluginConfig = discoveryContext.getDefaultPluginConfiguration();
DiscoveredResourceDetails details = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
- imagePath, discoveryContext.getSystemInformation().getHostname() + " IIS
Server", version, "IIS Server on "
+ imagePath, "IIS", version, "IIS Server on "
+ discoveryContext.getSystemInformation().getHostname(), pluginConfig,
null);
return Collections.singleton(details);
diff --git
a/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISVHostDiscoveryComponent.java
b/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISVHostDiscoveryComponent.java
index 9ea5aa9..a6fc8a1 100644
---
a/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISVHostDiscoveryComponent.java
+++
b/modules/plugins/iis/src/main/java/org/rhq/plugins/iis/IISVHostDiscoveryComponent.java
@@ -86,7 +86,7 @@ public class IISVHostDiscoveryComponent implements
ResourceDiscoveryComponent<II
config.put(new PropertySimple("logDirectory",
"C:\\Windows\\System32\\LogFiles\\W3SVC" + info.getId()));
DiscoveredResourceDetails details = new
DiscoveredResourceDetails(resourceDiscoveryContext
- .getResourceType(), siteName, siteName + " VHost",
"1.0", siteName + " Virtual Host", config, null);
+ .getResourceType(), siteName, siteName, "1.0", siteName +
" Virtual Host", config, null);
hostDetails.add(details);
}
commit bc19e61c3b7fc42f1aec1dc603ed6c637f3d7b79
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 18:34:18 2010 +0100
Virt plugin resources renamed.
diff --git
a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationBlockDeviceDiscoveryComponent.java
b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationBlockDeviceDiscoveryComponent.java
index fe7b2ce..98f1979 100644
---
a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationBlockDeviceDiscoveryComponent.java
+++
b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationBlockDeviceDiscoveryComponent.java
@@ -49,7 +49,7 @@ public class VirtualizationBlockDeviceDiscoveryComponent implements
ResourceDisc
String device =
intf.getSimple("targetDevice").getStringValue();
DiscoveredResourceDetails detail = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
- device, device + " virtual device", null, "Virtual
block device", null, null);
+ device, device, null, "Virtual block device", null, null);
details.add(detail);
}
}
diff --git
a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationInterfaceDiscoveryComponent.java
b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationInterfaceDiscoveryComponent.java
index 7829c9f..7d769d6 100644
---
a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationInterfaceDiscoveryComponent.java
+++
b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationInterfaceDiscoveryComponent.java
@@ -49,7 +49,7 @@ public class VirtualizationInterfaceDiscoveryComponent implements
ResourceDiscov
String path = intf.getSimple("target").getStringValue();
DiscoveredResourceDetails detail = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
- path, path + " virtual interface", null, "Virtual
network interface", null, null);
+ path, path, null, "Virtual network interface", null,
null);
details.add(detail);
}
}
commit 51cd46a911b27118e02ccc589dda2952c17af66a
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 11:19:36 2010 +0100
Snmptrapd plugin resources renamed.
diff --git
a/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java
b/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java
index ec741a4..aab6d6e 100644
---
a/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java
+++
b/modules/plugins/snmptrapd/src/main/java/org/rhq/plugins/snmptrapd/SnmpTrapdDiscovery.java
@@ -37,6 +37,8 @@ import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
*/
public class SnmpTrapdDiscovery implements
ResourceDiscoveryComponent<SnmpTrapdComponent>,
ManualAddFacet<SnmpTrapdComponent> {
+ private static final String PORT_PROPERTY = "port";
+
/*
* Autodiscovery is not supported.
*/
@@ -52,11 +54,11 @@ public class SnmpTrapdDiscovery implements
ResourceDiscoveryComponent<SnmpTrapdC
*/
public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration,
ResourceDiscoveryContext<SnmpTrapdComponent> ctx) throws
InvalidPluginConfigurationException {
-
- String pcName = ctx.getPluginContainerName();
- String key = "Trapd (" + pcName + ")";
+
+ String port = pluginConfiguration.getSimpleValue(PORT_PROPERTY, null);
+ String key = "Trapd " + port;
String name = key;
- String description = "SNMP Trap receiver on " + pcName;
+ String description = "SNMP Trap receiver on port " + port;
ResourceType resourceType = ctx.getResourceType();
DiscoveredResourceDetails details = new DiscoveredResourceDetails(resourceType,
key, name, null, description,
pluginConfiguration, null);
commit 7e2477a7d75fe8ff2de499f3b1143022b3d8e385
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 17:50:48 2010 +0100
Script2 plugin resources renamed.
diff --git
a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java
b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java
index 25411ee..4847261 100644
---
a/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java
+++
b/modules/plugins/script2/src/main/java/org/rhq/modules/plugins/script2/ScriptDiscovery.java
@@ -47,7 +47,7 @@ public class ScriptDiscovery implements
ResourceDiscoveryComponent,ManualAddFace
DiscoveredResourceDetails detail = new DiscoveredResourceDetails(
context.getResourceType(), // ResourceType
key, // resource key
- "Script " + lang + "::" + script, // resource name
TODO get via configuration
+ script, // resource name TODO get via configuration
null, // version
lang + "Script " + script, // Description
pluginConfiguration, // Configuration
commit e167b466c5a2b32c64bc2b8afe83e1213eb12460
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 17:48:06 2010 +0100
RHQ Server plugin resources renamed.
diff --git a/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
index 3b0b5da..1cc0925 100644
--- a/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
@@ -19,7 +19,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq:service=AlertConditionCacheMonitor"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Alerts Engine Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Alert
Subsystem"/>
<c:simple-property name="descriptionTemplate"
default="Statistics for the RHQ Server Alerts Engine Subsystem."/>
</plugin-configuration>
@@ -88,7 +88,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq:service=MeasurementMonitor"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Measurement Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Measurement
Subsystem"/>
<c:simple-property name="descriptionTemplate"
default="Statistics for the RHQ Server Measurement Subsystem."/>
</plugin-configuration>
@@ -144,7 +144,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq:service=GroupDefinitionRecalculationThreadMonitor"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Group Definition / DynaGroups Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Group
Definition Subsystem"/>
<c:simple-property name="descriptionTemplate"
default="Statistics for the RHQ Server Group Definition / DynaGroups
Subsystem."/>
</plugin-configuration>
@@ -189,7 +189,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq:service=ServerCommunications"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Communications Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Communications
Subsystem"/>
<c:simple-property name="descriptionTemplate" default="Details
on communications with agents"/>
</plugin-configuration>
@@ -265,7 +265,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq.remoting:type=RemoteApiMetrics"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Remote API Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Remote API
Subsystem"/>
<c:simple-property name="descriptionTemplate" default="Details
on remote API communications with external clients, including the CLI"/>
</plugin-configuration>
@@ -309,7 +309,7 @@
<plugin-configuration>
<c:simple-property name="objectName" readOnly="true"
default="rhq.serverplugin:service=ServerPluginService"/>
- <c:simple-property name="nameTemplate" default="RHQ Server
Plugin Subsystem"/>
+ <c:simple-property name="nameTemplate" default="Plugin
Subsystem"/>
<c:simple-property name="descriptionTemplate" default="Details
on the server-side plugin container subsystem"/>
</plugin-configuration>
commit bdf73e8c82c4568ea9a52b678d0b67b82926ffde
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 17:44:00 2010 +0100
RHQ agent plugin resources renamed.
diff --git
a/modules/plugins/rhq-agent/src/main/java/org/rhq/plugins/agent/AgentDiscoveryComponent.java
b/modules/plugins/rhq-agent/src/main/java/org/rhq/plugins/agent/AgentDiscoveryComponent.java
index 9580b69..52d9ac2 100644
---
a/modules/plugins/rhq-agent/src/main/java/org/rhq/plugins/agent/AgentDiscoveryComponent.java
+++
b/modules/plugins/rhq-agent/src/main/java/org/rhq/plugins/agent/AgentDiscoveryComponent.java
@@ -65,8 +65,7 @@ public class AgentDiscoveryComponent implements
ResourceDiscoveryComponent {
try {
AgentManagementMBean mbean = getAgentManagementMBean();
- String agentName =
mbean.getAgentConfiguration().getProperty(AgentConfigurationConstants.NAME);
- String name = agentName + " RHQ Agent";
+ String name = "RHQ Agent";
String key = name; // our key IS our name - its unique since there is only
one per platform
String version = mbean.getVersion();
String description = "RHQ Management Agent";
diff --git a/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
index ab76cb6..45af5ba 100644
--- a/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
@@ -13,7 +13,8 @@
<server name="RHQ Agent"
discovery="AgentDiscoveryComponent"
class="AgentServerComponent"
- description="Management Agent">
+ description="Management Agent"
+ singleton="true">
<plugin-configuration>
<c:group name="event" displayName="Log Tracking">
commit f0ba96ddb125030a5ce73106e47b33fc03a11c9d
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 15:06:09 2010 +0100
Platforms plugin resources renamed.
diff --git
a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemDiscoveryComponent.java
b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemDiscoveryComponent.java
index dbd207f..b7960c2 100644
---
a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemDiscoveryComponent.java
+++
b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemDiscoveryComponent.java
@@ -63,10 +63,9 @@ public class FileSystemDiscoveryComponent implements
ResourceDiscoveryComponent<
}
Configuration pluginConfig =
discoveryContext.getDefaultPluginConfiguration();
try {
- String name = ((hostname == null) ? "" : (hostname + "
")) + " File System ("
- + fs.getFileSystem().getTypeName() + ") " +
fs.getMountPoint();
+ String key = fs.getMountPoint();
DiscoveredResourceDetails details = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
- fs.getMountPoint(), name, null, fs.getFileSystem().getDevName() +
": "
+ key, key, null, fs.getFileSystem().getDevName() + ": "
+ fs.getFileSystem().getDirName(), pluginConfig, null);
results.add(details);
} catch (Exception e) {
commit 0790ffbfc48e7e7dd9eb43a43510282861f1bbd0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 15:03:22 2010 +0100
Oracle plugin resources renamed.
diff --git
a/modules/plugins/oracle/src/main/java/org/rhq/plugins/oracle/OracleDiscoveryComponent.java
b/modules/plugins/oracle/src/main/java/org/rhq/plugins/oracle/OracleDiscoveryComponent.java
index 985058a..2340f0b 100644
---
a/modules/plugins/oracle/src/main/java/org/rhq/plugins/oracle/OracleDiscoveryComponent.java
+++
b/modules/plugins/oracle/src/main/java/org/rhq/plugins/oracle/OracleDiscoveryComponent.java
@@ -92,7 +92,7 @@ public class OracleDiscoveryComponent implements
ResourceDiscoveryComponent, Man
Configuration pluginConfig, String version, @Nullable
ProcessInfo processInfo) {
String key = pluginConfig.getSimpleValue("sid", "XE");
- String name = "Oracle (" + key + ")";
+ String name = key;
String description = "Oracle " + version + " (" + key +
")";
return new DiscoveredResourceDetails(discoveryContext.getResourceType(), key,
name, version, description,
pluginConfig, processInfo);
diff --git a/modules/plugins/oracle/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/oracle/src/main/resources/META-INF/rhq-plugin.xml
index 9478f12..11eb232 100644
--- a/modules/plugins/oracle/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/oracle/src/main/resources/META-INF/rhq-plugin.xml
@@ -580,7 +580,7 @@
<c:simple-property name="table"
default="DBA_USERS"/>
<c:simple-property name="metricQuery" default="SELECT *
FROM DBA_USERS"/>
<c:simple-property name="keyColumn"
default="username"/>
- <c:simple-property name="name" default="Oracle User -
{key}"/>
+ <c:simple-property name="name" default="{key}"/>
<c:simple-property name="description" default="Oracle
User"/>
</plugin-configuration>
commit 112fadec0620f71058ca4f422753b6d3fe67a28c
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 14:54:13 2010 +0100
Jira plugin resources renamed.
diff --git
a/modules/plugins/jira/src/main/java/org/rhq/plugins/jira/JiraServerDiscoveryComponent.java
b/modules/plugins/jira/src/main/java/org/rhq/plugins/jira/JiraServerDiscoveryComponent.java
index 1585ba0..7349dfc 100644
---
a/modules/plugins/jira/src/main/java/org/rhq/plugins/jira/JiraServerDiscoveryComponent.java
+++
b/modules/plugins/jira/src/main/java/org/rhq/plugins/jira/JiraServerDiscoveryComponent.java
@@ -50,7 +50,7 @@ public class JiraServerDiscoveryComponent implements
ResourceDiscoveryComponent,
new DiscoveredResourceDetails(
resourceDiscoveryContext.getResourceType(),
url,
- "Jira " + url,
+ url,
info.getVersion(),
info.getEdition(),
config,
commit 58b5f646641ffa0b2acb5ee117873f564b503deb
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 23 14:47:26 2010 +0100
Grub plugin resources renamed.
diff --git
a/modules/plugins/grub/src/main/java/org/rhq/plugins/grub/GrubDiscoveryComponent.java
b/modules/plugins/grub/src/main/java/org/rhq/plugins/grub/GrubDiscoveryComponent.java
index 53022f1..4233bab 100644
--- a/modules/plugins/grub/src/main/java/org/rhq/plugins/grub/GrubDiscoveryComponent.java
+++ b/modules/plugins/grub/src/main/java/org/rhq/plugins/grub/GrubDiscoveryComponent.java
@@ -21,6 +21,8 @@ package org.rhq.plugins.grub;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
+
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
@@ -38,8 +40,9 @@ public class GrubDiscoveryComponent implements
ResourceDiscoveryComponent {
File grubFile = new File("/etc/grub.conf");
if (grubFile.exists()) {
+ ResourceType resourceType = resourceDiscoveryContext.getResourceType();
DiscoveredResourceDetails resource =
- new DiscoveredResourceDetails(resourceDiscoveryContext.getResourceType(),
"grub", "GRUB Boot Loader",
+ new DiscoveredResourceDetails(resourceType, "grub",
resourceType.getName(),
"1.0", "GRUB configuration on the machine.",
null, null);
details.add(resource);
diff --git a/modules/plugins/grub/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/grub/src/main/resources/META-INF/rhq-plugin.xml
index bf4d069..b5f9ab8 100644
--- a/modules/plugins/grub/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/grub/src/main/resources/META-INF/rhq-plugin.xml
@@ -11,7 +11,8 @@
<server name="GRUB"
description="The GRUB boot loader"
discovery="GrubDiscoveryComponent"
- class="GrubComponent">
+ class="GrubComponent"
+ singleton="true">
<plugin-configuration>
<c:group name="augeas" displayName="Augeas Settings">
commit 881e397532a18850d9c9d01e6bea00816dd2b277
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Feb 16 13:40:10 2010 +0100
Slight updates to the apache resource names.
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index f19f2e3..b87b3d6 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -21,6 +21,7 @@ package org.rhq.plugins.apache;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
+import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -216,7 +217,15 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo)
throws Exception {
String httpdConf =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
- String name = httpdConf;
+ String serverUrl =
pluginConfig.getSimpleValue(ApacheServerComponent.PLUGIN_CONFIG_PROP_URL, null);
+ //use the server url if we could detect it, otherwise use something unique
+ String name;
+ if (serverUrl == null) {
+ name = httpdConf;
+ } else {
+ URI uri = new URI(serverUrl);
+ name = uri.getHost() + ":" + uri.getPort();
+ }
DiscoveredResourceDetails resourceDetails = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
httpdConf, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
index 024517f..ad8ab5e 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
@@ -251,7 +251,7 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
}
DiscoveredResourceDetails mainServer = new
DiscoveredResourceDetails(resourceType,
- ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY, "Main
Server", null, null,
+ ApacheVirtualHostServiceComponent.MAIN_SERVER_RESOURCE_KEY, "Main",
null, null,
mainServerPluginConfig, null);
discoveredResources.add(mainServer);
}
commit 29e014aca53d7d1ab417005f81a204069f1d9ae7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Feb 15 13:12:13 2010 +0100
apache renaming
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
index dae7df0..f19f2e3 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerDiscoveryComponent.java
@@ -216,8 +216,7 @@ public class ApacheServerDiscoveryComponent implements
ResourceDiscoveryComponen
Configuration pluginConfig, ProcessInfo processInfo, ApacheBinaryInfo binaryInfo)
throws Exception {
String httpdConf =
pluginConfig.getSimple(ApacheServerComponent.PLUGIN_CONFIG_PROP_HTTPD_CONF).getStringValue();
String version = binaryInfo.getVersion();
- String hostname = discoveryContext.getSystemInformation().getHostname();
- String name = hostname + " Apache " + version + " (" +
httpdConf + ")";
+ String name = httpdConf;
DiscoveredResourceDetails resourceDetails = new
DiscoveredResourceDetails(discoveryContext.getResourceType(),
httpdConf, name, version, PRODUCT_DESCRIPTION, pluginConfig, processInfo);
diff --git
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
index 7e41eb4..024517f 100644
---
a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
+++
b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheVirtualHostServiceDiscoveryComponent.java
@@ -135,11 +135,11 @@ public class ApacheVirtualHostServiceDiscoveryComponent implements
ResourceDisco
ApacheVirtualHostServiceComponent.RESPONSE_TIME_LOG_FILE_CONFIG_PROP,
rtLogFile.toString());
pluginConfiguration.put(rtLogProp);
- String resourceName = "Virtual Host ";
+ String resourceName;
if (serverName != null) {
- resourceName += address.host + ":" + address.port;
+ resourceName = address.host + ":" + address.port;
} else {
- resourceName += resourceKey;
+ resourceName = resourceKey;
}
discoveredResources.add(new DiscoveredResourceDetails(resourceType,
resourceKey, resourceName, null, null,
commit 6278e7056403b2dcd0ffde84a7109e60790022eb
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:55:32 2010 -0500
simplify dbupgrade by merge saved search-related entries into a single schemaSpec
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 6fe555e..b2b3b11 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3231,9 +3231,7 @@
<schema-alterColumn table="RHQ_SAVED_SEARCH"
column="SUBJECT_ID" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" columnType="BOOLEAN" />
<schema-alterColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" nullable="FALSE" />
- </schemaSpec>
-
- <schemaSpec version="2.82.1">
+
<schema-directSQL>
<statement targetDBVendor="postgresql"
desc="Inserting global default saved search 'Downed Platforms'">
INSERT INTO rhq_saved_search (id, context, name, description,
pattern, last_compute_time, subject_id, global)
commit a6efa283222790b6e22f82861b1c145e34af9391
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:54:58 2010 -0500
insert some default global searches into the system during dbsetup
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
index 1a11114..da98622 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
@@ -10,7 +10,7 @@
DESCRIPTION="All downed machines across the entire enterprise"
PATTERN="down platform"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
<data ID="2"
CONTEXT="Resource"
@@ -18,7 +18,7 @@
DESCRIPTION="All downed servers across the entire enterprise"
PATTERN="down server"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
</table>
commit 1d02547312924f4904730bb0aebe7d0d8d9b70d2
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:21:37 2010 -0500
fix typo for column name in saved search table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
index 7c0de23..14634b6 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
@@ -17,7 +17,7 @@
<column name="RESULT_COUNT" type="LONG"
required="false"/>
<column name="SUBJECT_ID" type="INTEGER"
references="RHQ_SUBJECT" required="true"/>
- <column name="ENABLED" type="BOOLEAN"
required="true"/>
+ <column name="GLOBAL" type="BOOLEAN"
required="true"/>
</table>
</dbsetup>
\ No newline at end of file
commit 92adfd37e105c60efc0f1981d7fc2258ee423ad5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:05:08 2010 -0500
change order of dbsetup so that saved search table gets created after the rhq_subject
table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index f5e4eae..d5be746 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties
to true:
<property name="dbsetup.scripts.dir"
value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir"
value="${basedir}/target/dbsetup" /> <!-- away from classes so it
doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the
reverse order -->
- <property name="dbsetup.subsystems"
value="search,config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems"
value="config,cluster,inventory,auth,authz,search,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema"
value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data"
value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file"
value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
commit d0ef49e101ef7887e834b0a9021c0c0654a7f5d5
Merge: 613b993... 8a0951a...
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:34:50 2010 -0500
Merge branch 'master' into search
commit 613b993b85ac47117fda5d7f7810318e891cdf0e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:32:41 2010 -0500
construct AST from parse tree for RHQL grammar
diff --git
a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
index 00a0dab..ded91a1 100644
---
a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
+++
b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
@@ -27,11 +27,43 @@
* @author Joseph Marques
*/
grammar RHQL;
-
options {
language=Java;
backtrack=true;
memoize=true;
+ output=AST;
+ ASTLabelType=CommonTree;
+}
+
+/*
+ * Imaginary nodes serve to fully abstract the parse tree from the AST. This
+ * allows us, for example, to support the conjunctive ('and') operator between
+ * conditional expressions, but gives us the flexibility to modify the lexical
+ * element that represents that operation. In the future, we might want to
+ * support '&&' instead of 'and', or even support them both. The
inclusion of
+ * imaginary tokens creates a more stable AST that downstream grammars can use
+ * without fear that every change to the syntax will break their tree parser.
+ */
+tokens {
+ OR;
+ AND;
+
+ CONTEXT;
+ LINEAGE;
+ PATH;
+ PARAM;
+ IDENT;
+ VALUE;
+
+ OP_EQUALS;
+ OP_EQUALS_STRICT;
+ OP_NULL;
+ OP_IN;
+
+ OP_NOT_EQUALS;
+ OP_NOT_EQUALS_STRICT;
+ OP_NOT_NULL;
+ OP_NOT_IN;
}
@header {
@@ -41,26 +73,29 @@ options {
package org.rhq.enterprise.server.search;
}
+
/*
* parser rules
*/
searchExpression
- : conditionalExpression
+ : conditionalExpression {
System.out.println($conditionalExpression.tree.toStringTree()); }
;
conditionalExpression
- : conditionalFactor ( 'or' conditionalFactor )*
- ;
+ : conds+=conditionalFactor ( WS* ( 'or' ) WS* conds+=conditionalFactor )*
-> { $conds.size() == 1 }? ^($conds)
+ ->
^(OR conditionalFactor+)
+ ; // use rewrite predicates to eliminate superfluous 'or' node if only one
child
conditionalFactor
- : conditionalPrimary ( ( 'and' )? conditionalPrimary )*
- ;
+ : conds+=conditionalPrimary ( WS* ( 'and' WS* )? conds+=conditionalPrimary
)* -> { $conds.size() == 1 }? ^($conds)
+ ->
^(AND conditionalPrimary+)
+ ; // use rewrite predicates to eliminate superfluous 'and' node if only one
child
conditionalPrimary
- : simpleConditionalExpression
- | '(' conditionalExpression ')'
- ;
+ : WS* simpleConditionalExpression WS* ->
simpleConditionalExpression
+ | '(' WS* conditionalExpression WS* ')'
-> conditionalExpression
+ ; // avoid building nodes for parens, tree structure implies existence appropriately
-- ignore captured WS
simpleConditionalExpression
: comparisonConditionalExpression
@@ -69,69 +104,78 @@ simpleConditionalExpression
;
comparisonConditionalExpression
- : context comparisonOperator identifier
- ;
+ : c=context WS* op=comparisonOperator WS* ident=identifier ->
^($op $c ^(VALUE $ident))
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
nullComparisonConditionalExpression
- : context nullOperator
- ;
+ : c=context WS* op=nullOperator ->
^($op $c)
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
inExpression
- : context inOperator '[' '='? identifier ( ',' '='?
identifier )* ']'
- ;
+ : c=context WS* op=inOperator WS* '[' WS* ids+=identifier WS* ( ','
WS* ids+=identifier WS* )* ']'
+ ->
^($op $c ^(VALUE $ids+))
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
context
- : ( lineage '.' )? path ( '[' identifier ']' )?
+ : ( l=lineage '.' )? p=path ( '[' ident=identifier ']' )?
-> ^(CONTEXT ^(LINEAGE $l)? ^(PATH $p) ^(PARAM $ident)?)
;
lineage
- : path ( '(' INT ')' )?
- ;
+ : path ( '('! LEVEL ')'! )?
+ ; // avoid building nodes for brackets, tree structure implies existence
appropriately
path
: ID+
;
identifier
- : quotedValue
- | value
+ : doubleQuotedValue -> ^(IDENT doubleQuotedValue)
+ | quotedValue -> ^(IDENT quotedValue)
+ | openEndedvalue -> ^(IDENT openEndedvalue)
;
+doubleQuotedValue
+ : '"'! ~('"')* '"'!
+ ; // avoid building nodes for the double-quote characters
+
+
quotedValue
- : '\'' ~('\'')* '\''
- ;
+ : '\''! ~('\'')* '\''!
+ ; // avoid building nodes for the sinngle-quote characters
-value
- : ~('\'') ~(']'|','|')')*
- ;
+openEndedvalue
+ : ~(']' | ',' | ')' | '(' | 'or' |
'and' | WS )*
+ ; // consume until we find a char to terminate the current phrase ']'
',' ')' or begin the next '(' 'or' 'and'
comparisonOperator
- : '='
- | '=='
- | '!='
- | '!=='
- ;
+ : '=' -> ^(OP_EQUALS)
+ | '==' -> ^(OP_EQUALS_STRICT)
+ | '!=' -> ^(OP_NOT_EQUALS)
+ | '!==' -> ^(OP_NOT_EQUALS_STRICT)
+ ; // use imaginary nodes for all operators, which further removes the AST from the
real lexical elements
nullOperator
- : 'is' 'not'? 'null'
- ;
+ : 'is' WS+ (negation='not' WS+)? 'null' -> { $negation
== null }? ^(OP_NULL)
+ -> ^(OP_NOT_NULL)
+ ; // use imaginary nodes for all operators, which further removes the AST from the
real lexical elements
inOperator
- : 'not'? 'in'
- ;
+ : (negation+='not' WS+)? 'in' -> { $negation == null }?
^(OP_IN)
+ -> ^(OP_NOT_IN)
+ ; // use imaginary nodes for all operators, which further removes the AST from the
real lexical elements
/*
* lexical elements
- */
+ */
ID
: 'a'..'z'
;
-INT
- : '0'..'9'
+LEVEL
+ : '0'..'5'
;
WS
- : ( ' ' | '\n' | '\r' )+ { $channel = HIDDEN; }
+ : ( ' ' | '\n' | '\r' )+
;
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
index 637e339..ceab3e3 100644
---
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
@@ -62,6 +62,7 @@ public class RHQLTest extends AssertJUnit {
@Override
public TestResult call() throws Exception {
try {
+ System.out.println(line);
ANTLRStringStream input = new ANTLRStringStream(line); // Create an input
character stream from standard in
RHQLLexer lexer = new RHQLLexer(input); // Create an echoLexer that feeds
from that stream
CommonTokenStream tokens = new CommonTokenStream(lexer); // Create a
stream of tokens fed by the lexer
commit eac78662084095c22fb80326643fbf59f0e1a863
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:31:54 2010 -0500
modify RHQL test case file to adhere to simpler syntax for IN-clause:
* remove multi-word non-quoted identifers for the IN-clause
* remove ability to change case-sensitivity comparison for IN-clause
diff --git a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
index 2a5a195..f8c241a 100644
--- a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
+++ b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
@@ -7,11 +7,11 @@ context !== value
context is null
context is not null
context in [value]
-context in [value1, =value2]
-context in [=value1, value2, value3]
+context in [value1, value2]
+context in [value1, value2, value3]
context not in [value]
-context not in [value1, =value2]
-context not in [=value1, value2, value3]
+context not in [value1, value2]
+context not in [value1, value2, value3]
# simple term, all operators, quoted value
context = 'quoted value'
@@ -21,19 +21,11 @@ context !== 'quoted value'
context is null
context is not null
context in ['quoted value1']
-context in ['quoted value1', ='quoted value2']
-context in [='quoted value1', 'quoted value2', 'quoted value3']
+context in ['quoted value1', 'quoted value2']
+context in ['quoted value1', 'quoted value2', 'quoted value3']
context not in ['quoted value1']
-context not in ['quoted value1', ='quoted value2']
-context not in [='quoted value1', 'quoted value2', 'quoted
value3']
-
-# simple term, 'in' operator, non-quoted but multi-word values
-context in [quoted value1]
-context in [quoted value1, =quoted value2]
-context in [=quoted value1, quoted value2, quoted value3]
-context not in [quoted value1]
-context not in [quoted value1, =quoted value2]
-context not in [=quoted value1, quoted value2, quoted value3]
+context not in ['quoted value1', 'quoted value2']
+context not in ['quoted value1', 'quoted value2', 'quoted
value3']
# parameterized term, all operators
context[param] = value
@@ -43,11 +35,11 @@ context[param] !== value
context[param] is null
context[param] is not null
context[param] in [value]
-context[param] in [value1, =value2]
-context[param] in [=value1, value2, value3]
+context[param] in [value1, value2]
+context[param] in [value1, value2, value3]
context[param] not in [value]
-context[param] not in [value1, =value2]
-context[param] not in [=value1, value2, value3]
+context[param] not in [value1, value2]
+context[param] not in [value1, value2, value3]
# deeply nested parenthetical simple terms
((context = value))
@@ -63,11 +55,11 @@ context[param] not in [=value1, value2, value3]
(context is null)
(context is not null)
(context in [value])
-(context in [value1, =value2])
-(context in [=value1, value2, value3])
+(context in [value1, value2])
+(context in [value1, value2, value3])
(context not in [value])
-(context not in [value1, =value2])
-(context not in [=value1, value2, value3])
+(context not in [value1, value2])
+(context not in [value1, value2, value3])
# parameterized parenthetical term, all operators
(context[param] = value)
@@ -77,11 +69,11 @@ context[param] not in [=value1, value2, value3]
(context[param] is null)
(context[param] is not null)
(context[param] in [value])
-(context[param] in [value1, =value2])
-(context[param] in [=value1, value2, value3])
+(context[param] in [value1, value2])
+(context[param] in [value1, value2, value3])
(context[param] not in [value])
-(context[param] not in [value1, =value2])
-(context[param] not in [=value1, value2, value3])
+(context[param] not in [value1, value2])
+(context[param] not in [value1, value2, value3])
# single-pair parenthetical combinations
@@ -131,4 +123,4 @@ context = value1 and ((context = value2))
((context = value1)) context = value2
(context = value1) (context = value2)
(context = value1 (context = value2))
-context = value1 ((context1 = value2))
\ No newline at end of file
+context = value1 ((context = value2))
\ No newline at end of file
commit 8a0951a835997a2cdc75d2cf9840a7a7fdf59c15
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 26 17:57:56 2010 +0100
BZ 568544 - disambiguation doesn't get confused if more than one item in the
provided results corresponds to a signle resource.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
index 67f3276..dd359da 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
@@ -64,6 +64,6 @@ public class DisambiguationReport<T> implements Serializable {
}
public String toString() {
- return "DisambiguationReport(type=" + resourceTypeName + ",
plugin=" + resourceTypePluginName + ", parents=" + parents +
")";
+ return "DisambiguationReport(type=" + resourceTypeName + ",
plugin=" + resourceTypePluginName + ", parents=" + parents + ",
original=" + original + ")";
}
}
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 3af7a35..e5684d2 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -31,6 +31,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
@@ -2170,34 +2171,36 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
false);
}
- //this will contain the disambiguated results
- List<DisambiguationReport<T>> resolution = new
ArrayList<DisambiguationReport<T>>(results.size());
boolean typeResolutionNeeded = false;
boolean pluginResolutionNeeded = false;
boolean parentResolutionNeeded = false;
//we can't assume the ordering of the provided results and the disambiguation
query results
- //will be the same, hence this map.
- Map<Integer, MutableDisambiguationReport<T>> reportByResourceId = new
HashMap<Integer, MutableDisambiguationReport<T>>();
+ //will be the same.
+
+ //this list contains the resulting reports in the same order as the original
results
+ List<MutableDisambiguationReport<T>> reports = new
ArrayList<MutableDisambiguationReport<T>>(results.size());
+
+ //this maps the reports to resourceIds. More than one report can correspond to a
single
+ //resource id. The reports in this map are the same instances as in the reports
list.
+ Map<Integer, List<MutableDisambiguationReport<T>>>
reportsByResourceId = new HashMap<Integer,
List<MutableDisambiguationReport<T>>>();
for (T r : results) {
MutableDisambiguationReport<T> value = new
MutableDisambiguationReport<T>();
value.original = r;
int resourceId = extractor.extract(r);
if (resourceId > 0) {
- reportByResourceId.put(resourceId, value);
+ List<MutableDisambiguationReport<T>> correspondingResults =
reportsByResourceId.get(resourceId);
+ if (correspondingResults == null) {
+ correspondingResults = new
ArrayList<MutableDisambiguationReport<T>>();
+ reportsByResourceId.put(resourceId, correspondingResults);
+ }
+ correspondingResults.add(value);
}
+ reports.add(value);
}
//check that we still have something to disambiguate
- if (reportByResourceId.isEmpty()) {
- //no, we don't. construct the resolution only using the results.
-
- for (T result : results) {
- DisambiguationReport<T> report = new
DisambiguationReport<T>(result, Collections
- .<ResourceParentFlyweight> emptyList(), null, null);
- resolution.add(report);
- }
- } else {
+ if (reportsByResourceId.size() > 0) {
//first find out how many ancestors we are going to require to disambiguate
the resuls
String query = Resource.NATIVE_QUERY_FIND_DISAMBIGUATION_LEVEL;
@@ -2247,7 +2250,7 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
Query parentsQuery = entityManager.createQuery(selectBuilder.append("
").append(fromBuilder).toString());
- parentsQuery.setParameter("resourceIds",
reportByResourceId.keySet());
+ parentsQuery.setParameter("resourceIds",
reportsByResourceId.keySet());
@SuppressWarnings("unchecked")
List<Object[]> parentsResults = (List<Object[]>)
parentsQuery.getResultList();
@@ -2264,28 +2267,22 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
String parentName = (String) parentsResult[2 * i + 2];
parents.add(new ResourceParentFlyweight(parentId, parentName));
}
- MutableDisambiguationReport<T> report =
reportByResourceId.get(resourceId);
- report.typeName = typeName;
- report.pluginName = pluginName;
- report.parents = parents;
- }
-
- //now we have all the information to create the result.
- for (T result : results) {
- int resourceId = extractor.extract(result);
- if (resourceId > 0) {
- //this results was disambiguated by the query above...
- MutableDisambiguationReport<T> report =
reportByResourceId.get(resourceId);
- resolution.add(report.getReport());
- } else {
- //this result doesn't correspond to any resource, need to handle
it specially
- DisambiguationReport<T> report = new
DisambiguationReport<T>(result, Collections
- .<ResourceParentFlyweight> emptyList(), null, null);
- resolution.add(report);
+
+ //update all the reports that correspond to this resourceId
+ for(MutableDisambiguationReport<T> report :
reportsByResourceId.get(resourceId)) {
+ report.typeName = typeName;
+ report.pluginName = pluginName;
+ report.parents = parents;
}
}
}
+ List<DisambiguationReport<T>> resolution = new
ArrayList<DisambiguationReport<T>>(results.size());
+
+ for (MutableDisambiguationReport<T> report : reports) {
+ resolution.add(report.getReport());
+ }
+
return new ResourceNamesDisambiguationResult<T>(resolution,
typeResolutionNeeded, parentResolutionNeeded,
pluginResolutionNeeded);
}
@@ -2297,7 +2294,8 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
public List<ResourceParentFlyweight> parents;
public DisambiguationReport<T> getReport() {
- return new DisambiguationReport<T>(original, parents, typeName,
pluginName);
+ return new DisambiguationReport<T>(original, parents == null ?
Collections
+ .<ResourceParentFlyweight> emptyList() : parents, typeName,
pluginName);
}
}
}
commit 602b8780654df9298dc36f6e8523e2ebb3e0c906
Author: Joseph Marques <joseph(a)redhat.com>
Date: Thu Feb 25 12:34:39 2010 -0500
add missing @WebMethod annotation to saved search manager remote interface
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
index ffd4255..231167e 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -112,6 +112,7 @@ public interface SavedSearchManagerRemote {
* @return the {@link PageList} of {@link SavedSearch} entities that match the
criteria filters, an empty list
* will be returned if no results were found or none matches the given
filters
*/
+ @WebMethod
public PageList<SavedSearch> findSavedSearchesByCriteria( //
@WebParam(name = "subject") Subject subject, //
@WebParam(name = "criteria") SavedSearchCriteria criteria);
commit 07a482e999b87952b9cdbd2573fe6b04c4b8ff8e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Feb 24 22:04:30 2010 -0500
abstract RHQL grammar support:
* initial combined lexer/parser grammar file
* test harness to verify grammar correctness
* 100 acceptance test cases exercising all major parts of generic syntax
diff --git
a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
new file mode 100644
index 0000000..00a0dab
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
@@ -0,0 +1,137 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.
+ */
+
+/*
+ * Antlr v3 grammar file to parse RHQL search expressions.
+ *
+ * @author Joseph Marques
+ */
+grammar RHQL;
+
+options {
+ language=Java;
+ backtrack=true;
+ memoize=true;
+}
+
+@header {
+ package org.rhq.enterprise.server.search;
+}
+@lexer::header {
+ package org.rhq.enterprise.server.search;
+}
+
+/*
+ * parser rules
+ */
+
+searchExpression
+ : conditionalExpression
+ ;
+
+conditionalExpression
+ : conditionalFactor ( 'or' conditionalFactor )*
+ ;
+
+conditionalFactor
+ : conditionalPrimary ( ( 'and' )? conditionalPrimary )*
+ ;
+
+conditionalPrimary
+ : simpleConditionalExpression
+ | '(' conditionalExpression ')'
+ ;
+
+simpleConditionalExpression
+ : comparisonConditionalExpression
+ | nullComparisonConditionalExpression
+ | inExpression
+ ;
+
+comparisonConditionalExpression
+ : context comparisonOperator identifier
+ ;
+
+nullComparisonConditionalExpression
+ : context nullOperator
+ ;
+
+inExpression
+ : context inOperator '[' '='? identifier ( ',' '='?
identifier )* ']'
+ ;
+
+context
+ : ( lineage '.' )? path ( '[' identifier ']' )?
+ ;
+
+lineage
+ : path ( '(' INT ')' )?
+ ;
+
+path
+ : ID+
+ ;
+
+identifier
+ : quotedValue
+ | value
+ ;
+
+quotedValue
+ : '\'' ~('\'')* '\''
+ ;
+
+value
+ : ~('\'') ~(']'|','|')')*
+ ;
+
+comparisonOperator
+ : '='
+ | '=='
+ | '!='
+ | '!=='
+ ;
+
+nullOperator
+ : 'is' 'not'? 'null'
+ ;
+
+inOperator
+ : 'not'? 'in'
+ ;
+
+/*
+ * lexical elements
+ */
+
+ID
+ : 'a'..'z'
+ ;
+
+INT
+ : '0'..'9'
+ ;
+
+WS
+ : ( ' ' | '\n' | '\r' )+ { $channel = HIDDEN; }
+ ;
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
new file mode 100644
index 0000000..2a5a195
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
@@ -0,0 +1,134 @@
+
+# simple term, all operators
+context = value
+context == value
+context != value
+context !== value
+context is null
+context is not null
+context in [value]
+context in [value1, =value2]
+context in [=value1, value2, value3]
+context not in [value]
+context not in [value1, =value2]
+context not in [=value1, value2, value3]
+
+# simple term, all operators, quoted value
+context = 'quoted value'
+context == 'quoted value'
+context != 'quoted value'
+context !== 'quoted value'
+context is null
+context is not null
+context in ['quoted value1']
+context in ['quoted value1', ='quoted value2']
+context in [='quoted value1', 'quoted value2', 'quoted value3']
+context not in ['quoted value1']
+context not in ['quoted value1', ='quoted value2']
+context not in [='quoted value1', 'quoted value2', 'quoted
value3']
+
+# simple term, 'in' operator, non-quoted but multi-word values
+context in [quoted value1]
+context in [quoted value1, =quoted value2]
+context in [=quoted value1, quoted value2, quoted value3]
+context not in [quoted value1]
+context not in [quoted value1, =quoted value2]
+context not in [=quoted value1, quoted value2, quoted value3]
+
+# parameterized term, all operators
+context[param] = value
+context[param] == value
+context[param] != value
+context[param] !== value
+context[param] is null
+context[param] is not null
+context[param] in [value]
+context[param] in [value1, =value2]
+context[param] in [=value1, value2, value3]
+context[param] not in [value]
+context[param] not in [value1, =value2]
+context[param] not in [=value1, value2, value3]
+
+# deeply nested parenthetical simple terms
+((context = value))
+(((context = value)))
+((((context = value))))
+(((((context = value)))))
+
+# simple parenthetical term, all operators
+(context = value)
+(context == value)
+(context != value)
+(context !== value)
+(context is null)
+(context is not null)
+(context in [value])
+(context in [value1, =value2])
+(context in [=value1, value2, value3])
+(context not in [value])
+(context not in [value1, =value2])
+(context not in [=value1, value2, value3])
+
+# parameterized parenthetical term, all operators
+(context[param] = value)
+(context[param] == value)
+(context[param] != value)
+(context[param] !== value)
+(context[param] is null)
+(context[param] is not null)
+(context[param] in [value])
+(context[param] in [value1, =value2])
+(context[param] in [=value1, value2, value3])
+(context[param] not in [value])
+(context[param] not in [value1, =value2])
+(context[param] not in [=value1, value2, value3])
+
+
+# single-pair parenthetical combinations
+# simple expression, 'or' boolean operator
+context = value1 or context = value2
+(context = value1) or context = value2
+context = value1 or (context = value2)
+(context = value1) or (context = value2)
+
+# single-pair parenthetical combinations
+# simple expression, 'and' boolean operator
+context = value and context = value
+(context = value) and context = value
+context = value and (context = value)
+(context = value) and (context = value)
+
+# single-pair parenthetical combinations
+# simple expression, no boolean operator (implies 'and' semantics)
+context = value context = value
+(context = value) context = value
+context = value (context = value)
+(context = value) (context = value)
+
+
+# double-pair parenthetical combinations
+# simple expression, 'or' boolean operator
+((context = value1 or context = value2))
+((context = value1) or context = value2)
+((context = value1)) or context = value2
+(context = value1) or (context = value2)
+(context = value1 or (context = value2))
+context = value1 or ((context = value2))
+
+# double-pair parenthetical combinations
+# simple expression, 'and' boolean operator
+((context = value1 and context = value2))
+((context = value1) and context = value2)
+((context = value1)) and context = value2
+(context = value1) and (context = value2)
+(context = value1 and (context = value2))
+context = value1 and ((context = value2))
+
+# double-pair parenthetical combinations
+# simple expression, no boolean operator (implies 'and' semantics)
+((context = value1 context = value2))
+((context = value1) context = value2)
+((context = value1)) context = value2
+(context = value1) (context = value2)
+(context = value1 (context = value2))
+context = value1 ((context1 = value2))
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
new file mode 100644
index 0000000..637e339
--- /dev/null
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
@@ -0,0 +1,170 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.enterprise.server.search;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Test harness to verify correctness of RHQL grammar
+ *
+ * @author Joseph Marques
+ */
+public class RHQLTest extends AssertJUnit {
+
+ private enum TestResult {
+ SUCCESS, FAILURE, TIMEOUT, SKIPPED;
+ }
+
+ private class AntlrTask implements Callable<TestResult> {
+ private String line;
+
+ public AntlrTask(String line) {
+ this.line = line;
+ }
+
+ @Override
+ public TestResult call() throws Exception {
+ try {
+ ANTLRStringStream input = new ANTLRStringStream(line); // Create an input
character stream from standard in
+ RHQLLexer lexer = new RHQLLexer(input); // Create an echoLexer that feeds
from that stream
+ CommonTokenStream tokens = new CommonTokenStream(lexer); // Create a
stream of tokens fed by the lexer
+ RHQLParser parser = new RHQLParser(tokens); // Create a parser that feeds
off the token stream
+ parser.searchExpression(); // Begin parsing at 'searchExpression'
rule
+ return TestResult.SUCCESS;
+ } catch (Throwable t) {
+ return TestResult.FAILURE;
+ }
+ }
+ };
+
+ private ExecutorService executor;
+
+ @BeforeSuite
+ public void init() {
+ executor = Executors.newSingleThreadExecutor();
+ }
+
+ @AfterSuite
+ public void teardown() {
+ executor.shutdownNow();
+ }
+
+ @Test
+ public void testSingleLineRHQL() throws Exception {
+ BufferedReader reader = null;
+ List<String> successes = new java.util.ArrayList<String>();
+ List<String> failures = new java.util.ArrayList<String>();
+ int count = 0;
+ try {
+ InputStream stream =
getClass().getClassLoader().getResourceAsStream("single-line-rhql.txt");
+ reader = new BufferedReader(new InputStreamReader(stream));
+ String line = null;
+ long timeout = 2000;
+ while ((line = reader.readLine()) != null) {
+ TestResult result = testSuccess(line, timeout);
+ if (result == TestResult.SKIPPED) {
+ continue;
+ }
+ count++;
+ if (result == TestResult.SUCCESS) {
+ successes.add(line);
+ } else if (result == TestResult.FAILURE) {
+ failures.add(line);
+ } else if (result == TestResult.TIMEOUT) {
+ System.out.println("Parsing took more than " + timeout
+ + "ms, does your grammar have an infinite loop?");
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Error testing single line RHQL: " + e);
+ throw e;
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ System.out.println();
+ for (String success : successes) {
+ System.out.println("Parse success: " + success);
+ }
+ for (String failure : failures) {
+ System.out.println("Parse failure: " + failure);
+ }
+
+ System.out.println();
+ System.out.printf("RHQL expressions parsed: %1$s, Failures: %2$s",
count, failures.size());
+ System.out.println();
+
+ assert failures.size() == 0;
+ }
+
+ private TestResult testSuccess(final String line, long timeout) {
+ if (shouldSkip(line)) {
+ return TestResult.SKIPPED; // skip empty lines used for visual separation in
test file
+ }
+
+ AntlrTask task = new AntlrTask(line);
+ Future<TestResult> futureTask = executor.submit(task);
+ TestResult result = null;
+ try {
+ result = futureTask.get(timeout, TimeUnit.MILLISECONDS);
+ } catch (ExecutionException ee) {
+ } catch (TimeoutException te) {
+ futureTask.cancel(true);
+ result = TestResult.TIMEOUT;
+ } catch (InterruptedException ie) {
+ futureTask.cancel(true);
+ }
+
+ return result;
+ }
+
+ private boolean shouldSkip(String line) {
+ line = line.trim();
+ if (line.equals("")) {
+ return true; // ignore empty lines
+ }
+ if (line.startsWith("#")) {
+ return true; // ignore comments
+ }
+ return false;
+ }
+}
commit 7369db803076bc12f02bcc6131b9fe1e5303ae47
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Feb 24 01:57:08 2010 -0500
antlr should compile the grammar files before the standard maven compile phase
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index b322503..533c0e9 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -467,10 +467,10 @@
<version>3.2</version>
<executions>
<execution>
- <phase>compile</phase>
- <goals>
- <goal>antlr</goal>
- </goals>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>antlr</goal>
+ </goals>
<configuration>
<conversionTimeout>30000</conversionTimeout>
<debug>false</debug>
commit d17f4616c524e65decd6af3db65df8a83d18c12e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 16:54:20 2010 -0500
add anltr support to server/jar maven module, update eclipse classpath accordingly;
diff --git a/.classpath b/.classpath
index 660d74d..1a35400 100644
--- a/.classpath
+++ b/.classpath
@@ -19,6 +19,7 @@
<classpathentry kind="src"
path="modules/plugins/jboss-cache/src/main/java"/>
<classpathentry kind="src"
path="modules/plugins/jboss-cache-v3/src/main/java"/>
<classpathentry kind="src"
path="etc/samples/perspectives/sample-perspective/app/src/main/java"/>
+ <classpathentry kind="src"
path="modules/enterprise/server/jar/target/generated-sources/antlr3"/>
<classpathentry kind="var"
path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/>
<classpathentry kind="var"
path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/>
<classpathentry kind="var"
path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/>
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index e109c41..b322503 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -366,6 +366,13 @@
<artifactId>test-utils</artifactId>
<version>${version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ <version>3.2</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
<build>
@@ -454,6 +461,41 @@
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr3-maven-plugin</artifactId>
+ <version>3.2</version>
+ <executions>
+ <execution>
+ <phase>compile</phase>
+ <goals>
+ <goal>antlr</goal>
+ </goals>
+ <configuration>
+ <conversionTimeout>30000</conversionTimeout>
+ <debug>false</debug>
+ <dfa>false</dfa>
+ <nfa>false</nfa>
+ <excludes>
+
+ </excludes>
+ <includes>
+
+ </includes>
+ <libDirectory>src/main/antlr3/imports</libDirectory>
+ <messageFormat>antlr</messageFormat>
+
<outputDirectory>target/generated-sources/antlr3</outputDirectory>
+ <printGrammar>false</printGrammar>
+ <profile>false</profile>
+ <report>false</report>
+ <sourceDirectory>src/main/antlr3</sourceDirectory>
+ <trace>false</trace>
+ <verbose>true</verbose>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
</plugins>
</build>
commit fc1118af81ff953f2c05fb696629d799169b22f1
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 13:21:29 2010 -0500
fix some whitespace issues
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index f14e145..e109c41 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -414,7 +414,7 @@
Build-Jdk=${java.version}
Build-OS-Name=${os.name}
Build-OS-Version=${os.version}
-</echo>
+ </echo>
</tasks>
</configuration>
<goals>
@@ -593,8 +593,7 @@
<link href="../domain" />
<link href="../plugin-api" />
<link
href="http://java.sun.com/j2se/1.5.0/docs/api/" />
- <bottom><![CDATA[Copyright © 2008-2009
<a
href="http://rhq-project.org/">Red Hat, Inc.</a>. All Rights
Reserved.
-]]></bottom>
+ <bottom><![CDATA[Copyright © 2008-2009
<a
href="http://rhq-project.org/">Red Hat, Inc.</a>. All Rights
Reserved.]]></bottom>
</javadoc>
</tasks>
</configuration>
commit 1c79730a4d3ce260e2f3d6ce9b8e971da158e1d7
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 13:10:18 2010 -0500
add some default, global saved searches for the resource context
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
new file mode 100644
index 0000000..1a11114
--- /dev/null
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<dbsetup name="search-data.xml">
+
+ <!-- overlord-created, global, default saved searches -->
+ <table name="RHQ_SAVED_SEARCH">
+ <data ID="1"
+ CONTEXT="Resource"
+ NAME="Downed Platforms"
+ DESCRIPTION="All downed machines across the entire enterprise"
+ PATTERN="down platform"
+ LAST_COMPUTE_TIME="0"
+ SUBJECT="1"
+ GLOBAL="TRUE" />
+ <data ID="2"
+ CONTEXT="Resource"
+ NAME="Downed Servers"
+ DESCRIPTION="All downed servers across the entire enterprise"
+ PATTERN="down server"
+ LAST_COMPUTE_TIME="0"
+ SUBJECT="1"
+ GLOBAL="TRUE" />
+ </table>
+
+</dbsetup>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 834e9ce..6fe555e 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3202,13 +3202,18 @@
</statement>
</schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.82">
<schema-directSQL>
<statement desc="Creating table RHQ_SAVED_SEARCH">
CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
</statement>
</schema-directSQL>
+ <schema-directSQL>
+ <statement desc="Creating primary key for
RHQ_AFFINITY_GROUP">
+ ALTER TABLE RHQ_SAVED_SEARCH ADD PRIMARY KEY ( ID )
+ </statement>
+ </schema-directSQL>
<schema-addColumn table="RHQ_SAVED_SEARCH"
column="CONTEXT" columnType="VARCHAR2" precision="25" />
<schema-alterColumn table="RHQ_SAVED_SEARCH"
column="CONTEXT" nullable="FALSE" />
@@ -3227,6 +3232,29 @@
<schema-addColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" columnType="BOOLEAN" />
<schema-alterColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" nullable="FALSE" />
</schemaSpec>
+
+ <schemaSpec version="2.82.1">
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql"
desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description,
pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms',
'All downed machines across the entire enterprise', 'down platform', 0, 1,
true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting
global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description,
pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms',
'All downed machines across the entire enterprise', 'down platform', 0, 1,
1)
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql"
desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description,
pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All
downed servers across the entire enterprise', 'down server', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting
global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description,
pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All
downed servers across the entire enterprise', 'down server', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
commit 68f3634b787768dd5ee138a04a5398fdd4cb6404
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 12:07:56 2010 -0500
fix copy/paste error for saved search entity annotation
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
index 9142772..d6b50e7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
@@ -87,7 +87,7 @@ public class SavedSearch {
@Column(name = "SUBJECT_ID", nullable = false)
private Subject subject;
- @Column(name = "RESOURCE_ID", insertable = false, updatable = false)
+ @Column(name = "SUBJECT_ID", insertable = false, updatable = false)
private int subjectId;
@Column(name = "GLOBAL", nullable = false)
commit 2325fa6314a7ebcbf1d932fb42e9f9559e1d079b
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 03:02:28 2010 -0500
add auto-completion capability for saved search manager to the CLI
diff --git
a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
index acafe6f..a1a5b38 100644
---
a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
+++
b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
@@ -54,6 +54,7 @@ import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
import org.rhq.enterprise.server.support.SupportManagerRemote;
import org.rhq.enterprise.server.system.ServerVersion;
import org.rhq.enterprise.server.system.SystemManagerRemote;
@@ -94,6 +95,7 @@ public class RemoteClient {
ResourceGroupManager(ResourceGroupManagerRemote.class), //
ResourceTypeManager(ResourceTypeManagerRemote.class), //
RoleManager(RoleManagerRemote.class), //
+ SavedSearchManager(SavedSearchManagerRemote.class), //
SubjectManager(SubjectManagerRemote.class), //
SupportManager(SupportManagerRemote.class), //
SystemManager(SystemManagerRemote.class) //
commit 9bfad0211e66635e09d02d8959a81db33f6175b7
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:51:14 2010 -0500
add LookupUtil method to retrieve the saved search manager from the UI layer
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
index dc9ae11..c21526a 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
@@ -165,6 +165,8 @@ import
org.rhq.enterprise.server.resource.metadata.ResourceMetadataManagerBean;
import org.rhq.enterprise.server.resource.metadata.ResourceMetadataManagerLocal;
import org.rhq.enterprise.server.scheduler.SchedulerBean;
import org.rhq.enterprise.server.scheduler.SchedulerLocal;
+import org.rhq.enterprise.server.search.SavedSearchManagerBean;
+import org.rhq.enterprise.server.search.SavedSearchManagerLocal;
import org.rhq.enterprise.server.subsystem.AlertSubsystemManagerBean;
import org.rhq.enterprise.server.subsystem.AlertSubsystemManagerLocal;
import org.rhq.enterprise.server.subsystem.ConfigurationSubsystemManagerBean;
@@ -516,6 +518,10 @@ public final class LookupUtil {
return lookupLocal(SchedulerBean.class);
}
+ public static SavedSearchManagerLocal getSavedSearchManager() {
+ return lookupLocal(SavedSearchManagerBean.class);
+ }
+
public static SubjectManagerLocal getSubjectManager() {
return lookupLocal(SubjectManagerBean.class);
}
commit 7b68ec1372bd5af42793b5d15020e7b2f66bb931
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:49:08 2010 -0500
add criteria-based retrieval for the saved search manager
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
new file mode 100644
index 0000000..bd70b6f
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
@@ -0,0 +1,142 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.search.SearchContext;
+import org.rhq.core.domain.util.PageOrdering;
+
+/**
+ * @author Joseph Marques
+ */
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class SavedSearchCriteria extends Criteria {
+ public static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private SearchContext filterContext;
+ private String filterName;
+ private String filterDescription;
+ private String filterPattern;
+ private Long filterLastComputeTimeMin;
+ private Long filterLastComputeTimeMax;
+ private Long filterResultCountMin;
+ private Long filterResultCountMax;
+ private Integer filterSubjectId;
+ private Boolean filterGlobal;
+
+ private boolean fetchSubject;
+
+ private PageOrdering sortContext;
+ private PageOrdering sortName;
+ private PageOrdering sortLastComputeTime;
+ private PageOrdering sortResultCount;
+ private PageOrdering sortGlobal;
+
+ public SavedSearchCriteria() {
+ super(SavedSearch.class);
+
+ filterOverrides.put("lastComputeTimeMin", "lastComputeTime >=
?");
+ filterOverrides.put("lastComputeTimeMax", "lastComputeTime <=
?");
+ filterOverrides.put("resultCountMin", "resultCount >=
?");
+ filterOverrides.put("resultCountMax", "resultCount <=
?");
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterSearchContext(SearchContext filterContext) {
+ this.filterContext = filterContext;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void addFilterDescription(String filterDescription) {
+ this.filterDescription = filterDescription;
+ }
+
+ public void addFilterPattern(String filterPattern) {
+ this.filterPattern = filterPattern;
+ }
+
+ public void addFilterResultCountMin(Long filterResultCountMin) {
+ this.filterResultCountMin = filterResultCountMin;
+ }
+
+ public void addFilterResultCountMax(Long filterResultCountMax) {
+ this.filterResultCountMax = filterResultCountMax;
+ }
+
+ public void addFilterLastComputeTimeMin(Long filterLastComputeTimeMin) {
+ this.filterLastComputeTimeMin = filterLastComputeTimeMin;
+ }
+
+ public void addFilterLastComputeTimeMax(Long filterLastComputeTimeMax) {
+ this.filterLastComputeTimeMax = filterLastComputeTimeMax;
+ }
+
+ public void addFilterSubjectId(Integer filterSubjectId) {
+ this.filterSubjectId = filterSubjectId;
+ }
+
+ public void addFilterGlobal(Boolean filterGlobal) {
+ this.filterGlobal = filterGlobal;
+ }
+
+ public void setFetchSubject(boolean fetchSubject) {
+ this.fetchSubject = fetchSubject;
+ }
+
+ public void addSortContext(PageOrdering sortContext) {
+ addSortField("context");
+ this.sortContext = sortContext;
+ }
+
+ public void addSortName(PageOrdering sortName) {
+ addSortField("name");
+ this.sortName = sortName;
+ }
+
+ public void addSortLastComputeTime(PageOrdering sortLastComputeTime) {
+ addSortField("lastComputeTime");
+ this.sortLastComputeTime = sortLastComputeTime;
+ }
+
+ public void addSortResultCount(PageOrdering sortResultCount) {
+ addSortField("resultCount");
+ this.sortResultCount = sortResultCount;
+ }
+
+ public void addSortGlobal(PageOrdering sortGlobal) {
+ addSortField("global");
+ this.sortGlobal = sortGlobal;
+ }
+
+}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
index f672ac7..1485197 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
@@ -24,10 +24,14 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.SavedSearchCriteria;
import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* This bean provides functionality to CRUD saved search patterns.
@@ -79,6 +83,18 @@ public class SavedSearchManagerBean implements SavedSearchManagerLocal
/* local
return savedSearch;
}
+ public PageList<SavedSearch> findSavedSearchesByCriteria(Subject subject,
SavedSearchCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ if (!authorizationManager.isInventoryManager(subject)) {
+ generator.setAuthorizationCustomConditionFragment("(subject.id=" +
subject.getId() + " OR global=true)");
+ }
+
+ CriteriaQueryRunner<SavedSearch> queryRunner = new
CriteriaQueryRunner<SavedSearch>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
private void validateManipulatePermission(Subject subject, SavedSearch savedSearch)
{
if (savedSearch.isGlobal()) {
if (!authorizationManager.isInventoryManager(subject)) {
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
index a1615ec..ffd4255 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -25,7 +25,9 @@ import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.SavedSearchCriteria;
import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.system.ServerVersion;
@@ -99,4 +101,18 @@ public interface SavedSearchManagerRemote {
public SavedSearch getSavedSearchById( //
@WebParam(name = "subject") Subject subject, //
@WebParam(name = "savedSearchId") int savedSearchId);
+
+ /**
+ * Returns the {@link PageList} of {@link SavedSearch} entities that match the
criteria filters that are visible
+ * to the user
+ *
+ * @param subject the logged in user requesting the {@link PageList} of {@link
SavedSearch} to be returned
+ * @param criteria the {@link SavedSearchCriteria} object that will filter the
returned results
+ *
+ * @return the {@link PageList} of {@link SavedSearch} entities that match the
criteria filters, an empty list
+ * will be returned if no results were found or none matches the given
filters
+ */
+ public PageList<SavedSearch> findSavedSearchesByCriteria( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "criteria") SavedSearchCriteria criteria);
}
commit 8bee964f9c9fb494fc08a3baaa307361d826b445
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:48:32 2010 -0500
enhance the CriteriaQueryGenerator to allow more flexible authorization:
support users to set a completely arbitrary authorization fragment, which
will be inserted into the list of conditions for the generated query
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 9c62eed..bb0c072 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -58,13 +58,14 @@ public final class CriteriaQueryGenerator {
public enum AuthorizationTokenType {
RESOURCE, // specifies the resource alias to join on for standard
res-group-role-subject authorization checking
- GROUP; // specifies the group alias to join on for standard group-role-subject
authorization checking
+ GROUP; // specifies the group alias to join on for standard group-role-subject
authorization checking
}
private Criteria criteria;
private String authorizationJoinFragment;
private String authorizationPermsFragment;
+ private String authorizationCustomConditionFragment;
private int authorizationSubjectId;
private String alias;
@@ -89,6 +90,10 @@ public final class CriteriaQueryGenerator {
this.alias = aliasBuilder.toString();
}
+ public void setAuthorizationCustomConditionFragment(String fragment) {
+ this.authorizationCustomConditionFragment = fragment;
+ }
+
public void setAuthorizationResourceFragment(AuthorizationTokenType type, int
subjectId) {
String defaultFragment = null;
if (type == AuthorizationTokenType.RESOURCE) {
@@ -260,6 +265,16 @@ public final class CriteriaQueryGenerator {
}
}
+ if (authorizationCustomConditionFragment != null) {
+ if (firstCrit) {
+ firstCrit = false;
+ } else {
+ // always want AND for security, regardless of conjunctiveFragment
+ results.append(NL).append(" AND ");
+ }
+ results.append(this.authorizationCustomConditionFragment);
+ }
+
if (countQuery == false) {
boolean overridden = true;
PageControl pc = criteria.getPageControlOverrides();
commit d065f478b829887eda067308a10f98edef113b66
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 00:50:35 2010 -0500
initial SLSB support basic CRUD, with security restrictions, for saved search
patterns
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
new file mode 100644
index 0000000..f672ac7
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
@@ -0,0 +1,104 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.server.search;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.enterprise.server.RHQConstants;
+import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
+import org.rhq.enterprise.server.authz.PermissionException;
+
+/**
+ * This bean provides functionality to CRUD saved search patterns.
+ *
+ * @author Joseoh Marques
+ */
+@Stateless
+public class SavedSearchManagerBean implements SavedSearchManagerLocal /* local already
implements remote interface */{
+
+ @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
+ private EntityManager entityManager;
+
+ @EJB
+ private AuthorizationManagerLocal authorizationManager;
+
+ /**
+ * @see SavedSearchManagerRemote#createSavedSearch(Subject, SavedSearch)
+ */
+ public void createSavedSearch(Subject subject, SavedSearch savedSearch) {
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.persist(savedSearch);
+ return;
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#updateSavedSearch(Subject, SavedSearch)
+ */
+ public void updateSavedSearch(Subject subject, SavedSearch savedSearch) {
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.merge(savedSearch);
+ return;
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#deleteSavedSearch(Subject, int)
+ */
+ public void deleteSavedSearch(Subject subject, int savedSearchId) {
+ SavedSearch savedSearch = entityManager.find(SavedSearch.class, savedSearchId);
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.remove(savedSearch);
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#getSavedSearchById(Subject, int)
+ */
+ public SavedSearch getSavedSearchById(Subject subject, int savedSearchId) {
+ SavedSearch savedSearch = entityManager.find(SavedSearch.class, savedSearchId);
+ validateReadPermission(subject, savedSearch);
+ return savedSearch;
+ }
+
+ private void validateManipulatePermission(Subject subject, SavedSearch savedSearch)
{
+ if (savedSearch.isGlobal()) {
+ if (!authorizationManager.isInventoryManager(subject)) {
+ throw new PermissionException("Only inventory managers can
manipulate global saved searches");
+ }
+ // note: inventory managers can modify any saved search pattern, not just
their own
+ } else {
+ if (subject.equals(savedSearch.getSubject())) {
+ throw new PermissionException("Users without inventory manager
permission "
+ + "can only manipulate their own saved searches");
+ }
+ }
+ }
+
+ private void validateReadPermission(Subject subject, SavedSearch savedSearch) {
+ if (!savedSearch.isGlobal()) {
+ if (subject.equals(savedSearch.getSubject())) {
+ throw new PermissionException("Users without inventory manager
permission "
+ + "can only view their own or global saved saved
searches");
+ }
+ }
+ }
+}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
new file mode 100644
index 0000000..7ced552
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
@@ -0,0 +1,31 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.server.search;
+
+import javax.ejb.Local;
+
+/**
+ * The local interface to the SavedSearchManager.
+ *
+ * @author Joseph Marques
+ */
+@Local
+public interface SavedSearchManagerLocal extends SavedSearchManagerRemote {
+ // there are currently no methods in the local interface that do not exist in the
remote interface
+}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
new file mode 100644
index 0000000..a1615ec
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -0,0 +1,102 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 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.server.search;
+
+import javax.ejb.Remote;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.system.ServerVersion;
+
+/**
+ * The remote interface to the SavedSearchManager.
+ *
+ * @author Joseph Marques
+ */
+@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
+@WebService(targetNamespace = ServerVersion.namespace)
+@Remote
+public interface SavedSearchManagerRemote {
+
+ /**
+ * Persisted a new {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch}
deletion
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be deleted
+ *
+ * @throws PermissionException if the user is not authorized to create the {@link
SavedSearch}. Only inventory
+ * managers can create global saved searches. Regular users can only create
{@link SavedSearch}es against
+ * their own accounts.
+ */
+ @WebMethod
+ public void createSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearch") SavedSearch savedSearch);
+
+ /**
+ * Saves all changes to the passed {@link SavedSearch} database, correlating it to
the record already
+ * persisted with the same primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch}
persisted modification
+ * @param savedSearchId the {@link SavedSearch} which will have its modifications
persisted
+ *.
+ * @throws PermissionException if the user is not authorized to modify the {@link
SavedSearch}. Only inventory
+ * managers can update global saved searches. Regular users can only update
{@link SavedSearch}es from
+ * their own accounts.
+ */
+ @WebMethod
+ public void updateSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearch") SavedSearch savedSearch);
+
+ /**
+ * Deletes the {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch}
deletion
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be deleted
+ *
+ * @throws PermissionException if the user is not authorized to delete the {@link
SavedSearch}. Only inventory
+ * managers can delete global saved searches. Regular users can only delete
{@link SavedSearch}es from
+ * their own accounts.
+ */
+ @WebMethod
+ public void deleteSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearchId") int savedSearchId);
+
+ /**
+ * Returns the {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch} to be
loaded
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be loaded
+ *
+ * @return the {@link SavedSearch} or <code>null</code> if it wasn't
found
+ * @throws PermissionException if the user is not authorized to view the {@link
SavedSearch}. Regular users can
+ * only view {@link SavedSearch}es from their own accounts.
+ */
+ @WebMethod
+ public SavedSearch getSavedSearchById( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearchId") int savedSearchId);
+}
commit c95388946134a47b002f5821c3a168db6f549355
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:31 2010 -0500
saved search hibernate entities
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
new file mode 100644
index 0000000..9142772
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
@@ -0,0 +1,253 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.domain.search;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.rhq.core.domain.auth.Subject;
+
+/**
+ * The data model for saved searches. Each users has his or her own set of
+ * saved searches, but inventory managers are allowed to "promote" their
+ * saved searches to GLOBAL status, which makes them available to all users
+ * under that installation of RHQ.
+ *
+ * There are two levels of pre-computed data within this structured. After
+ * the {@link SavedSearch} is created, the pattern will be translated into its
+ * JPQL equivalent and stored. If the {@link SavedSearch} is ever modified
+ * and saved, the JPQL will be re-computed.
+ *
+ * Periodically, the count-query version of the {@link SavedSearch} will be
+ * executed (using the stored JPQL), and the number of matching records will
+ * be stored. If this {@link SavedSearch} ever needs to be displayed on the
+ * user interface, it will by default retrieve this cached result count.
+ *
+ * @author Joseph Marques
+ */
+@Entity
+@SequenceGenerator(name = "id", sequenceName =
"RHQ_SAVED_SEARCH_ID_SEQ")
+@Table(name = "RHQ_SAVED_SEARCH")
+public class SavedSearch {
+
+ @Id
+ @Column(name = "ID", nullable = false)
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "id")
+ private Integer id;
+
+ @Column(name = "CONTEXT", nullable = false)
+ @Enumerated(EnumType.STRING)
+ private SearchContext context;
+
+ @Column(name = "NAME")
+ private String name;
+
+ @Column(name = "DESCRIPTION")
+ private String description;
+
+ @Column(name = "PATTERN", nullable = false)
+ private String pattern;
+
+ @Column(name = "JPQL_TRANSLATION")
+ private String jpqlTranslation;
+
+ @Column(name = "LAST_COMPUTE_TIME", nullable = false)
+ private long lastComputeTime;
+
+ @Column(name = "RESULT_COUNT")
+ private Long resultCount;
+
+ @Column(name = "SUBJECT_ID", nullable = false)
+ private Subject subject;
+
+ @Column(name = "RESOURCE_ID", insertable = false, updatable = false)
+ private int subjectId;
+
+ @Column(name = "GLOBAL", nullable = false)
+ private boolean global;
+
+ protected SavedSearch() {
+ // no-arg ctor for Hibernate
+ }
+
+ public SavedSearch(SearchContext context, String name, String pattern, Subject
subject) {
+ // call setters to go through parameter validation
+ setContext(context);
+ setPattern(pattern);
+ setSubject(subject);
+ setName(name); // name can be null, to allow for saving searches quickly
+
+ this.description = null;
+ this.jpqlTranslation = null; // null value for pre-computed JPQL implies
computation is needed
+ this.lastComputeTime = 0; // further imply that computation needs to occur
+ this.resultCount = null; // NULL resultCount implies either computation failed or
hasn't begun yet
+ this.global = false; // user must promote saved search to be a global after
creation
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public SearchContext getContext() {
+ return context;
+ }
+
+ private void setContext(SearchContext context) {
+ if (context == null) {
+ throw new IllegalArgumentException("All saved searches must be bound to
a SearchContext");
+ }
+ this.context = context;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public void setPattern(String pattern) {
+ if (pattern == null || pattern.trim().equals("")) {
+ throw new IllegalArgumentException("All saved searches must have a
non-empty pattern");
+ }
+ this.pattern = pattern;
+ }
+
+ public String getJpqlTranslation() {
+ return jpqlTranslation;
+ }
+
+ public void setJpqlTransation(String jpqlTranslation) {
+ this.jpqlTranslation = jpqlTranslation;
+ }
+
+ public long getLastComputeTime() {
+ return lastComputeTime;
+ }
+
+ public void setLastComputeTime(long lastComputeTime) {
+ this.lastComputeTime = lastComputeTime;
+ }
+
+ public Long getResultCount() {
+ return resultCount;
+ }
+
+ public void setResultCount(Long resultCount) {
+ this.resultCount = resultCount;
+ }
+
+ public Subject getSubject() {
+ return subject;
+ }
+
+ private void setSubject(Subject subject) {
+ if (subject == null) {
+ throw new IllegalArgumentException("All saved searches must be owned by
a specific user");
+ }
+ this.subject = subject;
+ this.subjectId = subject.getId();
+ }
+
+ public int getSubjectId() {
+ return subjectId;
+ }
+
+ public boolean isGlobal() {
+ return global;
+ }
+
+ public void setGlobal(boolean global) {
+ this.global = global;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + subjectId;
+ result = (prime * result) + context.hashCode();
+ result = (prime * result) + ((name == null) ? 0 : name.hashCode());
+ result = (prime * result) + pattern.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if ((obj == null) || (!(obj instanceof SavedSearch))) {
+ return false;
+ }
+
+ final SavedSearch other = (SavedSearch) obj;
+
+ if (subjectId != other.subjectId) {
+ return false;
+ }
+
+ if (context != other.context) {
+ return false;
+ }
+
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+
+ if (!pattern.equals(other.pattern)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
new file mode 100644
index 0000000..bb045d5
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
@@ -0,0 +1,38 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.domain.search;
+
+/**
+ * The search mechanism is generic and, thus, suited to finding data in any
+ * RHQ subsystem, including its own. Each individual page in the UI can have
+ * different advanced syntax. This enum will serve as a unique identifier
+ * for which context is currently active. You can think of it as a piece of
+ * meta-data that annotates each saved search, representing which context it
+ * belongs to. This will also affect which grammar is used to auto-complete
+ * search expressions.
+ *
+ * @author Joseph Marques
+ */
+public enum SearchContext {
+ Resource, Group;
+}
commit c9d080cc510d6e4bf5c26c34f7b9050544736da3
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:19 2010 -0500
saved search dbupgrade scripts
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 1d4d3dd..2fb6a90 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.79</db.schema.version>
+ <db.schema.version>2.82</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 9af6aa5..834e9ce 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3202,6 +3202,31 @@
</statement>
</schema-directSQL>
</schemaSpec>
+
+ <schemaSpec version="2.82">
+ <schema-directSQL>
+ <statement desc="Creating table RHQ_SAVED_SEARCH">
+ CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
+ </statement>
+ </schema-directSQL>
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="CONTEXT" columnType="VARCHAR2" precision="25" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH"
column="CONTEXT" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="NAME" columnType="VARCHAR2" precision="200" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="DESCRIPTION" columnType="VARCHAR2" precision="500"
/>
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="PATTERN" columnType="VARCHAR2" precision="1000"
/>
+ <schema-alterColumn table="RHQ_SAVED_SEARCH"
column="PATTERN" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="JPQL_TRANSLATION" columnType="VARCHAR2"
precision="4000" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="LAST_COMPUTE_TIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH"
column="LAST_COMPUTE_TIME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="RESULT_COUNT" columnType="LONG" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="SUBJECT_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH"
column="SUBJECT_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" columnType="BOOLEAN" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH"
column="GLOBAL" nullable="FALSE" />
+ </schemaSpec>
</dbupgrade>
</target>
</project>
commit afc78a9b2bfcb14b5b079ffb29aa82c4e6b0e81f
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:07 2010 -0500
saved searches dbsetup scripts
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index 047d615..f5e4eae 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties
to true:
<property name="dbsetup.scripts.dir"
value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir"
value="${basedir}/target/dbsetup" /> <!-- away from classes so it
doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the
reverse order -->
- <property name="dbsetup.subsystems"
value="config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems"
value="search,config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema"
value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data"
value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file"
value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
new file mode 100644
index 0000000..7c0de23
--- /dev/null
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<dbsetup name="amps-schema.xml"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-dbsetup-schema">
+
+ <table name="RHQ_SAVED_SEARCH">
+ <column name="ID" default="sequence-only"
initial="10001" primarykey="true" required="true"
type="INTEGER"/>
+ <column name="CONTEXT" type="VARCHAR2" size="25"
required="true"/>
+
+ <column name="NAME" type="VARCHAR2" size="200"
required="true"/>
+ <column name="DESCRIPTION" type="VARCHAR2"
size="500" required="false"/>
+ <column name="PATTERN" type="VARCHAR2"
size="1000" required="true"/>
+
+ <column name="JPQL_TRANSLATION" type="VARCHAR2"
size="4000" required="false"/>
+ <column name="LAST_COMPUTE_TIME" type="LONG"
required="true"/>
+ <column name="RESULT_COUNT" type="LONG"
required="false"/>
+
+ <column name="SUBJECT_ID" type="INTEGER"
references="RHQ_SUBJECT" required="true"/>
+ <column name="ENABLED" type="BOOLEAN"
required="true"/>
+ </table>
+
+</dbsetup>
\ No newline at end of file
commit 6d87241b69c095bd2928f4e3b03bc9dcfbeeefd1
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 10:49:01 2010 +0100
Fix potential NPE
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index 5ed6d4f..b90def3 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -113,8 +113,8 @@ public class AlertNotificationLog implements Serializable {
@PrePersist
@PreUpdate
public void trimMessage() {
- if (message.length()>255)
- message = message.substring(0,254);
+ if (message!=null && message.length()>255)
+ message = message.substring(0,255);
}
protected AlertNotificationLog() {
commit 2d38d85bb4500c1a873aba7b193fb9984d00539d
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 09:47:10 2010 +0100
Truncate the message at 140 chars, as identi.ca bails out on longer messages; seems to
improve stability with Twitter too.
Introduce abbreviated versions of the messages as space on Microblog etc is scarce. BZ
555091
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index ba75940..5ed6d4f 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -38,6 +38,8 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -108,6 +110,13 @@ public class AlertNotificationLog implements Serializable {
@Transient
transient List<String> transientEmails = new ArrayList<String>();
+ @PrePersist
+ @PreUpdate
+ public void trimMessage() {
+ if (message.length()>255)
+ message = message.substring(0,254);
+ }
+
protected AlertNotificationLog() {
} // JPA
@@ -130,7 +139,6 @@ public class AlertNotificationLog implements Serializable {
public AlertNotificationLog(Alert alert, String senderName, ResultState state, String
message) {
this.alert = alert;
- this.sender = sender;
this.resultState = state;
this.message = message;
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
index 454b9a9..ff4025f 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
@@ -780,7 +780,7 @@ public class AlertManagerBean implements AlertManagerLocal,
AlertManagerRemote {
Map<String, String> alertMessage = emailManager.getAlertEmailMessage(
prettyPrintResourceHierarchy(alertDefinition.getResource()),
alertDefinition.getResource().getName(),
alertDefinition.getName(), alertDefinition.getPriority().toString(), new
Date(alert.getCtime()).toString(),
- prettyPrintAlertConditions(alert.getConditionLogs()),
prettyPrintAlertURL(alert));
+ prettyPrintAlertConditions(alert.getConditionLogs(), false),
prettyPrintAlertURL(alert));
String messageSubject = alertMessage.keySet().iterator().next();
String messageBody = alertMessage.values().iterator().next();
@@ -834,13 +834,14 @@ public class AlertManagerBean implements AlertManagerLocal,
AlertManagerRemote {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- public String prettyPrintAlertConditions(Alert alert) {
- return prettyPrintAlertConditions(alert.getConditionLogs());
+ public String prettyPrintAlertConditions(Alert alert, boolean shortVersion) {
+ return prettyPrintAlertConditions(alert.getConditionLogs(), shortVersion);
}
- private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs)
{
+ private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs,
boolean shortVersion) {
StringBuilder builder = new StringBuilder();
int conditionCounter = 1;
@@ -858,16 +859,27 @@ public class AlertManagerBean implements AlertManagerLocal,
AlertManagerRemote {
builder.append(NEW_LINE);
-
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT,
- conditionCounter, prettyPrintAlertCondition(aLog.getCondition()), new
SimpleDateFormat(
- "yyyy/MM/dd HH:mm:ss z").format(new Date(aLog.getCtime())),
formattedValue));
+ String format;
+ if (shortVersion)
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT;
+ else
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT;
+ SimpleDateFormat dateFormat;
+ if (shortVersion)
+ dateFormat= new SimpleDateFormat(
+ "yy/MM/dd HH:mm:ss z");
+ else
+ dateFormat= new SimpleDateFormat(
+ "yyyy/MM/dd HH:mm:ss z");
+ builder.append(AlertI18NFactory.getMessage(format,
+ conditionCounter, prettyPrintAlertCondition(aLog.getCondition(),
shortVersion), dateFormat.format(new Date(aLog.getCtime())), formattedValue));
conditionCounter++;
}
return builder.toString();
}
- private String prettyPrintAlertCondition(AlertCondition condition) {
+ private String prettyPrintAlertCondition(AlertCondition condition, boolean
shortVersion) {
StringBuilder builder = new StringBuilder();
AlertConditionCategory category = condition.getCategory();
@@ -915,19 +927,38 @@ public class AlertManagerBean implements AlertManagerLocal,
AlertManagerRemote {
}
} else if ((category == AlertConditionCategory.RESOURCE_CONFIG) || (category ==
AlertConditionCategory.CHANGE)
|| (category == AlertConditionCategory.TRAIT)) {
-
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
+ if (shortVersion)
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT));
+ else
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
} else if (category == AlertConditionCategory.EVENT) {
if ((condition.getOption() != null) &&
(condition.getOption().length() > 0)) {
+ String propsCbEventSeverityRegexMatch;
+ if (shortVersion)
+ propsCbEventSeverityRegexMatch =
AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT;
+ else
+ propsCbEventSeverityRegexMatch =
AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH;
+
builder.append(AlertI18NFactory.getMessage(
-
AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH,
condition.getName(),
+ propsCbEventSeverityRegexMatch, condition.getName(),
condition.getOption()));
} else {
-
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
- condition.getName()));
+ if (shortVersion)
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT,
+ condition.getName()));
+ else
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
+ condition.getName()));
}
} else if (category == AlertConditionCategory.AVAILABILITY) {
-
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
- condition.getOption()));
+ if (shortVersion)
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT,
+ condition.getOption()));
+ else
+
builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
+ condition.getOption()));
} else {
// do nothing
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
index 996f245..e482ffa 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
@@ -96,9 +96,10 @@ public interface AlertManagerLocal {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- String prettyPrintAlertConditions(Alert alert);
+ String prettyPrintAlertConditions(Alert alert, boolean shortVersion);
/**
* Tells us if the definition of the passed alert will be disabled after this alert
was fired
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
index 8734771..1de3d85 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
@@ -32,20 +32,41 @@ public interface AlertI18NResourceKeys {
@I18NMessage(locale = "de", value = "Verfgbarkeit wird {0}")
})
String ALERT_CONFIG_PROPS_CB_AVAILABILITY =
"alert.config.props.CB.Availability";
+ @I18NMessages( { @I18NMessage("Avail goes {0}"),
+ @I18NMessage(locale = "de", value = "Verf. wird {0}") })
+ String ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT =
"alert.config.props.CB.Availability.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0}"),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses:
{0}") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY =
"alert.config.props.CB.EventSeverity";
+ @I18NMessages( { @I18NMessage("Sev: {0}"),
+ @I18NMessage(locale = "de", value = "Schwere: {0}") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT =
"alert.config.props.CB.EventSeverity.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0} and matching expression
\"{1}\""),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses: {0}
und zugehriger Ausdruck \"{1}\"") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH =
"alert.config.props.CB.EventSeverity.RegexMatch";
+ @I18NMessages( { @I18NMessage("Sev: {0} & exp \"{1}\""),
+ @I18NMessage(locale = "de", value = "Schwere: {0} & Ausdruck
\"{1}\"") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT =
"alert.config.props.CB.EventSeverity.RegexMatch.short";
+
@I18NMessages( { @I18NMessage("value changed"), @I18NMessage(locale =
"de", value = "Der Wert hat sich gendert") })
String ALERT_CURRENT_LIST_VALUE_CHANGED =
"alert.current.list.ValueChanged";
+ @I18NMessages( { @I18NMessage("val chg"), @I18NMessage(locale =
"de", value = "Wertnd.") })
+ String ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT =
"alert.current.list.ValueChanged.short";
+
@I18NMessages( {
@I18NMessage("\\ - Condition {0}: {1}\\n\\\n" + "\\ - Date/Time:
{2}\\n\\\n" + "\\ - Details: {3}\\n\\\n"),
@I18NMessage(locale = "de", value = " - Bedingung {0}: {1}\\n\\\n
- Datum/Uhrzeit: {2}\\n\\\n"
+ "\\ - Details: {3}\\n\\\n") })
String ALERT_EMAIL_CONDITION_LOG_FORMAT =
"alert.email.condition.log.format";
+
+ @I18NMessages( {
+ @I18NMessage("\\ - Cond {0}: {1}\\n\\\n" + "\\ - Time:
{2}\\n\\\n" + "\\ - Det: {3}\\n\\\n"),
+ @I18NMessage(locale = "de", value = " - Bed {0}: {1}\\n\\\n -
Zeit: {2}\\n\\\n"
+ + "\\ - Det: {3}\\n\\\n") })
+ String ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT =
"alert.email.condition.log.format.short";
}
\ No newline at end of file
diff --git
a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
index 93eecc6..95abdb9 100644
---
a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
+++
b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
@@ -65,7 +65,7 @@ public class IrcSender extends AlertSender<IrcAlertComponent> {
b.append("): ");
b.append(alertManager.prettyPrintAlertURL(alert));
b.append("\n");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
return b.toString();
}
diff --git
a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
index 257b315..b13763e 100644
---
a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
+++
b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
@@ -57,14 +57,19 @@ public class MicroblogSender extends AlertSender {
b.append("' (");
b.append(alert.getAlertDefinition().getResource().getId());
b.append("): ");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, true));
b.append("-by @JBossJopr"); // TODO not for production :-)
// TODO use some alert url shortening service
SenderResult result ;
String txt = "user@baseUrl [" + user + "@" + baseUrl +
"]:";
try {
- Status status = twitter.updateStatus(b.toString());
+ String msg = b.toString();
+ if (msg.length()>140)
+ msg = msg.substring(0,140);
+
+ Status status = twitter.updateStatus(msg);
+
result = new SenderResult(ResultState.SUCCESS,"Send notification to
" + txt + ", msg-id: " + status.getId());
} catch (TwitterException e) {
diff --git
a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
index 649d6ed..b14c85d 100644
---
a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
+++
b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
@@ -74,7 +74,7 @@ public class MobicentsSender extends AlertSender {
// Switch locale to english, as the voice synthesizer expects this for
now
Locale currentLocale = Locale.getDefault();
Locale.setDefault(Locale.ENGLISH);
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
Locale.setDefault(currentLocale);
boolean willBeDisabled = alertManager.willDefinitionBeDisabled(alert);
diff --git
a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
index 985d890..bac51fb 100644
---
a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
+++
b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
@@ -93,7 +93,7 @@ public class ScriptLangSender extends
AlertSender<ScriptLangComponent> {
Object[] args = new Object[3];
args[0] = alert;
args[1] = alertManager.prettyPrintAlertURL(alert);
- args[2] = alertManager.prettyPrintAlertConditions(alert);
+ args[2] = alertManager.prettyPrintAlertConditions(alert, false);
result = ((Invocable) engine).invokeFunction("sendAlert", args);
if (result == null) {
diff --git
a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
index 3fd5d79..045c3bb 100644
---
a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
+++
b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
@@ -68,7 +68,7 @@ public class SnmpSender extends AlertSender {
String result;
List<Resource> lineage =
resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId());
String platformName = lineage.get(0).getName();
- String conditions = alertManager.prettyPrintAlertConditions(alert);
+ String conditions = alertManager.prettyPrintAlertConditions(alert, false);
String alertUrl = alertManager.prettyPrintAlertURL(alert);
SenderResult res ;
commit 798ac30ead634c43a72beed52446a38d9bfc1f09
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:51:53 2010 -0500
i think this should report an error always on lock acq failure. we'll leave the
flag alone - don't set it to true - let the next call take care of whether or not the
init callback should be invoked or not
diff --git
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 8c37b50..cd3b479 100644
---
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,11 +588,9 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
writeLock.unlock();
}
} else {
- if (m_needToCallInitializeCallback) {
- Throwable t = new Throwable("Initialize callback lock could not
be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
- }
+ Throwable t = new Throwable("Initialize callback lock could not be
acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 9746ea32492b638eacb741d608d9ce17349c925d
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:44:11 2010 -0500
should not worry about the lock failure if the init callback doesn't need to be
invoked anyway
diff --git
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 762b9b4..8c37b50 100644
---
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,10 +588,11 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
writeLock.unlock();
}
} else {
- m_needToCallInitializeCallback = true; // can't invoke callback,
we'll want to still call it later
- Throwable t = new Throwable("Initialize callback lock could not be
acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
+ if (m_needToCallInitializeCallback) {
+ Throwable t = new Throwable("Initialize callback lock could not
be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
}
return null;
commit c2cca917c88986ca48c84bbbdaf3408753299bf1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:38:16 2010 -0500
BZ 537396 - to not block indefinitely if a lock cannot be acquired before attempting
to invoke the initialize callback
diff --git
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 3775212..762b9b4 100644
---
a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++
b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -21,6 +21,9 @@ package org.rhq.enterprise.communications.command.client;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import mazz.i18n.Logger;
@@ -95,10 +98,22 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
private InitializeCallback m_initializeCallback;
/**
- * When the first element is <code>true</code>, the initialize callback
will need to be called prior
- * to sending any commands. This is an array because the array itself is used for its
lock.
+ * When <code>true</code>, the initialize callback will need to be called
prior
+ * to sending any commands. Used in conjunection with its associated RW lock.
*/
- private final boolean[] m_needToCallInitializeCallback;
+ private boolean m_needToCallInitializeCallback;
+
+ /**
+ * RW lock when needing to access its associated atomic boolean flag.
+ */
+ private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
+
+ /**
+ * Number of minutes to wait while attempting to aquire a lock before attempting
+ * to invoke the initialize callback. If this amount of minutes expires before the
lock
+ * is acquired, an error will occur and the initialize callback will have to be
attempted later.
+ */
+ private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
* Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the
client with no invoker locator
@@ -200,7 +215,17 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
m_clientConfiguration.putAll(client_config);
}
- m_needToCallInitializeCallback = new boolean[] { false };
+ m_needToCallInitializeCallback = false;
+ m_needToCallInitializeCallbackLock = new ReentrantReadWriteLock();
+
+ long mins;
+ try {
+ String minsStr =
System.getProperty("rhq.communications.initial-callback-lock-wait-mins",
"60");
+ mins = Long.parseLong(minsStr);
+ } catch (Throwable t) {
+ mins = 60L;
+ }
+ m_initializeCallbackLockAcquisitionTimeoutMins = mins;
return;
}
@@ -319,7 +344,7 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
m_remotingClient = null;
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); //
specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); //
specifically do not synchrononize by using lock, just set it
}
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator,
locator);
@@ -377,7 +402,7 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback[0] = (callback != null); // specifically do not
synchronize, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not
synchrononize by using lock, just set it
}
public String getRemoteEndpoint() {
@@ -403,7 +428,7 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
public void connect() throws Exception {
if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
m_remotingClient.connect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); //
specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); //
specifically do not synchrononize by using lock, just set it
}
return;
@@ -412,7 +437,7 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
public void disconnect() {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); //
specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); //
specifically do not synchrononize by using lock, just set it
}
return;
@@ -535,18 +560,38 @@ public class JBossRemotingRemoteCommunicator implements
RemoteCommunicator {
private CommandResponse invokeInitializeCallbackIfNeeded(Command command) {
InitializeCallback callback = getInitializeCallback();
if (callback != null) {
- // block here - in effect, this will stop all commands from going out until
the callback is done
- synchronized (m_needToCallInitializeCallback) {
- if (m_needToCallInitializeCallback[0]) {
- try {
- m_needToCallInitializeCallback[0] =
!callback.sendingInitialCommand(this, command);
- LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE,
m_needToCallInitializeCallback[0]);
- } catch (Throwable t) {
- m_needToCallInitializeCallback[0] = true; // callback failed,
we'll want to call it again
- LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
ThrowableUtil.getAllMessages(t));
- return new GenericCommandResponse(command, false, null, t);
+ // block here - in effect, this will stop all commands from going out until
the callback is done
+ // to avoid infinite blocking, we'll only wait for a set time (though
long).
+
+ WriteLock writeLock = m_needToCallInitializeCallbackLock.writeLock();
+ boolean locked;
+ try {
+ locked =
writeLock.tryLock(m_initializeCallbackLockAcquisitionTimeoutMins, TimeUnit.MINUTES);
+ } catch (InterruptedException ie) {
+ locked = false;
+ }
+
+ if (locked) {
+ try {
+ if (m_needToCallInitializeCallback) {
+ try {
+ m_needToCallInitializeCallback =
(!callback.sendingInitialCommand(this, command));
+ LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE,
m_needToCallInitializeCallback);
+ } catch (Throwable t) {
+ m_needToCallInitializeCallback = true; // callback failed,
we'll want to call it again
+ LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
ThrowableUtil
+ .getAllMessages(t));
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
+ } finally {
+ writeLock.unlock();
}
+ } else {
+ m_needToCallInitializeCallback = true; // can't invoke callback,
we'll want to still call it later
+ Throwable t = new Throwable("Initialize callback lock could not be
acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED,
t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 55ba6f8778820bdd417e99909220136a2e1e091f
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 11:10:53 2010 -0500
BZ 566724 - if classloader fails to be created, master PC will skip the plugin
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
index f46eaf5..bd4feac 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
@@ -136,16 +136,23 @@ public class MasterServerPluginContainer {
String pluginName = descriptor.getName();
ServerPluginType pluginType = new ServerPluginType(descriptor);
PluginKey pluginKey =
PluginKey.createServerPluginKey(pluginType.stringify(), pluginName);
- ClassLoader classLoader =
this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
- log.debug("Pre-loading server plugin [" + pluginKey +
"] from [" + pluginUrl
- + "] into its plugin container");
try {
- ServerPluginEnvironment env = new
ServerPluginEnvironment(pluginUrl, classLoader, descriptor);
- boolean enabled = !allDisabledPlugins.contains(pluginKey);
- pc.loadPlugin(env, enabled);
- log.info("Preloaded server plugin [" +
pluginKey.getPluginName() + "]");
+ ClassLoader classLoader =
this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
+ log.debug("Pre-loading server plugin [" + pluginKey +
"] from [" + pluginUrl
+ + "] into its plugin container");
+ try {
+ ServerPluginEnvironment env = new
ServerPluginEnvironment(pluginUrl, classLoader,
+ descriptor);
+ boolean enabled = !allDisabledPlugins.contains(pluginKey);
+ pc.loadPlugin(env, enabled);
+ log.info("Preloaded server plugin [" + pluginName +
"]");
+ } catch (Exception e) {
+ log.warn("Failed to preload server plugin [" +
pluginName + "] from URL [" + pluginUrl
+ + "]", e);
+ }
} catch (Exception e) {
- log.warn("Failed to preload server plugin [" +
pluginUrl + "]", e);
+ log.warn("Failed to preload server plugin [" +
pluginName
+ + "]; cannot get its classloader from URL [ " +
pluginUrl + "]", e);
}
} else {
log.warn("There is no server plugin container to support plugin:
" + pluginUrl);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
index 9f27ce9..fa26970 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
@@ -64,7 +64,7 @@ public class ServerPluginClassLoader extends URLClassLoader {
try {
unpackedDirectory = unpackEmbeddedJars(pluginJarName, pluginUrl,
classpathUrlList, tmpDirectory);
} catch (Exception e) {
- throw new Exception("Failed to unpack embedded JARs within:
" + pluginUrl);
+ throw new Exception("Failed to unpack embedded JARs within:
" + pluginUrl, e);
}
}
}
commit 2ffc564d7ff69a427755fa374419bc5980e47f94
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Fri Feb 19 13:37:36 2010 +0100
Fix link to definitions BZ 566004
diff --git
a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
index b6e386c..fd09f82 100644
---
a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
+++
b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
@@ -148,8 +148,7 @@
</onc:sortableColumnHeader>
</f:facet>
- <h:outputLink value="/alerts/Config.do">
- <f:param name="mode" value="viewRoles"/>
+ <h:outputLink
value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="id"
value="#{Resource.id}"/>
<f:param name="ad"
value="#{item.alert.alertDefinition.id}"/>
<h:outputText
value="#{item.alert.alertDefinition.name}" />