alert_notification.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package sqlstore
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "github.com/grafana/grafana/pkg/bus"
  8. m "github.com/grafana/grafana/pkg/models"
  9. )
  10. func init() {
  11. bus.AddHandler("sql", GetAlertNotifications)
  12. bus.AddHandler("sql", CreateAlertNotificationCommand)
  13. bus.AddHandler("sql", UpdateAlertNotification)
  14. bus.AddHandler("sql", DeleteAlertNotification)
  15. bus.AddHandler("sql", GetAlertNotificationsToSend)
  16. bus.AddHandler("sql", GetAllAlertNotifications)
  17. bus.AddHandler("sql", RecordNotificationJournal)
  18. bus.AddHandler("sql", GetLatestNotification)
  19. bus.AddHandler("sql", CleanNotificationJournal)
  20. }
  21. func DeleteAlertNotification(cmd *m.DeleteAlertNotificationCommand) error {
  22. return inTransaction(func(sess *DBSession) error {
  23. sql := "DELETE FROM alert_notification WHERE alert_notification.org_id = ? AND alert_notification.id = ?"
  24. _, err := sess.Exec(sql, cmd.OrgId, cmd.Id)
  25. return err
  26. })
  27. }
  28. func GetAlertNotifications(query *m.GetAlertNotificationsQuery) error {
  29. return getAlertNotificationInternal(query, newSession())
  30. }
  31. func GetAllAlertNotifications(query *m.GetAllAlertNotificationsQuery) error {
  32. results := make([]*m.AlertNotification, 0)
  33. if err := x.Where("org_id = ?", query.OrgId).Find(&results); err != nil {
  34. return err
  35. }
  36. query.Result = results
  37. return nil
  38. }
  39. func GetAlertNotificationsToSend(query *m.GetAlertNotificationsToSendQuery) error {
  40. var sql bytes.Buffer
  41. params := make([]interface{}, 0)
  42. sql.WriteString(`SELECT
  43. alert_notification.id,
  44. alert_notification.org_id,
  45. alert_notification.name,
  46. alert_notification.type,
  47. alert_notification.created,
  48. alert_notification.updated,
  49. alert_notification.settings,
  50. alert_notification.is_default,
  51. alert_notification.send_reminder,
  52. alert_notification.frequency
  53. FROM alert_notification
  54. `)
  55. sql.WriteString(` WHERE alert_notification.org_id = ?`)
  56. params = append(params, query.OrgId)
  57. sql.WriteString(` AND ((alert_notification.is_default = ?)`)
  58. params = append(params, dialect.BooleanStr(true))
  59. if len(query.Ids) > 0 {
  60. sql.WriteString(` OR alert_notification.id IN (?` + strings.Repeat(",?", len(query.Ids)-1) + ")")
  61. for _, v := range query.Ids {
  62. params = append(params, v)
  63. }
  64. }
  65. sql.WriteString(`)`)
  66. results := make([]*m.AlertNotification, 0)
  67. if err := x.SQL(sql.String(), params...).Find(&results); err != nil {
  68. return err
  69. }
  70. query.Result = results
  71. return nil
  72. }
  73. func getAlertNotificationInternal(query *m.GetAlertNotificationsQuery, sess *DBSession) error {
  74. var sql bytes.Buffer
  75. params := make([]interface{}, 0)
  76. sql.WriteString(`SELECT
  77. alert_notification.id,
  78. alert_notification.org_id,
  79. alert_notification.name,
  80. alert_notification.type,
  81. alert_notification.created,
  82. alert_notification.updated,
  83. alert_notification.settings,
  84. alert_notification.is_default,
  85. alert_notification.send_reminder,
  86. alert_notification.frequency
  87. FROM alert_notification
  88. `)
  89. sql.WriteString(` WHERE alert_notification.org_id = ?`)
  90. params = append(params, query.OrgId)
  91. if query.Name != "" || query.Id != 0 {
  92. if query.Name != "" {
  93. sql.WriteString(` AND alert_notification.name = ?`)
  94. params = append(params, query.Name)
  95. }
  96. if query.Id != 0 {
  97. sql.WriteString(` AND alert_notification.id = ?`)
  98. params = append(params, query.Id)
  99. }
  100. }
  101. results := make([]*m.AlertNotification, 0)
  102. if err := sess.Sql(sql.String(), params...).Find(&results); err != nil {
  103. return err
  104. }
  105. if len(results) == 0 {
  106. query.Result = nil
  107. } else {
  108. query.Result = results[0]
  109. }
  110. return nil
  111. }
  112. func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error {
  113. return inTransaction(func(sess *DBSession) error {
  114. existingQuery := &m.GetAlertNotificationsQuery{OrgId: cmd.OrgId, Name: cmd.Name}
  115. err := getAlertNotificationInternal(existingQuery, sess)
  116. if err != nil {
  117. return err
  118. }
  119. if existingQuery.Result != nil {
  120. return fmt.Errorf("Alert notification name %s already exists", cmd.Name)
  121. }
  122. var frequency time.Duration
  123. if cmd.SendReminder {
  124. if cmd.Frequency == "" {
  125. return m.ErrNotificationFrequencyNotFound
  126. }
  127. frequency, err = time.ParseDuration(cmd.Frequency)
  128. if err != nil {
  129. return err
  130. }
  131. }
  132. alertNotification := &m.AlertNotification{
  133. OrgId: cmd.OrgId,
  134. Name: cmd.Name,
  135. Type: cmd.Type,
  136. Settings: cmd.Settings,
  137. SendReminder: cmd.SendReminder,
  138. Frequency: frequency,
  139. Created: time.Now(),
  140. Updated: time.Now(),
  141. IsDefault: cmd.IsDefault,
  142. }
  143. if _, err = sess.MustCols("send_reminder").Insert(alertNotification); err != nil {
  144. return err
  145. }
  146. cmd.Result = alertNotification
  147. return nil
  148. })
  149. }
  150. func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
  151. return inTransaction(func(sess *DBSession) (err error) {
  152. current := m.AlertNotification{}
  153. if _, err = sess.ID(cmd.Id).Get(&current); err != nil {
  154. return err
  155. }
  156. // check if name exists
  157. sameNameQuery := &m.GetAlertNotificationsQuery{OrgId: cmd.OrgId, Name: cmd.Name}
  158. if err := getAlertNotificationInternal(sameNameQuery, sess); err != nil {
  159. return err
  160. }
  161. if sameNameQuery.Result != nil && sameNameQuery.Result.Id != current.Id {
  162. return fmt.Errorf("Alert notification name %s already exists", cmd.Name)
  163. }
  164. current.Updated = time.Now()
  165. current.Settings = cmd.Settings
  166. current.Name = cmd.Name
  167. current.Type = cmd.Type
  168. current.IsDefault = cmd.IsDefault
  169. current.SendReminder = cmd.SendReminder
  170. if current.SendReminder {
  171. if cmd.Frequency == "" {
  172. return m.ErrNotificationFrequencyNotFound
  173. }
  174. frequency, err := time.ParseDuration(cmd.Frequency)
  175. if err != nil {
  176. return err
  177. }
  178. current.Frequency = frequency
  179. }
  180. sess.UseBool("is_default", "send_reminder")
  181. if affected, err := sess.ID(cmd.Id).Update(current); err != nil {
  182. return err
  183. } else if affected == 0 {
  184. return fmt.Errorf("Could not update alert notification")
  185. }
  186. cmd.Result = &current
  187. return nil
  188. })
  189. }
  190. func RecordNotificationJournal(cmd *m.RecordNotificationJournalCommand) error {
  191. return inTransaction(func(sess *DBSession) error {
  192. journalEntry := &m.NotificationJournal{
  193. OrgId: cmd.OrgId,
  194. AlertId: cmd.AlertId,
  195. NotifierId: cmd.NotifierId,
  196. SentAt: cmd.SentAt,
  197. Success: cmd.Success,
  198. }
  199. if _, err := sess.Insert(journalEntry); err != nil {
  200. return err
  201. }
  202. return nil
  203. })
  204. }
  205. func GetLatestNotification(cmd *m.GetLatestNotificationQuery) error {
  206. return inTransaction(func(sess *DBSession) error {
  207. notificationJournal := &m.NotificationJournal{}
  208. _, err := sess.Desc("notification_journal.sent_at").Limit(1).Where("notification_journal.org_id = ? AND notification_journal.alert_id = ? AND notification_journal.notifier_id = ?", cmd.OrgId, cmd.AlertId, cmd.NotifierId).Get(notificationJournal)
  209. if err != nil {
  210. return err
  211. }
  212. cmd.Result = notificationJournal
  213. return nil
  214. })
  215. }
  216. func CleanNotificationJournal(cmd *m.CleanNotificationJournalCommand) error {
  217. return inTransaction(func(sess *DBSession) error {
  218. sql := "DELETE FROM notification_journal WHERE notification_journal.org_id = ? AND notification_journal.alert_id = ? AND notification_journal.notifier_id = ?"
  219. _, err := sess.Exec(sql, cmd.OrgId, cmd.AlertId, cmd.NotifierId)
  220. return err
  221. })
  222. }