modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
| 14
modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseTypeFactory.java
| 26
modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
| 14
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/EventCriteria.java
| 18
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
| 6
modules/core/domain/src/main/java/org/rhq/core/domain/event/EventSource.java
| 3
modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryGenerator.java
| 433 ---------
modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryRunner.java
| 84 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java
| 12
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
| 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ChannelManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/event/EventManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
| 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDefinitionManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
| 65 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/util/MeasurementDataManagerUtility.java
| 53 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerBean.java
| 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
| 443 ++++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
| 84 +
modules/plugins/platform/src/main/java/org/rhq/plugins/platform/CpuComponent.java
| 186 +++-
27 files changed, 874 insertions(+), 629 deletions(-)
New commits:
commit ba2a3f1cfc7090c99c33a1bd0590d20bbf6ac35a
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Oct 28 17:40:04 2009 -0400
Merge in JON 2.3 patch work. [RHQ-2445]
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
new file mode 100644
index 0000000..721fbb8
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -0,0 +1,443 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.annotations.IndexColumn;
+
+import org.rhq.core.db.DatabaseTypeFactory;
+import org.rhq.core.domain.criteria.AlertCriteria;
+import org.rhq.core.domain.criteria.Criteria;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
+import org.rhq.core.domain.criteria.SubjectCriteria;
+import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.util.OrderingField;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.core.domain.util.PersistenceUtility;
+
+/**
+ * A query generator used to generate queries with specific filtering, prefetching, or
sorting requirements.
+ *
+ * @author Joseph Marques
+ */
+public final class CriteriaQueryGenerator {
+
+ private static final Log LOG = LogFactory.getLog(CriteriaQueryGenerator.class);
+
+ 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
+ }
+
+ private Criteria criteria;
+
+ private String authorizationJoinFragment;
+ private int authorizationSubjectId;
+
+ private String alias;
+ private String className;
+ private static String NL = System.getProperty("line.separator");
+ private static String ESCAPE_CHARACTER = null;
+
+ private List<Field> persistentBagFields = new ArrayList<Field>();
+
+ public CriteriaQueryGenerator(Criteria criteria) {
+ this.criteria = criteria;
+
+ String criteriaClassName = criteria.getClass().getSimpleName();
+ className = criteriaClassName.substring(0, criteriaClassName.length() - 8);
+
+ StringBuilder aliasBuilder = new StringBuilder();
+ for (char c : this.className.toCharArray()) {
+ if (Character.isUpperCase(c)) {
+ aliasBuilder.append(Character.toLowerCase(c));
+ }
+ }
+ this.alias = aliasBuilder.toString();
+ }
+
+ public void setAuthorizationResourceFragment(AuthorizationTokenType type, int
subjectId) {
+ String defaultFragment = null;
+ if (type == AuthorizationTokenType.RESOURCE) {
+ defaultFragment = "resource";
+ } else if (type == AuthorizationTokenType.GROUP) {
+ defaultFragment = "group";
+ }
+ setAuthorizationResourceFragment(type, defaultFragment, subjectId);
+ }
+
+ private String fixFilterOverride(String expression, String fieldName) {
+ boolean fuzzyMatch = expression.toLowerCase().indexOf(" like ") != -1;
+ boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive() &&
fuzzyMatch;
+
+ while (expression.indexOf('?') != -1) {
+ String replacement = ":" + fieldName;
+ expression = expression.replaceFirst("\\?", replacement);
+ }
+
+ if (wantCaseInsensitiveMatch) {
+ int indexOfFirstSpace = expression.indexOf(" ");
+ String filterToken = expression.substring(0, indexOfFirstSpace);
+ expression = "LOWER( " + alias + "." + filterToken +
" ) " + expression.substring(indexOfFirstSpace);
+ } else {
+ expression = alias + "." + expression;
+ }
+
+ if (fuzzyMatch) {
+ expression += " ESCAPE '" + getEscapeCharacter() +
"'";
+ }
+
+ return expression;
+ }
+
+ public void setAuthorizationResourceFragment(AuthorizationTokenType type, String
fragment, int subjectId) {
+ this.authorizationSubjectId = subjectId;
+ if (type == AuthorizationTokenType.RESOURCE) {
+ if (fragment == null) {
+ this.authorizationJoinFragment = "" //
+ + "JOIN " + alias + ".implicitGroups authGroup "
+ NL //
+ + "JOIN authGroup.roles authRole " + NL //
+ + "JOIN authRole.subjects authSubject " + NL;
+ } else {
+ this.authorizationJoinFragment = "" //
+ + "JOIN " + alias + "." + fragment + "
authRes " + NL //
+ + "JOIN authRes.implicitGroups authGroup " + NL //
+ + "JOIN authGroup.roles authRole " + NL //
+ + "JOIN authRole.subjects authSubject " + NL;
+ }
+ } else if (type == AuthorizationTokenType.GROUP) {
+ if (fragment == null) {
+ this.authorizationJoinFragment = "" //
+ + "JOIN " + alias + ".roles authRole " + NL //
+ + "JOIN authRole.subjects authSubject " + NL;
+ } else {
+ this.authorizationJoinFragment = "" //
+ + "JOIN " + alias + "." + fragment + "
authGroup " + NL //
+ + "JOIN authGroup.roles authRole " + NL //
+ + "JOIN authRole.subjects authSubject " + NL;
+ }
+ } else {
+ throw new IllegalArgumentException(this.getClass().getSimpleName()
+ + " does not yet support generating queries for '" + type +
"' token types");
+ }
+ }
+
+ // for testing purposes only, should use getQuery(EntityManager) or
getCountQuery(EntityManager) instead
+ public String getQueryString(boolean countQuery) {
+ StringBuilder results = new StringBuilder();
+ results.append("SELECT ");
+ if (countQuery) {
+
results.append("COUNT(").append(alias).append(")").append(NL);
+ } else {
+ results.append(alias).append(NL);
+ }
+ results.append("FROM ").append(className).append('
').append(alias).append(NL);
+ if (countQuery == false) {
+ /*
+ * don't fetch in the count query to avoid: "query specified join
fetching,
+ * but the owner of the fetched association was not present in the select
list"
+ */
+ for (String fetchJoin : criteria.getFetchFields()) {
+ if (isPersistentBag(fetchJoin)) {
+ addPersistentBag(fetchJoin);
+ } else {
+ results.append("LEFT JOIN FETCH
").append(alias).append('.').append(fetchJoin).append(NL);
+ }
+ }
+ }
+ if (authorizationJoinFragment != null) {
+ results.append(authorizationJoinFragment);
+ }
+
+ Map<String, Object> filterFields = criteria.getFilterFields();
+ if (filterFields.size() > 0 || authorizationJoinFragment != null) {
+ results.append("WHERE ");
+ }
+
+ String conjunctiveFragment = criteria.isFiltersOptional() ? "OR " :
"AND ";
+ boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive();
+
+ // criteria
+ StringBuilder conjunctiveResults = new StringBuilder();
+ boolean firstCrit = true;
+ for (Map.Entry<String, Object> filterField : filterFields.entrySet()) {
+ if (firstCrit) {
+ firstCrit = false;
+ } else {
+ conjunctiveResults.append(NL).append(conjunctiveFragment);
+ }
+ String fieldName = filterField.getKey();
+ String override = criteria.getJPQLFilterOverride(fieldName);
+ String fragment = null;
+ if (override != null) {
+ fragment = fixFilterOverride(override, fieldName);
+ } else {
+ String operator = "=";
+ if (filterField.getValue() instanceof String) {
+ operator = "like";
+ if (wantCaseInsensitiveMatch) {
+ fragment = "LOWER( " + alias + "." +
fieldName + " ) " + operator + " :" + fieldName;
+ } else {
+ fragment = alias + "." + fieldName + " " +
operator + " :" + fieldName;
+ }
+ fragment += " ESCAPE '" + getEscapeCharacter() +
"'";
+ } else {
+ fragment = alias + "." + fieldName + " " +
operator + " :" + fieldName;
+ }
+ }
+
+ conjunctiveResults.append(fragment).append(' ');
+ }
+
+ if (conjunctiveResults.length() > 0) {
+ results.append("(
").append(conjunctiveResults).append(")");
+ }
+
+ // authorization
+ if (authorizationJoinFragment != null) {
+ if (firstCrit) {
+ firstCrit = false;
+ } else {
+ // always want AND for security, regardless of conjunctiveFragment
+ results.append(NL).append(" AND ");
+ }
+ results.append("authSubject.id = " + authorizationSubjectId +
" ");
+ }
+
+ if (countQuery == false) {
+ boolean overridden = true;
+ PageControl pc = criteria.getPageControlOverrides();
+ if (pc == null) {
+ overridden = false;
+ pc = criteria.getPageControl();
+ }
+
+ boolean first = true;
+ for (OrderingField orderingField : pc.getOrderingFields()) {
+ if (first) {
+ results.append(NL).append("ORDER BY ");
+ first = false;
+ } else {
+ results.append(", ");
+ }
+
+ if (overridden) {
+ String fieldName = orderingField.getField();
+ PageOrdering ordering = orderingField.getOrdering();
+
+ results.append(fieldName).append(' ').append(ordering);
+ } else {
+ String fieldName = orderingField.getField();
+ String override = criteria.getJPQLSortOverride(fieldName);
+ String fragment = override != null ? override : fieldName;
+
+ results.append(alias).append('.').append(fragment);
+ results.append(' ').append(orderingField.getOrdering());
+ }
+ }
+ }
+ results.append(NL);
+
+ LOG.debug(results);
+ System.out.println(results);
+ return results.toString();
+ }
+
+ private boolean isPersistentBag(String fieldName) {
+ try {
+ Class<?> persistentClass = criteria.getPersistentClass();
+ Field field = persistentClass.getDeclaredField(fieldName);
+
+ return isAList(field) &&
!field.isAnnotationPresent(IndexColumn.class);
+ } catch (NoSuchFieldException e) {
+ return false;
+ }
+ }
+
+ private boolean isAList(Field field) {
+ Class<?> fieldType = field.getType();
+
+ if (List.class.isAssignableFrom(fieldType)) {
+ return true;
+ }
+
+ for (Class declaredInterface : fieldType.getInterfaces()) {
+ if (List.class.isAssignableFrom(declaredInterface)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void addPersistentBag(String fieldName) {
+ try {
+ Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
+ persistentBagFields.add(field);
+ } catch (NoSuchFieldException e) {
+ LOG.warn("Failed to add persistent bag collection.", e);
+ }
+ }
+
+ /**
+ * <strong>Note:</strong> This method should only be called after {@link
#getQueryString(boolean)}} because it is
+ * that method where the persistentBagFields property is initialized.
+ *
+ * @return Returns a list of fields from the persistent class to which the criteria
class corresponds. The fields in
+ * the list are themselves instances of List and have "bag" semantics.
+ */
+ public List<Field> getPersistentBagFields() {
+ return persistentBagFields;
+ }
+
+ public Query getQuery(EntityManager em) {
+ String queryString = getQueryString(false);
+ Query query = em.createQuery(queryString);
+ setBindValues(query, false);
+ PersistenceUtility.setDataPage(query, criteria.getPageControl());
+ return query;
+ }
+
+ public Query getCountQuery(EntityManager em) {
+ String countQueryString = getQueryString(true);
+ Query query = em.createQuery(countQueryString);
+ setBindValues(query, false);
+ return query;
+ }
+
+ private void setBindValues(Query query, boolean countQuery) {
+ boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive();
+ boolean wantsFuzzyMatching = !criteria.isStrict();
+ boolean handleEscapedBackslash = "\\\\".equals(getEscapeCharacter());
+
+ for (Map.Entry<String, Object> critField :
criteria.getFilterFields().entrySet()) {
+ Object value = critField.getValue();
+ if (value instanceof String) {
+ String formattedValue = (String) value;
+ if (wantCaseInsensitiveMatch) {
+ formattedValue = formattedValue.toLowerCase();
+ }
+ /*
+ * Double escape backslashes if they are not treated as string literals
by the db vendor
+ *
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674
+ */
+ if (handleEscapedBackslash) {
+ formattedValue = ((String)
formattedValue).replaceAll("\\_", "\\\\_");
+ }
+ if (wantsFuzzyMatching) {
+ // append '%' onto edges that don't already have
'%' explicitly set from the caller
+ formattedValue = (formattedValue.startsWith("%") ?
"" : "%") + formattedValue
+ + (formattedValue.endsWith("%") ? "" :
"%");
+ }
+ value = formattedValue;
+ }
+ LOG.debug("Bind: (" + critField.getKey() + ", " + value +
")");
+ query.setParameter(critField.getKey(), value);
+ }
+ }
+
+ public static String getEscapeCharacter() {
+ if (null == ESCAPE_CHARACTER) {
+ ESCAPE_CHARACTER =
DatabaseTypeFactory.getDefaultDatabaseType().getEscapeCharacter();
+ }
+
+ return ESCAPE_CHARACTER;
+ }
+
+ public static void main(String[] args) {
+ //testSubjectCriteria();
+ //testAlertCriteria();
+ //testInheritanceCriteria();
+ testResourceCriteria();
+ }
+
+ public static void testSubjectCriteria() {
+ SubjectCriteria subjectCriteria = new SubjectCriteria();
+ subjectCriteria.addFilterFirstName("joe");
+ subjectCriteria.addFilterFactive(true);
+ subjectCriteria.fetchRoles(true);
+ subjectCriteria.addSortName(PageOrdering.ASC);
+
+ CriteriaQueryGenerator subjectGenerator = new
CriteriaQueryGenerator(subjectCriteria);
+ System.out.println(subjectGenerator.getQueryString(false));
+ System.out.println(subjectGenerator.getQueryString(true));
+ }
+
+ public static void testAlertCriteria() {
+ AlertCriteria alertCriteria = new AlertCriteria();
+ alertCriteria.addFilterName("joe");
+ alertCriteria.addFilterDescription("query generation is cool");
+ alertCriteria.addFilterStartTime(42L);
+ alertCriteria.addFilterEndTime(100L);
+ alertCriteria.addFilterResourceIds(1, 2, 3);
+ alertCriteria.fetchAlertDefinition(true);
+ alertCriteria.addSortPriority(PageOrdering.DESC);
+ alertCriteria.addSortName(PageOrdering.ASC);
+ alertCriteria.setPaging(0, 100);
+ alertCriteria.setFiltersOptional(true);
+ //alertCriteria.setCaseSensitive(false);
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(alertCriteria);
+ System.out.println(generator.getQueryString(false));
+ System.out.println(generator.getQueryString(true));
+
+ generator.setAuthorizationResourceFragment(AuthorizationTokenType.RESOURCE,
"definition.resource", 1);
+ System.out.println(generator.getQueryString(false));
+ System.out.println(generator.getQueryString(true));
+ }
+
+ public static void testInheritanceCriteria() {
+ ResourceOperationHistoryCriteria historyCriteria = new
ResourceOperationHistoryCriteria();
+ historyCriteria.addFilterResourceIds(1);
+ historyCriteria.addFilterStatus(OperationRequestStatus.FAILURE);
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(historyCriteria);
+ System.out.println(generator.getQueryString(false));
+ System.out.println(generator.getQueryString(true));
+ }
+
+ public static void testResourceCriteria() {
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterResourceCategory(ResourceCategory.SERVER);
+ resourceCriteria.addFilterName("marques");
+ resourceCriteria.fetchAgent(true);
+ resourceCriteria.addSortResourceTypeName(PageOrdering.ASC);
+ resourceCriteria.setCaseSensitive(true);
+ resourceCriteria.setFiltersOptional(true);
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(resourceCriteria);
+ generator.getQueryString(false);
+ generator.getQueryString(true);
+ }
+}
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
new file mode 100644
index 0000000..ba5d623
--- /dev/null
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
@@ -0,0 +1,84 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.rhq.core.domain.criteria.Criteria;
+import org.rhq.core.domain.util.PageList;
+
+public class CriteriaQueryRunner<T> {
+
+ private Criteria criteria;
+
+ private CriteriaQueryGenerator queryGenerator;
+
+ private EntityManager entityManager;
+
+ public CriteriaQueryRunner(Criteria criteria, CriteriaQueryGenerator queryGenerator,
EntityManager entityManager) {
+ this.criteria = criteria;
+ this.queryGenerator = queryGenerator;
+ this.entityManager = entityManager;
+ }
+
+ public PageList<T> execute() {
+ Query query = queryGenerator.getQuery(entityManager);
+ Query countQuery = queryGenerator.getCountQuery(entityManager);
+
+ long count = (Long) countQuery.getSingleResult();
+ List<T> results = query.getResultList();
+
+ initAllPersistentBags(results);
+
+ return new PageList<T>(results, (int) count, criteria.getPageControl());
+ }
+
+ private void initAllPersistentBags(List<T> entities) {
+ for (T entity : entities) {
+ initPersistentBags(entity);
+ }
+ }
+
+ private void initPersistentBags(T entity) {
+ for (Field persistentBagField : queryGenerator.getPersistentBagFields()) {
+ List persistentBag = getList(entity, persistentBagField);
+ persistentBag.size();
+ }
+ }
+
+ private List getList(T entity, Field field) {
+ try {
+ field.setAccessible(true);
+ return (List) field.get(entity);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+}
commit 15c5ab632360523f7ad37112700a1f2220163fb0
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Oct 28 17:31:50 2009 -0400
Merging in JON 2.3 patch work. [RHQ-1996,2470,2445,2457,2462,2468]
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
index 8871e0c..4708904 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
@@ -26,6 +26,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;
+
import mazz.i18n.Logger;
/**
@@ -559,4 +560,17 @@ public abstract class DatabaseType {
* @throws SQLException
*/
public abstract void reindexTable(Connection conn, String table) throws
SQLException;
+
+ /**
+ * Provides the value to be used for the ESCAPE character in string literals. The
SQL standard is a single
+ * character, typically '\', but not every dbType conforms to the standard.
To override the db default set
+ * the rhq.server.database.escape-character system property.
+ *
+ * @return If set, the value of rhq.server.database.escape-character, otherwise the
db default.
+ */
+ public String getEscapeCharacter() {
+ String result =
System.getProperty("rhq.server.database.escape-character");
+
+ return (null == result) ? "\\" : result;
+ }
}
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseTypeFactory.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseTypeFactory.java
index d3e3cc8..2d8c79e 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseTypeFactory.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseTypeFactory.java
@@ -45,6 +45,12 @@ public class DatabaseTypeFactory {
*/
private static final Map<String, String> DB_URL_DRIVER_MAP;
+ /**
+ * This can be set to store the defaultDatabaseType. Typically set it application
initialization to
+ * provide a quick way to get the (typically) unchanging db vendor setting.
+ */
+ private static DatabaseType defaultDatabaseType = null;
+
static {
DB_URL_DRIVER_MAP = new Hashtable<String, String>();
DB_URL_DRIVER_MAP.put("jdbc:postgresql:",
"org.postgresql.Driver");
@@ -184,6 +190,26 @@ public class DatabaseTypeFactory {
return database_type_class.newInstance();
}
+ /**
+ * This is the getter of a get/set convenience mechanism for storing and retrieving
the active database type.
+ * Not a true singleton but typically the value will not change as the underlying db
is typically
+ * not going to change at runtime.
+ *
+ * @return The current DatabaseType or null if not yet set.
+ */
+ public static DatabaseType getDefaultDatabaseType() {
+ return DatabaseTypeFactory.defaultDatabaseType;
+ }
+
+ /**
+ * This is the setter of a get/set convenience mechanism for storing and retrieving
the active database type.
+ * Typically called one time when the dbType is established. Not a true singleton
but typically the value will
+ * not change as the underlying db is typically not going to change.
+ */
+ public static void setDefaultDatabaseType(DatabaseType databaseType) {
+ DatabaseTypeFactory.defaultDatabaseType = databaseType;
+ }
+
/**
* Given a JDBC URL, this will attempt to load in the JDBC driver class that will be
needed to connect to the
* database via that URL and will return that driver class name. If the driver class
could not be loaded, <code>
diff --git
a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
index cdf29a3..c7566b9 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
@@ -162,4 +162,18 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
public void reindexTable(Connection conn, String table) throws SQLException {
executeSql(conn, "REINDEX TABLE " + table);
}
+
+ /**
+ * This is overridden for Postgres because by default (at least in our currently
supported versions)
+ * postgres does not treat the backslash as a string literal, which breaks the sql
standard. See
+ *
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674 for more.
+ *
+ * @see DatabaseType#getEscapeCharacter()
+ */
+ public String getEscapeCharacter() {
+ String result =
System.getProperty("rhq.server.database.escape-character");
+
+ return (null == result) ? "\\\\" : result;
+ }
+
}
\ No newline at end of file
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/EventCriteria.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/EventCriteria.java
index 28bcb98..1a39995 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/EventCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/EventCriteria.java
@@ -25,8 +25,8 @@ package org.rhq.core.domain.criteria;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
-import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.domain.event.Event;
+import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.domain.util.PageOrdering;
/**
@@ -41,8 +41,8 @@ public class EventCriteria extends Criteria {
private String filterDetail;
private String filterSourceName; // requires overrides
private EventSeverity filterSeverity;
- private Long startTime; // requires overrides
- private Long endTime; // requires overrides
+ private Long filterStartTime; // requires overrides
+ private Long filterEndTime; // requires overrides
private Integer filterResourceId; // requires overrides
private Integer filterResourceGroupId; // requires overrides
private Integer filterAutoGroupResourceTypeId; // requires overrides
@@ -63,8 +63,8 @@ public class EventCriteria extends Criteria {
filterOverrides.put("resourceGroupId", "source.resourceId IN
" //
+ "( SELECT res.id " //
+ " FROM Resource res " //
- + " JOIN res.implicitGroups group " //
- + " WHERE group.id = ? )");
+ + " JOIN res.implicitGroups ig " //
+ + " WHERE ig.id = ? )");
filterOverrides.put("autoGroupResourceTypeId", "source.resourceId
IN " //
+ "( SELECT res.id " //
+ " FROM Resource res " //
@@ -89,6 +89,14 @@ public class EventCriteria extends Criteria {
this.filterSourceName = filterSourceName;
}
+ public void addFilterStartTime(long filterStartTime) {
+ this.filterStartTime = filterStartTime;
+ }
+
+ public void addFilterEndTime(long filterEndTime) {
+ this.filterEndTime = filterEndTime;
+ }
+
public void addFilterSeverity(EventSeverity filterSeverity) {
this.filterSeverity = filterSeverity;
}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
index d14f517..268e57a 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
@@ -28,8 +28,8 @@ import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
-import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.measurement.MeasurementSchedule;
+import org.rhq.core.domain.util.PageOrdering;
/**
* @author Joseph Marques
@@ -60,8 +60,8 @@ public class MeasurementScheduleCriteria extends Criteria {
filterOverrides.put("resourceGroupId", "resource.id IN " //
+ "( SELECT res.id " //
+ " FROM Resource res " //
- + " JOIN res.implicitGroups group " //
- + " WHERE group.id = ? )");
+ + " JOIN res.implicitGroups ig " //
+ + " WHERE ig.id = ? )");
filterOverrides.put("autoGroupResourceTypeId", "resource.id IN
" //
+ "( SELECT res.id " //
+ " FROM Resource res " //
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/event/EventSource.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/event/EventSource.java
index 645ec8e..efe6978 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/event/EventSource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/event/EventSource.java
@@ -170,7 +170,8 @@ public class EventSource implements Externalizable {
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.eventDefinition);
out.writeInt((this.resource != null) ? this.resource.getId() : 0);
- out.writeUTF(this.location);
+ // this can be null when serializing a containing referencing Event, in which it
is lazy loaded
+ out.writeUTF((null == this.location) ? "" : this.location);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryGenerator.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryGenerator.java
deleted file mode 100644
index b06165e..0000000
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryGenerator.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * 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.util;
-
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.lang.reflect.Field;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.criteria.AlertCriteria;
-import org.rhq.core.domain.criteria.Criteria;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
-import org.rhq.core.domain.criteria.SubjectCriteria;
-import org.rhq.core.domain.operation.OperationRequestStatus;
-import org.rhq.core.domain.resource.ResourceCategory;
-import org.hibernate.annotations.IndexColumn;
-
-/**
- * A query generator used to generate queries with specific filtering, prefetching, or
sorting requirements.
- *
- * @author Joseph Marques
- */
-public final class CriteriaQueryGenerator {
-
- private static final Log LOG = LogFactory.getLog(CriteriaQueryGenerator.class);
-
- 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
- }
-
- private Criteria criteria;
-
- private String authorizationJoinFragment;
- private int authorizationSubjectId;
-
- private String alias;
- private String className;
- private static String NL = System.getProperty("line.separator");
-
- private List<Field> persistentBagFields = new ArrayList<Field>();
-
- public CriteriaQueryGenerator(Criteria criteria) {
- this.criteria = criteria;
-
- String criteriaClassName = criteria.getClass().getSimpleName();
- className = criteriaClassName.substring(0, criteriaClassName.length() - 8);
-
- StringBuilder aliasBuilder = new StringBuilder();
- for (char c : this.className.toCharArray()) {
- if (Character.isUpperCase(c)) {
- aliasBuilder.append(Character.toLowerCase(c));
- }
- }
- this.alias = aliasBuilder.toString();
- }
-
- public void setAuthorizationResourceFragment(AuthorizationTokenType type, int
subjectId) {
- String defaultFragment = null;
- if (type == AuthorizationTokenType.RESOURCE) {
- defaultFragment = "resource";
- } else if (type == AuthorizationTokenType.GROUP) {
- defaultFragment = "group";
- }
- setAuthorizationResourceFragment(type, defaultFragment, subjectId);
- }
-
- private String fixFilterOverride(String expression, String fieldName) {
- boolean fuzzyMatch = expression.toLowerCase().indexOf(" like ") != -1;
- boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive() &&
fuzzyMatch;
-
- while (expression.indexOf('?') != -1) {
- String replacement = ":" + fieldName;
- expression = expression.replaceFirst("\\?", replacement);
- }
-
- if (wantCaseInsensitiveMatch) {
- int indexOfFirstSpace = expression.indexOf(" ");
- String filterToken = expression.substring(0, indexOfFirstSpace);
- expression = "LOWER( " + alias + "." + filterToken +
" ) " + expression.substring(indexOfFirstSpace);
- } else {
- expression = alias + "." + expression;
- }
-
- if (fuzzyMatch) {
- expression += " ESCAPE '\\\\'";
- }
-
- return expression;
- }
-
- public void setAuthorizationResourceFragment(AuthorizationTokenType type, String
fragment, int subjectId) {
- this.authorizationSubjectId = subjectId;
- if (type == AuthorizationTokenType.RESOURCE) {
- if (fragment == null) {
- this.authorizationJoinFragment = "" //
- + "JOIN " + alias + ".implicitGroups authGroup "
+ NL //
- + "JOIN authGroup.roles authRole " + NL //
- + "JOIN authRole.subjects authSubject " + NL;
- } else {
- this.authorizationJoinFragment = "" //
- + "JOIN " + alias + "." + fragment + "
authRes " + NL //
- + "JOIN authRes.implicitGroups authGroup " + NL //
- + "JOIN authGroup.roles authRole " + NL //
- + "JOIN authRole.subjects authSubject " + NL;
- }
- } else if (type == AuthorizationTokenType.GROUP) {
- if (fragment == null) {
- this.authorizationJoinFragment = "" //
- + "JOIN " + alias + ".roles authRole " + NL //
- + "JOIN authRole.subjects authSubject " + NL;
- } else {
- this.authorizationJoinFragment = "" //
- + "JOIN " + alias + "." + fragment + "
authGroup " + NL //
- + "JOIN authGroup.roles authRole " + NL //
- + "JOIN authRole.subjects authSubject " + NL;
- }
- } else {
- throw new IllegalArgumentException(this.getClass().getSimpleName()
- + " does not yet support generating queries for '" + type +
"' token types");
- }
- }
-
- // for testing purposes only, should use getQuery(EntityManager) or
getCountQuery(EntityManager) instead
- public String getQueryString(boolean countQuery) {
- StringBuilder results = new StringBuilder();
- results.append("SELECT ");
- if (countQuery) {
-
results.append("COUNT(").append(alias).append(")").append(NL);
- } else {
- results.append(alias).append(NL);
- }
- results.append("FROM ").append(className).append('
').append(alias).append(NL);
- if (countQuery == false) {
- /*
- * don't fetch in the count query to avoid: "query specified join
fetching,
- * but the owner of the fetched association was not present in the select
list"
- */
- for (String fetchJoin : criteria.getFetchFields()) {
- if (isPersistentBag(fetchJoin)) {
- addPersistentBag(fetchJoin);
- }
- else {
- results.append("LEFT JOIN FETCH
").append(alias).append('.').append(fetchJoin).append(NL);
- }
- }
- }
- if (authorizationJoinFragment != null) {
- results.append(authorizationJoinFragment);
- }
-
- Map<String, Object> filterFields = criteria.getFilterFields();
- if (filterFields.size() > 0 || authorizationJoinFragment != null) {
- results.append("WHERE ");
- }
-
- String conjunctiveFragment = criteria.isFiltersOptional() ? "OR " :
"AND ";
- boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive();
-
- // criteria
- StringBuilder conjunctiveResults = new StringBuilder();
- boolean firstCrit = true;
- for (Map.Entry<String, Object> filterField : filterFields.entrySet()) {
- if (firstCrit) {
- firstCrit = false;
- } else {
- conjunctiveResults.append(NL).append(conjunctiveFragment);
- }
- String fieldName = filterField.getKey();
- String override = criteria.getJPQLFilterOverride(fieldName);
- String fragment = null;
- if (override != null) {
- fragment = fixFilterOverride(override, fieldName);
- } else {
- String operator = "=";
- if (filterField.getValue() instanceof String) {
- operator = "like";
- if (wantCaseInsensitiveMatch) {
- fragment = "LOWER( " + alias + "." +
fieldName + " ) " + operator + " :" + fieldName;
- } else {
- fragment = alias + "." + fieldName + " " +
operator + " :" + fieldName;
- }
- /*
- * Double escape backslashes because strings might be escaped at the
database level that
- * Hibernate calls into --
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674
- */
- fragment += " ESCAPE '\\\\'";
- } else {
- fragment = alias + "." + fieldName + " " +
operator + " :" + fieldName;
- }
- }
-
- conjunctiveResults.append(fragment).append(' ');
- }
-
- if (conjunctiveResults.length() > 0) {
- results.append("(
").append(conjunctiveResults).append(")");
- }
-
- // authorization
- if (authorizationJoinFragment != null) {
- if (firstCrit) {
- firstCrit = false;
- } else {
- // always want AND for security, regardless of conjunctiveFragment
- results.append(NL).append(" AND ");
- }
- results.append("authSubject.id = " + authorizationSubjectId +
" ");
- }
-
- if (countQuery == false) {
- boolean overridden = true;
- PageControl pc = criteria.getPageControlOverrides();
- if (pc == null) {
- overridden = false;
- pc = criteria.getPageControl();
- }
-
- boolean first = true;
- for (OrderingField orderingField : pc.getOrderingFields()) {
- if (first) {
- results.append(NL).append("ORDER BY ");
- first = false;
- } else {
- results.append(", ");
- }
-
- if (overridden) {
- String fieldName = orderingField.getField();
- PageOrdering ordering = orderingField.getOrdering();
-
- results.append(fieldName).append(' ').append(ordering);
- } else {
- String fieldName = orderingField.getField();
- String override = criteria.getJPQLSortOverride(fieldName);
- String fragment = override != null ? override : fieldName;
-
- results.append(alias).append('.').append(fragment);
- results.append(' ').append(orderingField.getOrdering());
- }
- }
- }
- results.append(NL);
-
- LOG.debug(results);
- System.out.println(results);
- return results.toString();
- }
-
- private boolean isPersistentBag(String fieldName) {
- try {
- Class<?> persistentClass = criteria.getPersistentClass();
- Field field = persistentClass.getDeclaredField(fieldName);
-
- return isAList(field) &&
!field.isAnnotationPresent(IndexColumn.class);
- }
- catch (NoSuchFieldException e) {
- return false;
- }
- }
-
- private boolean isAList(Field field) {
- Class<?> fieldType = field.getType();
-
- if (List.class.isAssignableFrom(fieldType)) {
- return true;
- }
-
- for (Class declaredInterface : fieldType.getInterfaces()) {
- if (List.class.isAssignableFrom(declaredInterface)) {
- return true;
- }
- }
- return false;
- }
-
- private void addPersistentBag(String fieldName) {
- try {
- Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
- persistentBagFields.add(field);
- }
- catch (NoSuchFieldException e) {
- LOG.warn("Failed to add persistent bag collection.", e);
- }
- }
-
- /**
- * <strong>Note:</strong> This method should only be called after {@link
#getQueryString(boolean)}} because it is
- * that method where the persistentBagFields property is initialized.
- *
- * @return Returns a list of fields from the persistent class to which the criteria
class corresponds. The fields in
- * the list are themselves instances of List and have "bag" semantics.
- */
- public List<Field> getPersistentBagFields() {
- return persistentBagFields;
- }
-
- public Query getQuery(EntityManager em) {
- String queryString = getQueryString(false);
- Query query = em.createQuery(queryString);
- setBindValues(query, false);
- PersistenceUtility.setDataPage(query, criteria.getPageControl());
- return query;
- }
-
- public Query getCountQuery(EntityManager em) {
- String countQueryString = getQueryString(true);
- Query query = em.createQuery(countQueryString);
- setBindValues(query, false);
- return query;
- }
-
- private void setBindValues(Query query, boolean countQuery) {
- boolean wantCaseInsensitiveMatch = !criteria.isCaseSensitive();
- boolean wantsFuzzyMatching = !criteria.isStrict();
-
- for (Map.Entry<String, Object> critField :
criteria.getFilterFields().entrySet()) {
- Object value = critField.getValue();
- if (value instanceof String) {
- String formattedValue = (String) value;
- if (wantCaseInsensitiveMatch) {
- formattedValue = formattedValue.toLowerCase();
- }
- /*
- * Double escape backslashes because strings might be escaped at the
database level that
- * Hibernate calls into --
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674
- */
- formattedValue = ((String) formattedValue).replaceAll("\\_",
"\\\\_");
- if (wantsFuzzyMatching) {
- // append '%' onto edges that don't already have
'%' explicitly set from the caller
- formattedValue = (formattedValue.startsWith("%") ?
"" : "%") + formattedValue
- + (formattedValue.endsWith("%") ? "" :
"%");
- }
- value = formattedValue;
- }
- LOG.debug("Bind: (" + critField.getKey() + ", " + value +
")");
- query.setParameter(critField.getKey(), value);
- }
- }
-
- public static void main(String[] args) {
- //testSubjectCriteria();
- //testAlertCriteria();
- //testInheritanceCriteria();
- testResourceCriteria();
- }
-
- public static void testSubjectCriteria() {
- SubjectCriteria subjectCriteria = new SubjectCriteria();
- subjectCriteria.addFilterFirstName("joe");
- subjectCriteria.addFilterFactive(true);
- subjectCriteria.fetchRoles(true);
- subjectCriteria.addSortName(PageOrdering.ASC);
-
- CriteriaQueryGenerator subjectGenerator = new
CriteriaQueryGenerator(subjectCriteria);
- System.out.println(subjectGenerator.getQueryString(false));
- System.out.println(subjectGenerator.getQueryString(true));
- }
-
- public static void testAlertCriteria() {
- AlertCriteria alertCriteria = new AlertCriteria();
- alertCriteria.addFilterName("joe");
- alertCriteria.addFilterDescription("query generation is cool");
- alertCriteria.addFilterStartTime(42L);
- alertCriteria.addFilterEndTime(100L);
- alertCriteria.addFilterResourceIds(1, 2, 3);
- alertCriteria.fetchAlertDefinition(true);
- alertCriteria.addSortPriority(PageOrdering.DESC);
- alertCriteria.addSortName(PageOrdering.ASC);
- alertCriteria.setPaging(0, 100);
- alertCriteria.setFiltersOptional(true);
- //alertCriteria.setCaseSensitive(false);
-
- CriteriaQueryGenerator generator = new CriteriaQueryGenerator(alertCriteria);
- System.out.println(generator.getQueryString(false));
- System.out.println(generator.getQueryString(true));
-
- generator.setAuthorizationResourceFragment(AuthorizationTokenType.RESOURCE,
"definition.resource", 1);
- System.out.println(generator.getQueryString(false));
- System.out.println(generator.getQueryString(true));
- }
-
- public static void testInheritanceCriteria() {
- ResourceOperationHistoryCriteria historyCriteria = new
ResourceOperationHistoryCriteria();
- historyCriteria.addFilterResourceIds(1);
- historyCriteria.addFilterStatus(OperationRequestStatus.FAILURE);
-
- CriteriaQueryGenerator generator = new CriteriaQueryGenerator(historyCriteria);
- System.out.println(generator.getQueryString(false));
- System.out.println(generator.getQueryString(true));
- }
-
- public static void testResourceCriteria() {
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterResourceCategory(ResourceCategory.SERVER);
- resourceCriteria.addFilterName("marques");
- resourceCriteria.fetchAgent(true);
- resourceCriteria.addSortResourceTypeName(PageOrdering.ASC);
- resourceCriteria.setCaseSensitive(true);
- resourceCriteria.setFiltersOptional(true);
-
- CriteriaQueryGenerator generator = new CriteriaQueryGenerator(resourceCriteria);
- generator.getQueryString(false);
- generator.getQueryString(true);
- }
-}
\ No newline at end of file
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryRunner.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryRunner.java
deleted file mode 100644
index eebc2f6..0000000
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/CriteriaQueryRunner.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.util;
-
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.criteria.Criteria;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-import java.util.List;
-import java.lang.reflect.Field;
-
-public class CriteriaQueryRunner<T> {
-
- private Criteria criteria;
-
- private CriteriaQueryGenerator queryGenerator;
-
- private EntityManager entityManager;
-
- public CriteriaQueryRunner(Criteria criteria, CriteriaQueryGenerator queryGenerator,
EntityManager entityManager) {
- this.criteria = criteria;
- this.queryGenerator = queryGenerator;
- this.entityManager = entityManager;
- }
-
- public PageList<T> execute() {
- Query query = queryGenerator.getQuery(entityManager);
- Query countQuery = queryGenerator.getCountQuery(entityManager);
-
- long count = (Long) countQuery.getSingleResult();
- List<T> results = query.getResultList();
-
- initAllPersistentBags(results);
-
- return new PageList<T>(results, (int) count, criteria.getPageControl());
- }
-
- private void initAllPersistentBags(List<T> entities) {
- for (T entity : entities) {
- initPersistentBags(entity);
- }
- }
-
- private void initPersistentBags(T entity) {
- for (Field persistentBagField : queryGenerator.getPersistentBagFields()) {
- List persistentBag = getList(entity, persistentBagField);
- persistentBag.size();
- }
- }
-
- private List getList(T entity, Field field) {
- try {
- field.setAccessible(true);
- return (List) field.get(entity);
- }
- catch (IllegalAccessException e) {
- e.printStackTrace();
- return null;
- }
- }
-
-}
diff --git
a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java
b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java
index 1a4fd05..5135817 100644
---
a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java
+++
b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/startup/StartupServlet.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.gui.startup;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.sql.Connection;
import java.util.List;
import java.util.Properties;
@@ -29,11 +30,13 @@ import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
+import javax.sql.DataSource;
import org.quartz.SchedulerException;
import org.jboss.mx.util.MBeanServerLocator;
+import org.rhq.core.db.DatabaseTypeFactory;
import org.rhq.core.domain.cloud.Server;
import org.rhq.core.domain.cloud.Server.OperationMode;
import org.rhq.core.domain.resource.Agent;
@@ -126,6 +129,15 @@ public class StartupServlet extends HttpServlet {
}
private void initializeServer() {
+ // Ensure the class is loaded and the dbType is set for our current db
+ try {
+ DataSource ds = LookupUtil.getDataSource();
+ Connection conn = ds.getConnection();
+
DatabaseTypeFactory.setDefaultDatabaseType(DatabaseTypeFactory.getDatabaseType(conn));
+ } catch (Exception e) {
+ log("Could not initialize server: ", e);
+ }
+
// Ensure that this server is registered in the database.
createDefaultServerIfNecessary();
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index b56ec26..e9468ad 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -45,17 +45,17 @@ import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.NumericType;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.alert.engine.AlertDefinitionEvent;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.cloud.StatusManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* @author Joseph Marques
@@ -634,6 +634,6 @@ public class AlertDefinitionManagerBean implements
AlertDefinitionManagerLocal,
}
CriteriaQueryRunner<AlertDefinition> queryRunner = new
CriteriaQueryRunner(criteria, generator, entityManager);
- return queryRunner.execute();
+ return queryRunner.execute();
}
}
\ No newline at end of file
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 83efd92..78d4342 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
@@ -67,12 +67,10 @@ import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.measurement.util.MeasurementConverter;
import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.jdbc.JDBCUtil;
import org.rhq.enterprise.server.RHQConstants;
@@ -87,6 +85,8 @@ import org.rhq.enterprise.server.measurement.util.MeasurementFormatter;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.util.LookupUtil;
/**
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
index d074d18..f3bb715 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
@@ -47,11 +47,9 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.SubjectCriteria;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
@@ -59,6 +57,8 @@ import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.core.CustomJaasDeploymentServiceMBean;
import org.rhq.enterprise.server.exception.LoginException;
import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* Provides functionality to access and manipulate subjects and principals, mainly for
authentication purposes.
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
index 7875dd7..3478499 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
@@ -39,13 +39,13 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.criteria.RoleCriteria;
import org.rhq.core.domain.resource.group.ResourceGroup;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* This bean provides functionality to manipulate the security rules. That is,
adding/modifying/deleting roles and their
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ChannelManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ChannelManagerBean.java
index 7447934..25a886d 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ChannelManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ChannelManagerBean.java
@@ -45,16 +45,16 @@ import org.rhq.core.domain.content.composite.ChannelComposite;
import org.rhq.core.domain.criteria.ChannelCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
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.authz.RequiredPermission;
import org.rhq.enterprise.server.plugin.content.ContentSourcePluginContainer;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
@Stateless
public class ChannelManagerBean implements ChannelManagerLocal, ChannelManagerRemote {
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index d2f2b73..8f8a024 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -83,7 +83,6 @@ import org.rhq.core.domain.criteria.PackageVersionCriteria;
import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.exception.ThrowableUtil;
@@ -95,6 +94,7 @@ import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.core.AgentManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
/**
* EJB that handles content subsystem interaction with resources, including content
discovery reports and create/delete
@@ -335,7 +335,7 @@ public class ContentManagerBean implements ContentManagerLocal,
ContentManagerRe
throw new IllegalArgumentException("PackageVersion: [" +
packageVersionId + "] not found!");
}
- ResourcePackageDetails details =
ContentManagerHelper.packageVersionToDetails(packageVersion);
+ ResourcePackageDetails details =
ContentManagerHelper.packageVersionToDetails(packageVersion);
details.setInstallationTimestamp(System.currentTimeMillis());
packages.add(details);
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/event/EventManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/event/EventManagerBean.java
index f5a5f77..632141b 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/event/EventManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/event/EventManagerBean.java
@@ -62,12 +62,10 @@ import org.rhq.core.domain.event.EventSource;
import org.rhq.core.domain.event.composite.EventComposite;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.group.GroupCategory;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.util.jdbc.JDBCUtil;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.alert.engine.AlertConditionCacheManagerLocal;
@@ -76,6 +74,8 @@ import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.measurement.instrumentation.MeasurementMonitor;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* Manager for Handling of {@link Event}s.
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
index 365c3df..b1a849e 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
@@ -337,9 +337,10 @@ public class MeasurementDataManagerBean implements
MeasurementDataManagerLocal,
}
private List<List<MeasurementDataNumericHighLowComposite>>
findDataAggregatesForSiblingResources(Subject subject,
- int[] resourceIds, int measurementDefinitionId, long beginTime, long endTime, int
numberOfDataPoints) {
+ int[] resourceIds, int measurementDefinitionId, long beginTime, long endTime, int
numDataPoints) {
+
return
MeasurementDataManagerUtility.getInstance(rhqDs).getMeasurementDataAggregatesForSiblingResources(
- beginTime, endTime, resourceIds, measurementDefinitionId);
+ beginTime, endTime, resourceIds, measurementDefinitionId, numDataPoints);
}
public List<List<MeasurementDataNumericHighLowComposite>>
findDataForAutoGroup(Subject subject,
@@ -790,14 +791,14 @@ public class MeasurementDataManagerBean implements
MeasurementDataManagerLocal,
}
public List<List<MeasurementDataNumericHighLowComposite>>
findDataForResource(Subject subject, int resourceId,
- int[] definitionIds, long beginTime, long endTime, int numPoints) {
+ int[] definitionIds, long beginTime, long endTime, int numDataPoints) {
if (authorizationManager.canViewResource(subject, resourceId) == false) {
throw new PermissionException("User[" + subject.getName()
+ "] does not have permission to view measurement data for
resource[id=" + resourceId + "]");
}
return
MeasurementDataManagerUtility.getInstance(rhqDs).getMeasurementDataForResource(beginTime,
endTime,
- resourceId, definitionIds);
+ resourceId, definitionIds, numDataPoints);
}
@SuppressWarnings("unchecked")
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDefinitionManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDefinitionManagerBean.java
index 210adb7..b485960 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDefinitionManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDefinitionManagerBean.java
@@ -39,11 +39,11 @@ import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.DisplayType;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementSchedule;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* A manager for {@link MeasurementDefinition}s.
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
index cdc8f7f..aa28f40 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
@@ -39,7 +39,6 @@ import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.sql.DataSource;
-import javax.jws.WebParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -71,8 +70,6 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.domain.util.OrderingField;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -80,7 +77,6 @@ import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.core.util.jdbc.JDBCUtil;
-import org.rhq.core.clientapi.agent.measurement.MeasurementAgentService;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.agentclient.AgentClient;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
@@ -94,6 +90,8 @@ import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -1284,35 +1282,34 @@ public class MeasurementScheduleManagerBean implements
MeasurementScheduleManage
return queryRunner.execute();
}
-// public PageList<MeasurementSchedule>
getResourceMeasurementSchedulesFromAgent(Subject subject, int resourceId) {
-// //verifyViewPermissionForMeasurementSchedules(subject,
measurementScheduleIds);
-//
-// AgentClient agentClient = agentManager.getAgentClient(resourceId);
-// MeasurementAgentService measurementAgentSvc =
agentClient.getMeasurementAgentService();
-//
-// PageList<MeasurementSchedule> schedules = new
PageList<MeasurementSchedule>();
-// for (int scheduleId :
measurementAgentSvc.getMeasurementScheduleIdsForResource(resourceId)) {
-// MeasurementSchedule schedule = getScheduleById(scheduleId);
-// schedules.add(schedule);
-// }
-//
-// return schedules;
-// }
-//
-// private void verifyViewPermissionForMeasurementSchedules(Subject subject, int[]
measurementScheduleIds) {
-// for (int id : measurementScheduleIds) {
-// verifyViewPermission(subject, id);
-// }
-// }
-//
-// private void verifyViewPermission(Subject subject, int scheduleId) {
-// MeasurementSchedule schedule = entityManager.find(MeasurementSchedule.class,
scheduleId);
-// if (authorizationManager.hasResourcePermission(subject,
Permission.MANAGE_MEASUREMENTS, schedule.getResource()
-// .getId()) == false) {
-// throw new PermissionException("User[" + subject.getName()
-// + "] does not have permission to view
measurementSchedule[id=" + schedule.getId() + "]");
-// }
-// }
-
+ // public PageList<MeasurementSchedule>
getResourceMeasurementSchedulesFromAgent(Subject subject, int resourceId) {
+ // //verifyViewPermissionForMeasurementSchedules(subject,
measurementScheduleIds);
+ //
+ // AgentClient agentClient = agentManager.getAgentClient(resourceId);
+ // MeasurementAgentService measurementAgentSvc =
agentClient.getMeasurementAgentService();
+ //
+ // PageList<MeasurementSchedule> schedules = new
PageList<MeasurementSchedule>();
+ // for (int scheduleId :
measurementAgentSvc.getMeasurementScheduleIdsForResource(resourceId)) {
+ // MeasurementSchedule schedule = getScheduleById(scheduleId);
+ // schedules.add(schedule);
+ // }
+ //
+ // return schedules;
+ // }
+ //
+ // private void verifyViewPermissionForMeasurementSchedules(Subject subject, int[]
measurementScheduleIds) {
+ // for (int id : measurementScheduleIds) {
+ // verifyViewPermission(subject, id);
+ // }
+ // }
+ //
+ // private void verifyViewPermission(Subject subject, int scheduleId) {
+ // MeasurementSchedule schedule =
entityManager.find(MeasurementSchedule.class, scheduleId);
+ // if (authorizationManager.hasResourcePermission(subject,
Permission.MANAGE_MEASUREMENTS, schedule.getResource()
+ // .getId()) == false) {
+ // throw new PermissionException("User[" + subject.getName()
+ // + "] does not have permission to view
measurementSchedule[id=" + schedule.getId() + "]");
+ // }
+ // }
}
\ No newline at end of file
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/util/MeasurementDataManagerUtility.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/util/MeasurementDataManagerUtility.java
index e547810..7114e17 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/util/MeasurementDataManagerUtility.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/util/MeasurementDataManagerUtility.java
@@ -83,6 +83,9 @@ public class MeasurementDataManagerUtility {
public static final long RAW_PURGE = STORED_DAYS * MILLISECONDS_PER_DAY;
+ /** For methods taking a number of data points, the default if the passed value is
invalid (<=0). */
+ public static final int DEFAULT_NUM_DATA_POINTS = 60;
+
private Connection connection;
private DataSource datasource;
@@ -234,6 +237,14 @@ public class MeasurementDataManagerUtility {
public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataForResource(long beginTime,
long endTime, int resourceId, int[] measurementDefinitionIds) throws
MeasurementNotFoundException {
+
+ // use default number of data points
+ return getMeasurementDataForResource(beginTime, endTime, resourceId,
measurementDefinitionIds, 0);
+ }
+
+ public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataForResource(long beginTime,
+ long endTime, int resourceId, int[] measurementDefinitionIds, int numDataPoints)
+ throws MeasurementNotFoundException {
String otherTable = ", RHQ_MEASUREMENT_SCHED s ";
String conditions = " AND d.schedule_id = s.id" + " AND
s.resource_id = ? \n" + " AND s.definition = ? \n";
@@ -249,8 +260,8 @@ public class MeasurementDataManagerUtility {
ps = null;
rs = null;
try {
- ps = getFullQuery(myConnection, beginTime, endTime, 60, otherTable,
conditions, resourceId,
- measurementDefinitionId);
+ ps = getFullQuery(myConnection, beginTime, endTime, numDataPoints,
otherTable, conditions,
+ resourceId, measurementDefinitionId);
rs = ps.executeQuery();
List<MeasurementDataNumericHighLowComposite> compositeList =
new ArrayList<MeasurementDataNumericHighLowComposite>();
@@ -292,6 +303,15 @@ public class MeasurementDataManagerUtility {
public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataForSiblingResources(long beginTime,
long endTime, int[] resourceIds, int measurementDefinitionId) throws
MeasurementNotFoundException {
+
+ // use default numDataPoints
+ return getMeasurementDataForSiblingResources(beginTime, endTime, resourceIds,
measurementDefinitionId, 0);
+
+ }
+
+ public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataForSiblingResources(long beginTime,
+ long endTime, int[] resourceIds, int measurementDefinitionId, int numDataPoints)
+ throws MeasurementNotFoundException {
String otherTable = ", RHQ_MEASUREMENT_SCHED s ";
String conditions = " AND d.schedule_id = s.id" + " AND
s.resource_id = ? \n" + " AND s.definition = ? \n";
@@ -303,7 +323,7 @@ public class MeasurementDataManagerUtility {
for (int resourceId : resourceIds) {
try {
myConnection = getConnection();
- ps = getFullQuery(myConnection, beginTime, endTime, 60, otherTable,
conditions, resourceId,
+ ps = getFullQuery(myConnection, beginTime, endTime, numDataPoints,
otherTable, conditions, resourceId,
measurementDefinitionId);
rs = ps.executeQuery();
@@ -345,6 +365,15 @@ public class MeasurementDataManagerUtility {
public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataAggregatesForSiblingResources(
long beginTime, long endTime, int[] resourceIds, int measurementDefinitionId)
throws MeasurementNotFoundException {
+
+ // use default number of data points
+ return getMeasurementDataAggregatesForSiblingResources(beginTime, endTime,
resourceIds,
+ measurementDefinitionId, 0);
+ }
+
+ public List<List<MeasurementDataNumericHighLowComposite>>
getMeasurementDataAggregatesForSiblingResources(
+ long beginTime, long endTime, int[] resourceIds, int measurementDefinitionId, int
numDataPoints)
+ throws MeasurementNotFoundException {
String otherTable = ", RHQ_MEASUREMENT_SCHED s ";
String conditions = " AND d.schedule_id = s.id" + " AND
s.resource_id IN ( "
@@ -356,7 +385,7 @@ public class MeasurementDataManagerUtility {
List<List<MeasurementDataNumericHighLowComposite>> data = new
ArrayList<List<MeasurementDataNumericHighLowComposite>>();
try {
myConnection = getConnection();
- ps = getFullQuery(myConnection, beginTime, endTime, 60, otherTable,
conditions, resourceIds,
+ ps = getFullQuery(myConnection, beginTime, endTime, numDataPoints,
otherTable, conditions, resourceIds,
measurementDefinitionId);
rs = ps.executeQuery();
@@ -550,9 +579,13 @@ public class MeasurementDataManagerUtility {
return null;
}
- private PreparedStatement getFullQuery(Connection connection, long beginTime, long
endTime, int numberOfDataPoints,
+ private PreparedStatement getFullQuery(Connection connection, long beginTime, long
endTime, int numDataPoints,
String otherTables, String conditions, Object... bindParameters) throws
SQLException {
- long interval = (endTime - beginTime) / numberOfDataPoints;
+
+ // ensure valid number of data points
+ numDataPoints = (numDataPoints <= 0) ? DEFAULT_NUM_DATA_POINTS :
numDataPoints;
+
+ long interval = (endTime - beginTime) / numDataPoints;
String valuesClause;
if (isRawTimePeriod(beginTime)) {
@@ -589,13 +622,13 @@ public class MeasurementDataManagerUtility {
for (String table : tables) {
ps.setLong(i++, beginTime);
ps.setLong(i++, interval); // 2) interval
- ps.setInt(i++, numberOfDataPoints); // 3) points
+ ps.setInt(i++, numDataPoints); // 3) points
ps.setLong(i++, interval); // 4) interval
if (LOG.isDebugEnabled()) {
fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(beginTime));
fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(interval));
- fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(numberOfDataPoints));
+ fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(numDataPoints));
fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(interval));
}
@@ -624,12 +657,12 @@ public class MeasurementDataManagerUtility {
ps.setLong(i++, beginTime); // 1) begin
ps.setLong(i++, interval); // 2) interval
- ps.setInt(i++, numberOfDataPoints); // 3) points
+ ps.setInt(i++, numDataPoints); // 3) points
if (LOG.isDebugEnabled()) {
fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(beginTime));
fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(interval));
- fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(numberOfDataPoints));
+ fullSql.replace(fullSql.indexOf("?"),
fullSql.indexOf("?") + 1, String.valueOf(numDataPoints));
LOG.debug(fullSql);
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerBean.java
index 3f38a7e..6c2f968 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerBean.java
@@ -68,8 +68,6 @@ import
org.rhq.core.domain.operation.composite.ResourceOperationScheduleComposit
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
@@ -91,6 +89,8 @@ import org.rhq.enterprise.server.resource.ResourceNotFoundException;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupNotFoundException;
import org.rhq.enterprise.server.scheduler.SchedulerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
@Stateless
public class OperationManagerBean implements OperationManagerLocal,
OperationManagerRemote {
@@ -393,8 +393,7 @@ public class OperationManagerBean implements OperationManagerLocal,
OperationMan
return operationSchedules;
}
- public List<GroupOperationSchedule> findScheduledGroupOperations(Subject
subject, int groupId)
- throws Exception {
+ public List<GroupOperationSchedule> findScheduledGroupOperations(Subject
subject, int groupId) throws Exception {
ResourceGroup group = getCompatibleGroupIfAuthorized(subject, groupId);
List<GroupOperationSchedule> operationSchedules = new
ArrayList<GroupOperationSchedule>();
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 55c0693..7a78db6 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
@@ -98,8 +98,6 @@ import org.rhq.core.domain.resource.composite.ResourceInstallCount;
import org.rhq.core.domain.resource.composite.ResourceWithAvailability;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.AutoGroupComposite;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
@@ -117,6 +115,8 @@ import
org.rhq.enterprise.server.measurement.MeasurementScheduleManagerLocal;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.operation.ResourceOperationSchedule;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* A manager that provides methods for creating, updating, deleting, and querying {@link
Resource}s.
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
index 5e10358..fed3b9e 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
@@ -49,13 +49,13 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceFacets;
import org.rhq.core.domain.resource.composite.ResourceTypeTemplateCountComposite;
import org.rhq.core.domain.resource.group.ResourceGroup;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* A manager that provides methods for creating, updating, deleting, and querying
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
index 4294a23..b84b7c5 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
@@ -72,8 +72,6 @@ import org.rhq.core.domain.resource.composite.ResourceFacets;
import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
-import org.rhq.core.domain.util.CriteriaQueryGenerator;
-import org.rhq.core.domain.util.CriteriaQueryRunner;
import org.rhq.core.domain.util.OrderingField;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -93,6 +91,8 @@ import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* A manager that provides methods for creating, updating, deleting, and querying
diff --git
a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/CpuComponent.java
b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/CpuComponent.java
index 6065c30..67ee20a 100644
--- a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/CpuComponent.java
+++ b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/CpuComponent.java
@@ -1,32 +1,34 @@
- /*
- * 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.
- */
+/*
+ * 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.plugins.platform;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import org.hyperic.sigar.Cpu;
import org.hyperic.sigar.CpuInfo;
-import org.hyperic.sigar.CpuPerc;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
@@ -41,11 +43,21 @@ import org.rhq.core.system.CpuInformation;
public class CpuComponent implements ResourceComponent<PlatformComponent>,
MeasurementFacet {
private CpuInformation cpuInformation = null;
+ private CpuEntry startCpuEntry = null;
+
+ /**
+ * A Map of cpu metric names to the last (Sigar) Cpu record used in calculations for
that metric in getValues.
+ * This allows us to take proper cpu usage deltas for each metric, on different
schedules. See
+ * RHQ-2457 for why this is necessary.
+ */
+ private Map<String, CpuEntry> cpuCache;
public void start(ResourceContext<PlatformComponent> resourceContext) {
if (resourceContext.getSystemInformation().isNative()) {
cpuInformation = resourceContext.getSystemInformation().getCpu(
Integer.parseInt(resourceContext.getResourceKey()));
+ cpuCache = new HashMap<String, CpuEntry>();
+ startCpuEntry = new CpuEntry(cpuInformation.getCpu());
}
}
@@ -66,13 +78,14 @@ public class CpuComponent implements
ResourceComponent<PlatformComponent>, Measu
cpuInformation.refresh();
Cpu cpu = null;
- CpuPerc cpuPerc = null;
+ CpuEntry currentCpu = null;
CpuInfo cpuInfo = null; // this is probably gonna be used for traits only
for (MeasurementScheduleRequest request : metrics) {
String property = request.getName();
if (property.startsWith("Cpu.")) {
+ // Grab the current cpu info from Sigar, only once for this cpu for
all processed schedules
if (cpu == null) {
cpu = cpuInformation.getCpu();
}
@@ -84,12 +97,46 @@ public class CpuComponent implements
ResourceComponent<PlatformComponent>, Measu
report.addData(new MeasurementDataNumeric(request,
longValue.doubleValue()));
}
} else if (property.startsWith("CpuPerc.")) {
- if (cpuPerc == null) {
- cpuPerc = cpuInformation.getCpuPercentage();
+
+ /*
+ * ! we no longer use the Sigar CpuPerc object to report cpu
percentage metrics. See
+ * ! RHQ-245 for an explanation. We now calculate our own
percentages using
+ * ! the current raw cpu info from Sigar and the previous cpu
numbers, cached per metric.
+ * ! This allows us to avoid the problem in RHQ-245 while handling
perCpu-perMetric schedule
+ * ! granularity.
+ */
+
+ // Grab the current cpu info from Sigar, only once for this cpu for
all processed schedules
+ if (null == cpu) {
+ cpu = cpuInformation.getCpu();
+ }
+ // Create a Cpu cacheEntry only once for this cpu for all processed
schedules
+ if (null == currentCpu) {
+ currentCpu = new CpuEntry(cpu);
}
- property = property.substring(property.indexOf(".") + 1);
- Number num = ((Number) ObjectUtil.lookupAttributeProperty(cpuPerc,
property));
+ // Get the previous cpu numbers to be used for this metric and update
the cache for the next go.
+ CpuEntry previousCpu = cpuCache.put(property, currentCpu);
+ previousCpu = (null == previousCpu) ? startCpuEntry : previousCpu;
+
+ // if for some reason the delta time is excessive then toss the
+ // the metric, it depends on a reasonable interval between prev
+ // and curr. This can happen due to avail down or a newly
+ // activated metric. Allow up to twice the metric interval.
+ Number num = null;
+ long deltaTime = currentCpu.getTimestamp() -
previousCpu.getTimestamp();
+
+ if (deltaTime <= (2 * request.getInterval())) {
+ // Use the same calculation as Sigar uses to generate the
percentages. The difference is that
+ // we use a safe "previous" cpu record.
+ num = getPercentage(previousCpu.getCpu(), cpu, property);
+ }
+
+ // uncomment to see details about the calculations
+ //System.out.println("\nCPU-" +
cpuInformation.getCpuIndex() + " Interval="
+ // + ((currentCpu.getTimestamp() - previousCpu.getTimestamp()) /
1000) + " " + property + "="
+ // + num + "\n Prev=" + previousCpu + "\n
Curr=" + currentCpu);
+
if (num != null) {
report.addData(new MeasurementDataNumeric(request,
num.doubleValue()));
}
@@ -122,4 +169,87 @@ public class CpuComponent implements
ResourceComponent<PlatformComponent>, Measu
}
}
}
+
+ /**
+ * Calculate the percentage of CPU taken up by the requested cpu property (metric)
for the interval
+ * defined by the prev and curr cpu numbers. This algorithm is taken from Sigar.
See
+ *
http://svn.hyperic.org/projects/sigar/trunk/src/sigar_format.c (
sigar_cpu_perc_calculate() )
+ */
+ private Number getPercentage(Cpu prev, Cpu curr, String property) {
+ Number result = 0.0;
+
+ double diff_user, diff_sys, diff_nice, diff_idle;
+ double diff_wait, diff_irq, diff_soft_irq, diff_stolen;
+ double diff_total;
+
+ diff_user = curr.getUser() - prev.getUser();
+ diff_sys = curr.getSys() - prev.getSys();
+ diff_nice = curr.getNice() - prev.getNice();
+ diff_idle = curr.getIdle() - prev.getIdle();
+ diff_wait = curr.getWait() - prev.getWait();
+ diff_irq = curr.getIrq() - prev.getIrq();
+ diff_soft_irq = curr.getSoftIrq() - prev.getSoftIrq();
+ diff_stolen = curr.getStolen() - prev.getStolen();
+
+ // It's not exactly clear to me what Sigar is doing here. It may be to handle
a rollover of
+ // the cumulative cpu usage numbers. If so, this code could maybe be improved to
still
+ // determine the total usage.
+ diff_user = diff_user < 0 ? 0 : diff_user;
+ diff_sys = diff_sys < 0 ? 0 : diff_sys;
+ diff_nice = diff_nice < 0 ? 0 : diff_nice;
+ diff_idle = diff_idle < 0 ? 0 : diff_idle;
+ diff_wait = diff_wait < 0 ? 0 : diff_wait;
+ diff_irq = diff_irq < 0 ? 0 : diff_irq;
+ diff_soft_irq = diff_soft_irq < 0 ? 0 : diff_soft_irq;
+ diff_stolen = diff_stolen < 0 ? 0 : diff_stolen;
+
+ diff_total = diff_user + diff_sys + diff_nice + diff_idle + diff_wait + diff_irq
+ diff_soft_irq + diff_stolen;
+
+ property = property.substring(property.lastIndexOf(".") + 1,
property.length());
+ if ("idle".equals(property)) {
+ result = diff_idle / diff_total;
+ } else if ("sys".equals(property)) {
+ result = diff_sys / diff_total;
+ } else if ("user".equals(property)) {
+ result = diff_user / diff_total;
+ } else if ("wait".equals(property)) {
+ result = diff_wait / diff_total;
+ } else if ("nice".equals(property)) {
+ result = diff_nice / diff_total;
+ } else if ("irq".equals(property)) {
+ result = diff_irq / diff_total;
+ } else if ("softIrq".equals(property)) {
+ result = diff_soft_irq / diff_total;
+ } else if ("stolen".equals(property)) {
+ result = diff_stolen / diff_total;
+ }
+
+ return result;
+ }
+
+ /**
+ * Just a private, immutable, utility class for associating a CPU and timestamp with
teh raw Cpu object from Sigar.
+ */
+ private class CpuEntry {
+ private Cpu cpu;
+ private long timestamp;
+
+ public CpuEntry(Cpu cpu) {
+ this.cpu = cpu;
+ this.timestamp = System.currentTimeMillis();
+ }
+
+ public Cpu getCpu() {
+ return cpu;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public String toString() {
+ return "CPU-" + cpuInformation.getCpuIndex() + "[" + new
SimpleDateFormat("HH:mm:ss").format(timestamp)
+ + "] = " + cpu;
+ }
+ }
}