/* * 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.measurement; import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.rhq.core.domain.resource.Resource; @Entity @NamedQueries({ // @NamedQuery(name = MeasurementSchedule.FIND_ALL_FOR_DEFINITIONS, query = "" // + "SELECT ms "// + " FROM MeasurementSchedule ms " // + " WHERE ms.definition IN (:definitions) "), // @NamedQuery(name = MeasurementSchedule.FIND_BY_IDS, query = "" // + "SELECT ms " // + " FROM MeasurementSchedule ms " // + " WHERE ms.id IN ( :ids )"), // @NamedQuery(name = MeasurementSchedule.FIND_ENABLED_BY_RESOURCES_AND_RESOURCE_TYPE, query = "" // + "SELECT ms.id, res.id, def.id " // + " FROM MeasurementSchedule ms " // + " JOIN ms.definition def " // + " JOIN ms.resource res " // + " WHERE def.resourceType = :resourceType " // + " AND ms.definition = def " // + " AND res IN (:resources) " // + " AND ms.enabled = true" // + " AND (def.dataType = :dataType OR :dataType is null )"), // @NamedQuery(name = MeasurementSchedule.FIND_ENABLED_BY_RESOURCE_IDS_AND_RESOURCE_TYPE_ID, query = ""// + "SELECT ms.id, res.id, def.id "// + " FROM MeasurementSchedule ms "// + " JOIN ms.definition def "// + " JOIN ms.resource res "// + " WHERE def.resourceType.id = :resourceTypeId " // + " AND ms.definition = def "// + " AND res.id IN (:resourceIds) " // + " AND ms.enabled = true"),// @NamedQuery(name = MeasurementSchedule.FIND_SCHEDULES_WITH_BASLINES_TO_CALC, query = "" // + "SELECT ms FROM MeasurementSchedule ms " // + " WHERE ms.enabled = true " // + " AND ms.definition.numericType = :measType " // + " AND ms.baseline.computeTime < :ctime " // + " AND ms.baseline.userEntered = false"), // @NamedQuery(name = MeasurementSchedule.FIND_ALL_FOR_RESOURCE_ID, query = "" // + " SELECT ms " // + " FROM MeasurementSchedule ms " // + "JOIN FETCH ms.definition " // + " WHERE ms.resource.id = :resourceId " // + " AND (ms.definition.dataType = :dataType OR :dataType is null) " + " AND (ms.definition.displayType = :displayType OR :displayType is null) " + " AND (ms.enabled = :enabled OR :enabled is null) "), // @NamedQuery(name = MeasurementSchedule.FIND_BY_RESOURCE_IDS_AND_DEFINITION_IDS, query = "" // + "SELECT ms " // + " FROM MeasurementSchedule ms " // + " WHERE ms.definition.id IN (:definitionIds) " // + " AND ms.resource.id IN (:resourceIds)"), // @NamedQuery(name = MeasurementSchedule.FIND_SCHEDULE_COMPOSITE_FOR_RESOURCE, query = "" // + "SELECT new org.rhq.core.domain.measurement.composite.MeasurementScheduleComposite" // + " ( ms.definition, " // + " ms.enabled, " // + " ms.interval ) " // + " FROM MeasurementSchedule ms " // + " WHERE ms.resource.id = :resourceId " // + " AND (ms.definition.dataType = :dataType OR :dataType is null) "), // @NamedQuery(name = MeasurementSchedule.GET_SCHEDULED_MEASUREMENTS_PER_MINUTED, query = "" // + "SELECT SUM(1000.0 / ms.interval) * 60.0 " // + " FROM MeasurementSchedule ms " // + " WHERE ms.enabled = true " // + " AND ms.definition.name <> '" + MeasurementDefinition.AVAILABILITY_NAME + "' " // + " AND ms.resource.inventoryStatus = :status"), // @NamedQuery(name = MeasurementSchedule.DISABLE_ALL, query = "" // + "UPDATE MeasurementSchedule ms " // + " SET ms.enabled = false"), // @NamedQuery(name = MeasurementSchedule.DELETE_BY_RESOURCES, query = "" // + "DELETE MeasurementSchedule ms " // + " WHERE ms.resource.id IN ( :resourceIds )")}) @SequenceGenerator(allocationSize = org.rhq.core.domain.util.Constants.ALLOCATION_SIZE, name = "RHQ_MEASUREMENT_SCHED_ID_SEQ", sequenceName = "RHQ_MEASUREMENT_SCHED_ID_SEQ") @Table(name = "RHQ_MEASUREMENT_SCHED", uniqueConstraints = { @UniqueConstraint(columnNames = { "DEFINITION", "RESOURCE_ID" }) }) public class MeasurementSchedule implements Serializable { private static final long serialVersionUID = 1L; public static final long MINIMUM_INTERVAL = 30000L; /** * Finds schedules that have a baseline attached that needs to be recalculated. MeasuremetType is passed in * :measType, baseline compute time in :ctime */ public static final String FIND_SCHEDULES_WITH_BASLINES_TO_CALC = "MeasurementSchedule.findSchedulesWithBaselinesToCalculate"; /** * Find all MeasurementSchedules that are attached to the resource passed by its id in :resourceId */ public static final String FIND_ALL_FOR_RESOURCE_ID = "MeasurementSchedule.FIND_ALL_FOR_RESOURCE_ID"; /** * Find schedules by definitions and resource. Definitions are in :definitionIds, resource id is in :resourceId */ public static final String FIND_BY_RESOURCE_IDS_AND_DEFINITION_IDS = "MeasurementSchedule.findByResourceIdsAndDefinitionIds"; /** * Find MeasureScheduleComposites for a resource. Resource id is passed in :resourceId */ public static final String FIND_SCHEDULE_COMPOSITE_FOR_RESOURCE = "MeasurementDefinition.findScheduleCompositeForResource"; public static final String GET_SCHEDULED_MEASUREMENTS_PER_MINUTED = "MeasurementSchedule.getScheduledMeasurementsPerMinute"; public static final String DISABLE_ALL = "MeasurementSchedule.disableAll"; public static final String FIND_ENABLED_BY_RESOURCES_AND_RESOURCE_TYPE = "MeasurementSchedule.FIND_ENABLED_BY_ResourcesS_AND_RESOURCE_TYPE"; public static final String FIND_ENABLED_BY_RESOURCE_IDS_AND_RESOURCE_TYPE_ID = "MeasurementSchedule.FIND_ENABLED_BY_ResourceIds_AND_RESOURCE_TYPE"; public static final String DELETE_BY_RESOURCES = "MeasurementSchedule.deleteByResources"; public static final String FIND_ALL_FOR_DEFINITIONS = "MeasurementSchedule.FIND_ALL_FOR_DEFINITIONS"; public static final String FIND_BY_IDS = "MeasurementSchedule.findByIds"; public static final String NATIVE_QUERY_REPORTING_RESOURCE_MEASUREMENT_SCHEDULE_REQUEST = "" // + "SELECT ms.RESOURCE_ID, ms.ID, def.NAME, ms.COLL_INTERVAL, ms.ENABLED, def.DATA_TYPE, def.RAW_NUMERIC_TYPE " // + " FROM RHQ_MEASUREMENT_SCHED ms " // + " JOIN RHQ_MEASUREMENT_DEF def ON ms.DEFINITION = def.ID " // + " WHERE ms.RESOURCE_ID IN ( @@RESOURCES@@ )"; public static final String NATIVE_QUERY_INSERT_SCHEDULES_POSTGRES = "" // + "INSERT INTO RHQ_MEASUREMENT_SCHED ( ID, ENABLED, COLL_INTERVAL, DEFINITION, RESOURCE_ID ) " // + " SELECT nextval('RHQ_MEASUREMENT_SCHED_ID_SEQ'), " // + " def.DEFAULT_ON AS defaultOn, " // + " def.DEFAULT_INTERVAL AS interval, " // + " def.ID AS definitionId, " // + " res.ID AS resourceId " // + " FROM RHQ_RESOURCE res, RHQ_RESOURCE_TYPE type, RHQ_MEASUREMENT_DEF def " // + " WHERE ( res.ID in ( @@RESOURCES@@ ) ) " // + " AND type.ID = res.RESOURCE_TYPE_ID " // + " AND type.ID = def.RESOURCE_TYPE_ID " // + " AND NOT EXISTS ( SELECT ms.id " // + " FROM RHQ_MEASUREMENT_SCHED ms " // + " WHERE ms.RESOURCE_ID = res.ID " // + " AND ms.DEFINITION = def.ID ) "; public static final String NATIVE_QUERY_INSERT_SCHEDULES_ORACLE = "" // + "INSERT INTO RHQ_MEASUREMENT_SCHED ( ID, ENABLED, COLL_INTERVAL, DEFINITION, RESOURCE_ID ) " // + " SELECT RHQ_MEASUREMENT_SCHED_ID_SEQ.nextval, " // + " defaultOn, interval, definitionId, resourceId " + " FROM ( SELECT def.DEFAULT_ON AS defaultOn, " // + " def.DEFAULT_INTERVAL AS interval, " // + " def.ID AS definitionId, " // + " res.ID AS resourceId " // + " FROM RHQ_RESOURCE res, RHQ_RESOURCE_TYPE type, RHQ_MEASUREMENT_DEF def " // + " WHERE ( res.ID in ( @@RESOURCES@@ ) ) " // + " AND type.ID = res.RESOURCE_TYPE_ID " // + " AND type.ID = def.RESOURCE_TYPE_ID " // + " AND NOT EXISTS ( SELECT ms.id " // + " FROM RHQ_MEASUREMENT_SCHED ms " // + " WHERE ms.RESOURCE_ID = res.ID " // + " AND ms.DEFINITION = def.ID ) ) "; public static final String NATIVE_QUERY_INSERT_SCHEDULES_SQL_SERVER = "" // + "INSERT INTO RHQ_MEASUREMENT_SCHED ( ENABLED, COLL_INTERVAL, DEFINITION, RESOURCE_ID ) " // + " SELECT def.DEFAULT_ON AS defaultOn, " // + " def.DEFAULT_INTERVAL AS interval, " // + " def.ID AS definitionId, " // + " res.ID AS resourceId " // + " FROM RHQ_RESOURCE res, RHQ_RESOURCE_TYPE type, RHQ_MEASUREMENT_DEF def " // + " WHERE ( res.ID in ( @@RESOURCES@@ ) ) " // + " AND type.ID = res.RESOURCE_TYPE_ID " // + " AND type.ID = def.RESOURCE_TYPE_ID " // + " AND NOT EXISTS ( SELECT ms.id " // + " FROM RHQ_MEASUREMENT_SCHED ms " // + " WHERE ms.RESOURCE_ID = res.ID " // + " AND ms.DEFINITION = def.ID ) "; @GeneratedValue(strategy = GenerationType.AUTO, generator = "RHQ_MEASUREMENT_SCHED_ID_SEQ") @Id private int id; /** * A possible baseline for this MeasurementSchedule Since baseline will always initially be null for a while, we * don't need CascadeType.PERSIST. However, we do need CascadeType.MERGE because the schedule will get its baseline * calculated for the first time (a merge-persist cascade), or have it updated at some later point in time (a * merge-merge cascade). */ // Remove now performed by bulk delete @OneToOne(mappedBy = "schedule", cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY) private MeasurementBaseline baseline; /** * The base definition of this Metric */ @JoinColumn(name = "DEFINITION") @ManyToOne(fetch = FetchType.EAGER) private MeasurementDefinition definition; /** * Metrics can be gathered on all levels of physical resources (Platform, Server, Service) */ @JoinColumn(name = "RESOURCE_ID", referencedColumnName = "ID", nullable = false) @ManyToOne(fetch = FetchType.LAZY) private Resource resource; /** * The interval of collecting. Only applicable if gatherMode() is set to MeasurementGathering.NUMERIC */ @Column(name = "COLL_INTERVAL") private long interval; /** * Time the schedule itself was last modified */ @Column(name = "MTIME") private Long mtime; /** * Is this metric schedule enabled */ @Column(name = "ENABLED") private boolean enabled; public MeasurementSchedule() { } public long getInterval() { return (this.interval < MINIMUM_INTERVAL) ? MINIMUM_INTERVAL : this.interval; } /** * Construct a new MeasurementSchedule * * @param definition The definition to apply * @param resource The resource this schedule is for */ public MeasurementSchedule(MeasurementDefinition definition, Resource resource) { this.definition = definition; this.enabled = true; this.resource = resource; } @Override public String toString() { return "[MeasurementSchedule, id=" + id + "]"; } /** * @return the baseline */ public MeasurementBaseline getBaseline() { return baseline; } /** * @param baseline the baseline to set */ public void setBaseline(MeasurementBaseline baseline) { this.baseline = baseline; } /** * @return if the schedule is enabled */ public boolean isEnabled() { return enabled; } /** * @param enabled the enabled to set */ public void setEnabled(boolean enabled) { this.enabled = enabled; } /** * @return the mtime */ public Long getMtime() { return mtime; } /** * Let the persistence framework set this for us. */ @PrePersist @PreUpdate @SuppressWarnings({ "unused" }) private void setMtime() { this.mtime = System.currentTimeMillis(); } /** * @return the myDefinition */ public MeasurementDefinition getDefinition() { return definition; } /** * @param myDefinition the myDefinition to set */ public void setDefinition(MeasurementDefinition myDefinition) { this.definition = myDefinition; } public Resource getResource() { return resource; } public void setResource(Resource resource) { this.resource = resource; } /** * @return the id */ public int getId() { return id; } public void setId(int id) { this.id = id; } public void setInterval(long interval) { this.interval = interval; } @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + ((definition == null) ? 0 : definition.hashCode()); result = (prime * result) + ((resource == null) ? 0 : resource.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof MeasurementSchedule)) { return false; } final MeasurementSchedule other = (MeasurementSchedule) obj; if (definition == null) { if (other.definition != null) { return false; } } else if (!definition.equals(other.definition)) { return false; } if (resource == null) { if (other.resource != null) { return false; } } else if (!resource.equals(other.resource)) { return false; } return true; } }