Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E7F341905F for ; Mon, 11 Apr 2016 19:16:31 +0000 (UTC) Received: (qmail 98808 invoked by uid 500); 11 Apr 2016 19:16:31 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 98776 invoked by uid 500); 11 Apr 2016 19:16:31 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 98767 invoked by uid 99); 11 Apr 2016 19:16:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Apr 2016 19:16:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 80DC0DFBED; Mon, 11 Apr 2016 19:16:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: swagle@apache.org To: commits@ambari.apache.org Message-Id: <4ccba594a6d240a2bbe803d3459aac44@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-15774. Ambari upgrade fails with MySQL DB and enforce gtid enabled. (swagle) Date: Mon, 11 Apr 2016 19:16:31 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/branch-2.2 c704377fe -> 85a5e975f AMBARI-15774. Ambari upgrade fails with MySQL DB and enforce gtid enabled. (swagle) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/85a5e975 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/85a5e975 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/85a5e975 Branch: refs/heads/branch-2.2 Commit: 85a5e975fa76832c5ac644b55f539b674e2376ff Parents: c704377 Author: Siddharth Wagle Authored: Mon Apr 11 11:39:55 2016 -0700 Committer: Siddharth Wagle Committed: Mon Apr 11 12:16:55 2016 -0700 ---------------------------------------------------------------------- .../listeners/alerts/AlertReceivedListener.java | 1 + .../server/orm/dao/AlertDefinitionDAO.java | 3 +- .../ambari/server/orm/dao/AlertDispatchDAO.java | 72 +++++++----- .../apache/ambari/server/orm/dao/AlertsDAO.java | 117 ++++++++++++++++--- .../server/orm/entities/AlertCurrentEntity.java | 69 ++++++++--- .../server/orm/entities/AlertHistoryEntity.java | 38 ++++-- .../server/orm/entities/AlertNoticeEntity.java | 33 +++++- .../internal/AlertResourceProviderTest.java | 1 + .../server/orm/dao/AlertDefinitionDAOTest.java | 74 +++++++++++- .../ambari/server/orm/dao/AlertsDAOTest.java | 5 + 10 files changed, 341 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertReceivedListener.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertReceivedListener.java index a3befa6..896500a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertReceivedListener.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertReceivedListener.java @@ -473,6 +473,7 @@ public class AlertReceivedListener { AlertDefinitionEntity definition, Alert alert) { AlertHistoryEntity history = new AlertHistoryEntity(); history.setAlertDefinition(definition); + history.setAlertDefinitionId(definition.getDefinitionId()); history.setAlertLabel(definition.getLabel()); history.setAlertInstance(alert.getInstance()); history.setAlertState(alert.getState()); http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java index 82fa48a..703ff58 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java @@ -372,8 +372,7 @@ public class AlertDefinitionDAO { */ @Transactional public AlertDefinitionEntity merge(AlertDefinitionEntity alertDefinition) { - AlertDefinitionEntity entity = entityManagerProvider.get().merge( - alertDefinition); + AlertDefinitionEntity entity = entityManagerProvider.get().merge(alertDefinition); AlertDefinition definition = alertDefinitionFactory.coerce(entity); http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java index 1f1aa45..4ffb802 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java @@ -17,18 +17,10 @@ */ package org.apache.ambari.server.orm.dao; -import java.text.MessageFormat; -import java.util.List; -import java.util.Map; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Order; -import javax.persistence.metamodel.SingularAttribute; - +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.query.JpaPredicateVisitor; import org.apache.ambari.server.api.query.JpaSortBuilder; @@ -48,11 +40,19 @@ import org.apache.ambari.server.state.NotificationState; import org.apache.ambari.server.state.Service; import org.eclipse.persistence.config.HintValues; import org.eclipse.persistence.config.QueryHints; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Singleton; -import com.google.inject.persist.Transactional; +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Order; +import javax.persistence.metamodel.SingularAttribute; +import java.text.MessageFormat; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; /** * The {@link AlertDispatchDAO} class manages the {@link AlertTargetEntity}, @@ -85,13 +85,16 @@ public class AlertDispatchDAO { */ private final Lock m_groupLock = new ReentrantLock(); - /** - * Gets an alert group with the specified ID. - * - * @param groupId - * the ID of the group to retrieve. - * @return the group or {@code null} if none exists. - */ + private static final Logger LOG = LoggerFactory.getLogger(AlertDispatchDAO.class); + + /** + * Gets an alert group with the specified ID. + * + * @param groupId + * the ID of the group to retrieve. + * @return the group or {@code null} if none exists. + */ + @RequiresSession public AlertGroupEntity findGroupById(long groupId) { return entityManagerProvider.get().find(AlertGroupEntity.class, groupId); @@ -683,12 +686,27 @@ public class AlertDispatchDAO { */ @Transactional public void removeNoticeByDefinitionId(long definitionId) { + LOG.info("Deleting AlertNotice entities by definition id."); EntityManager entityManager = entityManagerProvider.get(); - TypedQuery currentQuery = entityManager.createNamedQuery( - "AlertNoticeEntity.removeByDefinitionId", AlertNoticeEntity.class); + TypedQuery historyIdQuery = entityManager.createNamedQuery( + "AlertHistoryEntity.findHistoryIdsByDefinitionId", Integer.class); + historyIdQuery.setParameter("definitionId", definitionId); + List ids = daoUtils.selectList(historyIdQuery); + // Batch delete notice + int BATCH_SIZE = 999; + TypedQuery noticeQuery = entityManager.createNamedQuery( + "AlertNoticeEntity.removeByHistoryIds", AlertNoticeEntity.class); + if (ids != null && !ids.isEmpty()) { + for (int i = 0; i < ids.size(); i += BATCH_SIZE) { + int endIndex = (i + BATCH_SIZE) > ids.size() ? ids.size() : (i + BATCH_SIZE); + List idsSubList = ids.subList(i, endIndex); + LOG.info("Deleting AlertNotice entity batch with history ids: " + + idsSubList.get(0) + " - " + idsSubList.get(idsSubList.size() - 1)); + noticeQuery.setParameter("historyIds", idsSubList); + noticeQuery.executeUpdate(); + } + } - currentQuery.setParameter("definitionId", definitionId); - currentQuery.executeUpdate(); entityManager.clear(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java index 781d4cf..d187947 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java @@ -151,6 +151,11 @@ public class AlertsDAO implements Cleanable { private LoadingCache m_currentAlertCache = null; /** + * Batch size to query the DB and use the results in an IN clause. + */ + private static final int BATCH_SIZE = 999; + + /** * Constructor. * */ @@ -526,7 +531,7 @@ public class AlertsDAO implements Cleanable { @RequiresSession public AlertSummaryDTO findCurrentCounts(long clusterId, String serviceName, String hostName) { String sql = String.format(ALERT_COUNT_SQL_TEMPLATE, - AlertSummaryDTO.class.getName()); + AlertSummaryDTO.class.getName()); StringBuilder sb = new StringBuilder(sql); @@ -539,7 +544,7 @@ public class AlertsDAO implements Cleanable { } TypedQuery query = m_entityManagerProvider.get().createQuery( - sb.toString(), AlertSummaryDTO.class); + sb.toString(), AlertSummaryDTO.class); query.setParameter("clusterId", Long.valueOf(clusterId)); query.setParameter("okState", AlertState.OK); @@ -655,7 +660,7 @@ public class AlertsDAO implements Cleanable { public List findCurrentByService(long clusterId, String serviceName) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.findByService", AlertCurrentEntity.class); + "AlertCurrentEntity.findByService", AlertCurrentEntity.class); query.setParameter("clusterId", clusterId); query.setParameter("serviceName", serviceName); @@ -718,7 +723,7 @@ public class AlertsDAO implements Cleanable { private AlertCurrentEntity findCurrentByHostAndNameInJPA(long clusterId, String hostName, String alertName) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.findByHostAndName", AlertCurrentEntity.class); + "AlertCurrentEntity.findByHostAndName", AlertCurrentEntity.class); query.setParameter("clusterId", Long.valueOf(clusterId)); query.setParameter("hostName", hostName); @@ -768,7 +773,7 @@ public class AlertsDAO implements Cleanable { @Transactional public int removeCurrentByHistoryId(long historyId) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.removeByHistoryId", AlertCurrentEntity.class); + "AlertCurrentEntity.removeByHistoryId", AlertCurrentEntity.class); query.setParameter("historyId", historyId); int rowsRemoved = query.executeUpdate(); @@ -790,9 +795,16 @@ public class AlertsDAO implements Cleanable { @Transactional public int removeCurrentDisabledAlerts() { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.removeDisabled", AlertCurrentEntity.class); - - int rowsRemoved = query.executeUpdate(); + "AlertCurrentEntity.findDisabled", AlertCurrentEntity.class); + + int rowsRemoved = 0; + List currentEntities = m_daoUtils.selectList(query); + if (currentEntities != null) { + for (AlertCurrentEntity currentEntity : currentEntities) { + remove(currentEntity); + rowsRemoved++; + } + } // if caching is enabled, invalidate the cache to force the latest values // back from the DB @@ -820,11 +832,18 @@ public class AlertsDAO implements Cleanable { @Transactional public int removeCurrentByService(long clusterId, String serviceName) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.removeByService", AlertCurrentEntity.class); + "AlertCurrentEntity.findByServiceName", AlertCurrentEntity.class); query.setParameter("serviceName", serviceName); - int removedItems = query.executeUpdate(); + int removedItems = 0; + List currentEntities = m_daoUtils.selectList(query); + if (currentEntities != null) { + for (AlertCurrentEntity currentEntity : currentEntities) { + remove(currentEntity); + removedItems++; + } + } // if caching is enabled, invalidate the cache to force the latest values // back from the DB @@ -852,10 +871,17 @@ public class AlertsDAO implements Cleanable { @Transactional public int removeCurrentByHost(String hostName) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.removeByHost", AlertCurrentEntity.class); + "AlertCurrentEntity.findByHost", AlertCurrentEntity.class); query.setParameter("hostName", hostName); - int removedItems = query.executeUpdate(); + List currentEntities = m_daoUtils.selectList(query); + int removedItems = 0; + if (currentEntities != null) { + for (AlertCurrentEntity currentEntity : currentEntities) { + remove(currentEntity); + removedItems++; + } + } // if caching is enabled, invalidate the cache to force the latest values // back from the DB @@ -903,13 +929,20 @@ public class AlertsDAO implements Cleanable { String componentName, String hostName) { TypedQuery query = m_entityManagerProvider.get().createNamedQuery( - "AlertCurrentEntity.removeByHostComponent", AlertCurrentEntity.class); + "AlertCurrentEntity.findByHostComponent", AlertCurrentEntity.class); query.setParameter("serviceName", serviceName); query.setParameter("componentName", componentName); query.setParameter("hostName", hostName); - int removedItems = query.executeUpdate(); + List currentEntities = m_daoUtils.selectList(query); + int removedItems = 0; + if (currentEntities != null) { + for (AlertCurrentEntity currentEntity : currentEntities) { + remove(currentEntity); + removedItems++; + } + } // if caching is enabled, invalidate the cache to force the latest values // back from the DB @@ -1433,6 +1466,23 @@ public class AlertsDAO implements Cleanable { private static final class AlertNotYetCreatedException extends Exception { } + /** + * Find all @AlertHistoryEntity with date before provided date. + * @param clusterId cluster id + * @param beforeDateMillis timestamp in millis + * @return List ids + */ + private List findAllAlertHistoryIdsBeforeDate(Long clusterId, long beforeDateMillis) { + + EntityManager entityManager = m_entityManagerProvider.get(); + TypedQuery alertHistoryQuery = + entityManager.createNamedQuery("AlertHistoryEntity.findAllIdsInClusterBeforeDate", Integer.class); + + alertHistoryQuery.setParameter("clusterId", clusterId); + alertHistoryQuery.setParameter("beforeDate", beforeDateMillis); + + return m_daoUtils.selectList(alertHistoryQuery); + } /** * Deletes AlertNotice records in relation with AlertHistory entries older than the given date. @@ -1443,7 +1493,25 @@ public class AlertsDAO implements Cleanable { */ @Transactional private int cleanAlertNoticesForClusterBeforeDate(Long clusterId, long beforeDateMillis) { - return executeQuery("AlertNoticeEntity.removeByAlertHistoryBeforeDate", AlertNoticeEntity.class, clusterId, beforeDateMillis); + LOG.info("Deleting AlertNotice entities before date " + new Date(beforeDateMillis)); + EntityManager entityManager = m_entityManagerProvider.get(); + List ids = findAllAlertHistoryIdsBeforeDate(clusterId, beforeDateMillis); + int affectedRows = 0; + // Batch delete + TypedQuery noticeQuery = + entityManager.createNamedQuery("AlertNoticeEntity.removeByHistoryIds", AlertNoticeEntity.class); + if (ids != null && !ids.isEmpty()) { + for (int i = 0; i < ids.size(); i += BATCH_SIZE) { + int endIndex = (i + BATCH_SIZE) > ids.size() ? ids.size() : (i + BATCH_SIZE); + List idsSubList = ids.subList(i, endIndex); + LOG.info("Deleting AlertNotice entity batch with history ids: " + + idsSubList.get(0) + " - " + idsSubList.get(idsSubList.size() - 1)); + noticeQuery.setParameter("historyIds", idsSubList); + affectedRows += noticeQuery.executeUpdate(); + } + } + + return affectedRows; } @@ -1456,7 +1524,24 @@ public class AlertsDAO implements Cleanable { */ @Transactional private int cleanAlertCurrentsForClusterBeforeDate(long clusterId, long beforeDateMillis) { - return executeQuery("AlertCurrentEntity.removeByAlertHistoryBeforeDate", AlertCurrentEntity.class, clusterId, beforeDateMillis); + LOG.info("Deleting AlertCurrent entities before date " + new Date(beforeDateMillis)); + EntityManager entityManager = m_entityManagerProvider.get(); + List ids = findAllAlertHistoryIdsBeforeDate(clusterId, beforeDateMillis); + int affectedRows = 0; + TypedQuery currentQuery = + entityManager.createNamedQuery("AlertCurrentEntity.removeByHistoryIds", AlertCurrentEntity.class); + if (ids != null && !ids.isEmpty()) { + for (int i = 0; i < ids.size(); i += BATCH_SIZE) { + int endIndex = (i + BATCH_SIZE) > ids.size() ? ids.size() : (i + BATCH_SIZE); + List idsSubList = ids.subList(i, endIndex); + LOG.info("Deleting AlertCurrent entity batch with history ids: " + + idsSubList.get(0) + " - " + idsSubList.get(idsSubList.size() - 1)); + currentQuery.setParameter("historyIds", ids.subList(i, endIndex)); + affectedRows += currentQuery.executeUpdate(); + } + } + + return affectedRows; } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java index 604b00e..06dd2dd 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java @@ -47,19 +47,22 @@ import org.apache.ambari.server.state.MaintenanceState; @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.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.alertId = :historyId"), - @NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId"), - @NamedQuery(name = "AlertCurrentEntity.removeDisabled", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.enabled = 0"), - @NamedQuery(name = "AlertCurrentEntity.removeByService", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.serviceName = :serviceName"), - @NamedQuery(name = "AlertCurrentEntity.removeByHost", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.hostName = :hostName"), - @NamedQuery(name = "AlertCurrentEntity.removeByHostComponent", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.serviceName = :serviceName AND alert.alertHistory.componentName = :componentName AND alert.alertHistory.hostName = :hostName"), - @NamedQuery(name = "AlertCurrentEntity.removeByAlertHistoryBeforeDate", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.alertTimestamp <= :beforeDate") + @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 { @@ -68,6 +71,12 @@ public class AlertCurrentEntity { @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; @@ -122,6 +131,38 @@ public class AlertCurrentEntity { } /** + * 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. * @@ -220,7 +261,9 @@ public class AlertCurrentEntity { */ public void setAlertHistory(AlertHistoryEntity alertHistory) { this.alertHistory = alertHistory; + historyId = alertHistory.getAlertId(); alertDefinition = alertHistory.getAlertDefinition(); + definitionId = alertHistory.getAlertDefinitionId(); latestText = alertHistory.getAlertText(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java index 03ffcde..8bc4b99 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java @@ -45,14 +45,16 @@ import org.apache.ambari.server.state.AlertState; @Table(name = "alert_history") @TableGenerator(name = "alert_history_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_history_id_seq", initialValue = 0) @NamedQueries({ - @NamedQuery(name = "AlertHistoryEntity.findAll", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory"), - @NamedQuery(name = "AlertHistoryEntity.findAllInCluster", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId"), - @NamedQuery(name = "AlertHistoryEntity.findAllInClusterWithState", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertState IN :alertStates"), - @NamedQuery(name = "AlertHistoryEntity.findAllInClusterBetweenDates", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp BETWEEN :startDate AND :endDate"), - @NamedQuery(name = "AlertHistoryEntity.findAllInClusterBeforeDate", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp <= :beforeDate"), - @NamedQuery(name = "AlertHistoryEntity.findAllInClusterAfterDate", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp >= :afterDate"), - @NamedQuery(name = "AlertHistoryEntity.removeByDefinitionId", query = "DELETE FROM AlertHistoryEntity alertHistory WHERE alertHistory.alertDefinition.definitionId = :definitionId"), - @NamedQuery(name = "AlertHistoryEntity.removeInClusterBeforeDate", query = "DELETE FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId= :clusterId AND alertHistory.alertTimestamp <= :beforeDate") + @NamedQuery(name = "AlertHistoryEntity.findAll", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory"), + @NamedQuery(name = "AlertHistoryEntity.findAllInCluster", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId"), + @NamedQuery(name = "AlertHistoryEntity.findAllInClusterWithState", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertState IN :alertStates"), + @NamedQuery(name = "AlertHistoryEntity.findAllInClusterBetweenDates", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp BETWEEN :startDate AND :endDate"), + @NamedQuery(name = "AlertHistoryEntity.findAllInClusterBeforeDate", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp <= :beforeDate"), + @NamedQuery(name = "AlertHistoryEntity.findAllIdsInClusterBeforeDate", query = "SELECT alertHistory.alertId FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp <= :beforeDate"), + @NamedQuery(name = "AlertHistoryEntity.findAllInClusterAfterDate", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp >= :afterDate"), + @NamedQuery(name = "AlertHistoryEntity.removeByDefinitionId", query = "DELETE FROM AlertHistoryEntity alertHistory WHERE alertHistory.alertDefinitionId = :definitionId"), + @NamedQuery(name = "AlertHistoryEntity.removeInClusterBeforeDate", query = "DELETE FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId AND alertHistory.alertTimestamp <= :beforeDate"), + @NamedQuery(name = "AlertHistoryEntity.findHistoryIdsByDefinitionId", query = "SELECT alertHistory.alertId FROM AlertHistoryEntity alertHistory WHERE alertHistory.alertDefinitionId = :definitionId ORDER BY alertHistory.alertId") }) public class AlertHistoryEntity { @@ -97,6 +99,9 @@ public class AlertHistoryEntity { @JoinColumn(name = "alert_definition_id", nullable = false) private AlertDefinitionEntity alertDefinition; + @Column(name = "alert_definition_id", nullable = false, insertable = false, updatable = false, length = 10) + private Long alertDefinitionId; + /** * Constructor. */ @@ -326,6 +331,23 @@ public class AlertHistoryEntity { */ public void setAlertDefinition(AlertDefinitionEntity alertDefinition) { this.alertDefinition = alertDefinition; + this.alertDefinitionId = alertDefinition.getDefinitionId(); + } + + /** + * Get parent alert definition id + * @return definition id + */ + public Long getAlertDefinitionId() { + return alertDefinitionId; + } + + /** + * Set parent alert definition id + * @param alertDefinitionId definition id + */ + public void setAlertDefinitionId(Long alertDefinitionId) { + this.alertDefinitionId = alertDefinitionId; } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java index ae7495d..cb24354 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java @@ -46,11 +46,14 @@ import org.apache.ambari.server.state.NotificationState; @Table(name = "alert_notice") @TableGenerator(name = "alert_notice_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_notice_id_seq", initialValue = 0) @NamedQueries({ - @NamedQuery(name = "AlertNoticeEntity.findAll", query = "SELECT notice FROM AlertNoticeEntity notice"), - @NamedQuery(name = "AlertNoticeEntity.findByState", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.notifyState = :notifyState"), - @NamedQuery(name = "AlertNoticeEntity.findByUuid", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.uuid = :uuid"), - @NamedQuery(name = "AlertNoticeEntity.removeByDefinitionId", query = "DELETE FROM AlertNoticeEntity notice WHERE notice.alertHistory.alertDefinition.definitionId = :definitionId"), - @NamedQuery(name = "AlertNoticeEntity.removeByAlertHistoryBeforeDate", query = "DELETE FROM AlertNoticeEntity notice WHERE notice.alertHistory.clusterId = :clusterId AND notice.alertHistory.alertTimestamp <= :beforeDate") + @NamedQuery(name = "AlertNoticeEntity.findAll", query = "SELECT notice FROM AlertNoticeEntity notice"), + @NamedQuery(name = "AlertNoticeEntity.findByState", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.notifyState = :notifyState"), + @NamedQuery(name = "AlertNoticeEntity.findByUuid", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.uuid = :uuid"), + @NamedQuery(name = "AlertNoticeEntity.findByHistoryIds", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.historyId IN :historyIds"), + // The remove query 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 = "AlertNoticeEntity.removeByHistoryIds", query = "DELETE FROM AlertNoticeEntity notice WHERE notice.historyId IN :historyIds") }) public class AlertNoticeEntity { @@ -74,6 +77,9 @@ public class AlertNoticeEntity { @JoinColumn(name = "history_id", nullable = false) private AlertHistoryEntity alertHistory; + @Column(name = "history_id", nullable = false, insertable = false, updatable = false, length = 10) + private Long historyId; + /** * Bi-directional many-to-one association to {@link AlertTargetEntity} */ @@ -165,6 +171,23 @@ public class AlertNoticeEntity { */ public void setAlertHistory(AlertHistoryEntity alertHistory) { this.alertHistory = alertHistory; + this.historyId = alertHistory.getAlertId(); + } + + /** + * Get parent AlertHistory id + * @return history id + */ + public Long getHistoryId() { + return historyId; + } + + /** + * Set parent Alert History id + * @param historyId history id + */ + public void setHistoryId(Long historyId) { + this.historyId = historyId; } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java index d611fe8..8083bfb 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java @@ -462,6 +462,7 @@ public class AlertResourceProviderTest { private List getClusterMockEntities() throws Exception { AlertCurrentEntity current = new AlertCurrentEntity(); current.setAlertId(Long.valueOf(1000L)); + current.setHistoryId(ALERT_VALUE_ID); current.setLatestTimestamp(Long.valueOf(1L)); current.setOriginalTimestamp(Long.valueOf(2L)); http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java index 36e75e7..88cbd1c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java @@ -22,6 +22,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.persist.PersistService; import com.google.inject.persist.UnitOfWork; +import junit.framework.Assert; import org.apache.ambari.server.controller.RootServiceResponseFactory; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; @@ -56,6 +57,7 @@ import java.util.UUID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * Tests {@link AlertDefinitionDAO} for interacting with @@ -261,7 +263,7 @@ public class AlertDefinitionDAOTest { @Test public void testFindByServiceComponent() { List definitions = dao.findByServiceComponent( - clusterId, "OOZIE", "OOZIE_SERVER"); + clusterId, "OOZIE", "OOZIE_SERVER"); assertNotNull(definitions); assertEquals(2, definitions.size()); @@ -318,6 +320,7 @@ public class AlertDefinitionDAOTest { history.setAlertState(AlertState.OK); history.setAlertText("Alert Text"); history.setAlertTimestamp(calendar.getTimeInMillis()); + alertsDao.create(history); AlertCurrentEntity current = new AlertCurrentEntity(); current.setAlertHistory(history); @@ -411,4 +414,73 @@ public class AlertDefinitionDAOTest { assertNotNull(definition.getCluster()); assertEquals(clusterId, definition.getCluster().getClusterId()); } + + @Test + public void testBatchDeleteOfNoticeEntities() throws Exception { + AlertDefinitionEntity definition = helper.createAlertDefinition(clusterId); + + AlertGroupEntity group = helper.createAlertGroup(clusterId, null); + group.addAlertDefinition(definition); + dispatchDao.merge(group); + + // Add 1000+ notice entities + for (int i = 0; i < 1500; i++) { + AlertHistoryEntity history = new AlertHistoryEntity(); + history.setServiceName(definition.getServiceName()); + history.setClusterId(clusterId); + history.setAlertDefinition(definition); + history.setAlertLabel("Label"); + history.setAlertState(AlertState.OK); + history.setAlertText("Alert Text"); + history.setAlertTimestamp(calendar.getTimeInMillis()); + alertsDao.create(history); + + AlertCurrentEntity current = new AlertCurrentEntity(); + current.setAlertHistory(history); + current.setLatestTimestamp(new Date().getTime()); + current.setOriginalTimestamp(new Date().getTime() - 10800000); + current.setMaintenanceState(MaintenanceState.OFF); + alertsDao.create(current); + + AlertNoticeEntity notice = new AlertNoticeEntity(); + notice.setAlertHistory(history); + notice.setAlertTarget(helper.createAlertTarget()); + notice.setNotifyState(NotificationState.PENDING); + notice.setUuid(UUID.randomUUID().toString()); + dispatchDao.create(notice); + } + + group = dispatchDao.findGroupById(group.getGroupId()); + assertNotNull(group); + assertNotNull(group.getAlertDefinitions()); + assertEquals(1, group.getAlertDefinitions().size()); + + List historyEntities = alertsDao.findAll(); + assertEquals(1500, historyEntities.size()); + + List currentEntities = alertsDao.findCurrentByDefinitionId(definition.getDefinitionId()); + assertNotNull(currentEntities); + assertEquals(1500, currentEntities.size()); + + List noticeEntities = dispatchDao.findAllNotices(); + Assert.assertEquals(1500, noticeEntities.size()); + + // delete the definition + definition = dao.findById(definition.getDefinitionId()); + dao.refresh(definition); + dao.remove(definition); + + List notices = dispatchDao.findAllNotices(); + assertTrue(notices.isEmpty()); + + currentEntities = alertsDao.findCurrentByDefinitionId(definition.getDefinitionId()); + assertTrue(currentEntities == null || currentEntities.isEmpty()); + historyEntities = alertsDao.findAll(); + assertTrue(historyEntities == null || historyEntities.isEmpty()); + + group = dispatchDao.findGroupById(group.getGroupId()); + assertNotNull(group); + assertNotNull(group.getAlertDefinitions()); + assertEquals(0, group.getAlertDefinitions().size()); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/85a5e975/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java index 10f099e..94f54d6 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java @@ -252,6 +252,7 @@ public class AlertsDAOTest { history.setAlertTimestamp(Long.valueOf(1L)); history.setHostName("h1"); history.setAlertState(AlertState.OK); + m_dao.create(history); // current for the history AlertCurrentEntity current = new AlertCurrentEntity(); @@ -273,6 +274,7 @@ public class AlertsDAOTest { history2.setAlertTimestamp(Long.valueOf(1L)); history2.setHostName("h2"); history2.setAlertState(AlertState.OK); + m_dao.create(history); // current for the history AlertCurrentEntity current2 = new AlertCurrentEntity(); @@ -339,6 +341,7 @@ public class AlertsDAOTest { history.setAlertTimestamp(Long.valueOf(1L)); history.setHostName(HOSTNAME); history.setAlertState(AlertState.OK); + m_dao.create(history); // current for the history AlertCurrentEntity current = new AlertCurrentEntity(); @@ -479,6 +482,7 @@ public class AlertsDAOTest { history.setAlertTimestamp(Long.valueOf(1L)); history.setHostName("h2"); history.setAlertState(AlertState.OK); + m_dao.create(history); // current for the history AlertCurrentEntity current = new AlertCurrentEntity(); @@ -922,6 +926,7 @@ public class AlertsDAOTest { history.setComponentName(""); history.setHostName("h2"); history.setServiceName("ServiceName"); + m_dao.create(history); current = new AlertCurrentEntity(); current.setAlertHistory(history);