blob: 686de432808f9d3367b619016cc2825e05ac9eaf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ambari.server.orm.entities;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import org.apache.ambari.server.state.AlertFirmness;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.MaintenanceState;
import org.apache.commons.lang.builder.EqualsBuilder;
/**
* The {@link AlertCurrentEntity} class represents the most recently received an
* alert data for a given instance. This class always has an associated matching
* {@link AlertHistoryEntity} that defines the actual data of the alert.
* <p/>
* There will only ever be a single entity for each given
* {@link AlertDefinitionEntity}.
*/
@Entity
@Table(name = "alert_current")
@TableGenerator(name = "alert_current_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_current_id_seq", initialValue = 0)
@NamedQueries({
@NamedQuery(name = "AlertCurrentEntity.findAll", query = "SELECT alert FROM AlertCurrentEntity alert"),
@NamedQuery(name = "AlertCurrentEntity.findByCluster", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId"),
@NamedQuery(name = "AlertCurrentEntity.findByDefinitionId", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId"),
@NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.serviceName = :serviceName AND alert.alertHistory.alertDefinition.scope IN :inlist"),
@NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.alertDefinition.definitionName = :definitionName AND alert.alertHistory.hostName = :hostName"),
@NamedQuery(name = "AlertCurrentEntity.findByNameAndNoHost", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.alertDefinition.definitionName = :definitionName AND alert.alertHistory.hostName IS NULL"),
@NamedQuery(name = "AlertCurrentEntity.findByHostComponent", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.serviceName = :serviceName AND alert.alertHistory.componentName = :componentName AND alert.alertHistory.hostName = :hostName"),
@NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.hostName = :hostName"),
@NamedQuery(name = "AlertCurrentEntity.findByServiceName", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.serviceName = :serviceName"),
@NamedQuery(name = "AlertCurrentEntity.findDisabled", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertDefinition.enabled = 0"),
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.historyId = :historyId"),
// The remove queries can be handled by a simpler JPQL query,
// however, MySQL gtid enforce policy gets violated due to creation and
// deletion of TEMP table in the same transaction
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryIds", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.historyId IN :historyIds"),
@NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.definitionId = :definitionId")
})
public class AlertCurrentEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "alert_current_id_generator")
@Column(name = "alert_id", nullable = false, updatable = false)
private Long alertId;
@Column(name = "history_id", nullable = false, insertable = false, updatable = false, length = 10)
private Long historyId;
@Column(name = "definition_id", nullable = false, insertable = false, updatable = false, length = 10)
private Long definitionId;
@Column(name = "latest_timestamp", nullable = false)
private Long latestTimestamp;
@Column(name = "maintenance_state", length = 255)
@Enumerated(value = EnumType.STRING)
private MaintenanceState maintenanceState = MaintenanceState.OFF;
@Column(name = "original_timestamp", nullable = false)
private Long originalTimestamp;
@Lob
@Column(name = "latest_text")
private String latestText = null;
/**
* The number of occurrences of this alert in its current state. States which
* are not {@link AlertState#OK} are aggregated such that transitioning
* between these states should not reset this value. For example, if an alert
* bounces between {@link AlertState#WARNING} and {@link AlertState#CRITICAL},
* then it will not reset this value.
*
*/
@Column(name="occurrences", nullable=false)
private Long occurrences = Long.valueOf(1);
@Column(name = "firmness", nullable = false)
@Enumerated(value = EnumType.STRING)
private AlertFirmness firmness = AlertFirmness.HARD;
/**
* Unidirectional one-to-one association to {@link AlertHistoryEntity}
*/
@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "history_id", unique = true, nullable = false)
private AlertHistoryEntity alertHistory;
/**
* Unidirectional one-to-one association to {@link AlertDefinitionEntity}
*/
@OneToOne
@JoinColumn(name = "definition_id", unique = false, nullable = false)
private AlertDefinitionEntity alertDefinition;
/**
* Constructor.
*/
public AlertCurrentEntity() {
}
/**
* Gets the unique ID for this current alert.
*
* @return the ID (never {@code null}).
*/
public Long getAlertId() {
return alertId;
}
/**
* Sets the unique ID for this current alert.
*
* @param alertId
* the ID (not {@code null}).
*/
public void setAlertId(Long alertId) {
this.alertId = alertId;
}
/**
* Get the related alert history id.
* @return history id
*/
public Long getHistoryId() {
return historyId;
}
/**
* Set the related history id.
* @param historyId historyId
*/
public void setHistoryId(Long historyId) {
this.historyId = historyId;
}
/**
* Get parent alert definition id
* @return definition id
*/
public Long getDefinitionId() {
return definitionId;
}
/**
* Set the parent alert definition id
* @param definitionId definition id
*/
public void setDefinitionId(Long definitionId) {
this.definitionId = definitionId;
}
/**
* Gets the time, in millis, that the last instance of this alert state was
* received.
*
* @return the time of the most recently received alert data for this instance
* (never {@code null}).
*/
public Long getLatestTimestamp() {
return latestTimestamp;
}
/**
* Sets the time, in millis, that the last instance of this alert state was
* received.
*
* @param latestTimestamp
* the time of the most recently received alert data for this
* instance (never {@code null}).
*/
public void setLatestTimestamp(Long latestTimestamp) {
this.latestTimestamp = latestTimestamp;
}
/**
* Gets the current maintenance state for the alert.
*
* @return the current maintenance state (never {@code null}).
*/
public MaintenanceState getMaintenanceState() {
return maintenanceState;
}
/**
* Sets the current maintenance state for the alert.
*
* @param maintenanceState
* the state to set (not {@code null}).
*/
public void setMaintenanceState(MaintenanceState maintenanceState) {
this.maintenanceState = maintenanceState;
}
/**
* Gets the time, in milliseconds, when the alert was first received with the
* current state.
*
* @return the time of the first instance of this alert.
*/
public Long getOriginalTimestamp() {
return originalTimestamp;
}
/**
* Sets the time, in milliseconds, when the alert was first received with the
* current state.
*
* @param originalTimestamp
* the time of the first instance of this alert (not {@code null}).
*/
public void setOriginalTimestamp(Long originalTimestamp) {
this.originalTimestamp = originalTimestamp;
}
/**
* Gets the latest text for this alert. History will not get a new record on
* update when the state is the same, but the text may be changed. For example,
* CPU utilization includes the usage in the text and should be available.
*/
public String getLatestText() {
return latestText;
}
/**
* Sets the latest text. {@link #getLatestText()}
*/
public void setLatestText(String text) {
latestText = text;
}
/**
* Gets the number of occurrences of this alert in its current state. States
* which are not {@link AlertState#OK} are aggregated such that transitioning
* between these states should not reset this value. For example, if an alert
* bounces between {@link AlertState#WARNING} and {@link AlertState#CRITICAL},
* then it will not reset this value.
*
* @return the number of occurrences.
*/
public Long getOccurrences() {
return occurrences;
}
/**
* Sets the number of occurrences for this alert instance.
*
* @param occurrences
* the occurrences.
* @see #getOccurrences()
*
*/
public void setOccurrences(long occurrences) {
this.occurrences = occurrences;
}
/**
* Gets the firmness of the alert, indicating whether or not it could be a
* potential false positive.
*
* @return the alert firmness.
*/
public AlertFirmness getFirmness() {
return firmness;
}
/**
* Sets the firmness of the alert, indicating whether or not it could be a
* potential false positive.
*
* @param firmness
* the firmness (not {@code null}).
*/
public void setFirmness(AlertFirmness firmness) {
this.firmness = firmness;
}
/**
* Gets the associated {@link AlertHistoryEntity} entry for this current alert
* instance.
*
* @return the most recently received history entry (never {@code null}).
*/
public AlertHistoryEntity getAlertHistory() {
return alertHistory;
}
/**
* Sets the associated {@link AlertHistoryEntity} entry for this current alert
* instance. This will update the internal fields of this current alert with
* those from the alertHistory.
*
* @param alertHistory
* the most recently received history entry (not {@code null}).
*/
public void setAlertHistory(AlertHistoryEntity alertHistory) {
this.alertHistory = alertHistory;
historyId = alertHistory.getAlertId();
alertDefinition = alertHistory.getAlertDefinition();
definitionId = alertHistory.getAlertDefinitionId();
latestText = alertHistory.getAlertText();
}
/**
* Gets the equality to another alert based on the following criteria:
* <ul>
* <li>{@link #alertId}
* <li>{@link #alertHistory}
* </ul>
* <p/>
* {@inheritDoc}
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
AlertCurrentEntity that = (AlertCurrentEntity) object;
EqualsBuilder equalsBuilder = new EqualsBuilder();
equalsBuilder.append(alertId, that.alertId);
equalsBuilder.append(alertHistory, that.alertHistory);
return equalsBuilder.isEquals();
}
/**
* Generates a hash for the current alert based on the following criteria:
* <ul>
* <li>{@link #alertId}
* <li>{@link #alertHistory}
* </ul>
* <p/>
* For new alerts, the associated {@link AlertHistoryEntity} may not be
* persisted yet. This will rely on the
* {@link AlertHistoryEntity#equals(Object)} and
* {@link AlertHistoryEntity#hashCode()} being correct.
* <p/>
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hash(alertId, alertHistory);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder buffer = new StringBuilder("AlertCurrentEntity{");
buffer.append("alertId=").append(alertId);
if( null != alertDefinition) {
buffer.append(", name=").append(alertDefinition.getDefinitionName());
}
if (null != alertHistory) {
buffer.append(", state=").append(alertHistory.getAlertState());
}
buffer.append(", latestTimestamp=").append(latestTimestamp);
buffer.append("}");
return buffer.toString();
}
}