Drop superfluous NotificationType mappings

This commit is contained in:
Yonas Habteab 2025-05-20 16:37:55 +02:00
parent 40a4bccc51
commit ea17fa4a4e
3 changed files with 81 additions and 104 deletions

View file

@ -8,7 +8,6 @@ import (
"github.com/icinga/icinga-go-library/types"
"github.com/icinga/icinga-go-library/utils"
"github.com/icinga/icingadb/pkg/common"
icingadbTypes "github.com/icinga/icingadb/pkg/icingadb/types"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1"
"github.com/icinga/icingadb/pkg/icingadb/v1/history"
"github.com/jmoiron/sqlx"
@ -621,17 +620,16 @@ func convertNotificationRows(
// migrated data itself via the history ID as object name, i.e. one "virtual object" per sent notification.
name := strconv.FormatUint(row.NotificationId, 10)
nt := convertNotificationType(row.NotificationReason, row.State)
ntEnum, err := nt.Value()
notificationType, err := convertNotificationType(row.NotificationReason, row.State)
if err != nil {
log.With("notification_reason", row.NotificationReason, "state", row.State).Errorf("%+v", err)
continue
}
ts := convertTime(row.EndTime.Int64, row.EndTimeUsec)
tsMilli := float64(ts.Time().UnixMilli())
notificationHistoryId := hashAny([]interface{}{env, name, ntEnum, tsMilli})
id := hashAny([]interface{}{env, "notification", name, ntEnum, tsMilli})
notificationHistoryId := hashAny([]interface{}{env, name, notificationType, tsMilli})
id := hashAny([]interface{}{env, "notification", name, notificationType, tsMilli})
typ := objectTypes[row.ObjecttypeId]
hostId := calcObjectId(env, row.Name1)
serviceId := calcServiceId(env, row.Name1, row.Name2)
@ -654,7 +652,7 @@ func convertNotificationRows(
ServiceId: serviceId,
},
NotificationId: calcObjectId(env, name),
Type: nt,
Type: history.NotificationType(notificationType),
SendTime: ts,
State: row.State,
PreviousHardState: previousHardState,
@ -699,34 +697,34 @@ func convertNotificationRows(
return
}
// convertNotificationType maps IDO values[1] to Icinga DB ones[2].
// convertNotificationType maps IDO values [^1] to their Icinga DB counterparts [^2].
//
// [1]: https://github.com/Icinga/icinga2/blob/32c7f7730db154ba0dff5856a8985d125791c/lib/db_ido/dbevents.cpp#L1507-L1524
// [2]: https://github.com/Icinga/icingadb/blob/8f31ac143875498797725adb9bfacf3d4/pkg/types/notification_type.go#L53-L61
func convertNotificationType(notificationReason, state uint8) icingadbTypes.NotificationType {
// [^1]: https://github.com/Icinga/icinga2/blob/32c7f7730db154ba0dff5856a8985d125791c/lib/db_ido/dbevents.cpp#L1507-L1524
// [^2]: https://github.com/Icinga/icinga2/blob/32c7f7730db154ba0dff5856a8985d125791c73e/lib/icingadb/icingadb-utility.cpp#L157-L176
func convertNotificationType(notificationReason, state uint8) (string, error) {
switch notificationReason {
case 0: // state
if state == 0 {
return 64 // recovery
return "recovery", nil
} else {
return 32 // problem
return "problem", nil
}
case 1: // acknowledgement
return 16
case 2: // flapping start
return 128
case 3: // flapping end
return 256
case 5: // downtime start
return 1
case 6: // downtime end
return 2
case 7: // downtime removed
return 4
case 8: // custom
return 8
default: // bad notification type
return 0
case 1:
return "acknowledgement", nil
case 2:
return "flapping_start", nil
case 3:
return "flapping_end", nil
case 5:
return "downtime_start", nil
case 6:
return "downtime_end", nil
case 7:
return "downtime_removed", nil
case 8:
return "custom", nil
default:
return "", fmt.Errorf("bad notification type: %d", notificationReason)
}
}

View file

@ -1,62 +0,0 @@
package types
import (
"database/sql/driver"
"encoding"
"github.com/pkg/errors"
"strconv"
)
// NotificationType specifies the reason of a sent notification.
type NotificationType uint16
// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (nt *NotificationType) UnmarshalText(text []byte) error {
s := string(text)
i, err := strconv.ParseUint(s, 10, 16)
if err != nil {
return errors.Wrapf(err, "can't parse %q into uint16", s)
}
n := NotificationType(i)
if _, ok := notificationTypes[n]; !ok {
return badNotificationType(s)
}
*nt = n
return nil
}
// Value implements the driver.Valuer interface.
func (nt NotificationType) Value() (driver.Value, error) {
if v, ok := notificationTypes[nt]; ok {
return v, nil
} else {
return nil, badNotificationType(nt)
}
}
// badNotificationType returns an error about a syntactically, but not semantically valid NotificationType.
func badNotificationType(t interface{}) error {
return errors.Errorf("bad notification type: %#v", t)
}
// notificationTypes maps all valid NotificationType values to their SQL representation.
var notificationTypes = map[NotificationType]string{
1: "downtime_start",
2: "downtime_end",
4: "downtime_removed",
8: "custom",
16: "acknowledgement",
32: "problem",
64: "recovery",
128: "flapping_start",
256: "flapping_end",
}
// Assert interface compliance.
var (
_ encoding.TextUnmarshaler = (*NotificationType)(nil)
_ driver.Valuer = NotificationType(0)
)

View file

@ -1,23 +1,24 @@
package history
import (
"database/sql/driver"
"encoding"
"github.com/icinga/icinga-go-library/database"
"github.com/icinga/icinga-go-library/types"
icingadbTypes "github.com/icinga/icingadb/pkg/icingadb/types"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1"
)
type NotificationHistory struct {
HistoryTableEntity `json:",inline"`
HistoryTableMeta `json:",inline"`
NotificationId types.Binary `json:"notification_id"`
Type icingadbTypes.NotificationType `json:"type"`
SendTime types.UnixMilli `json:"send_time"`
State uint8 `json:"state"`
PreviousHardState uint8 `json:"previous_hard_state"`
Author string `json:"author"`
Text types.String `json:"text"`
UsersNotified uint16 `json:"users_notified"`
NotificationId types.Binary `json:"notification_id"`
Type NotificationType `json:"type"`
SendTime types.UnixMilli `json:"send_time"`
State uint8 `json:"state"`
PreviousHardState uint8 `json:"previous_hard_state"`
Author string `json:"author"`
Text types.String `json:"text"`
UsersNotified uint16 `json:"users_notified"`
}
type UserNotificationHistory struct {
@ -42,10 +43,50 @@ func (*HistoryNotification) TableName() string {
return "history"
}
// NotificationType represents the type of notification for a notification history entry.
//
// Starting with Icinga 2 v2.15, the type is will always be written to Redis as a string.
// This merely exists to provide a compatibility with older history entries lying around in Redis,
// which may have been written as an integer.
type NotificationType string
// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (nt *NotificationType) UnmarshalText(text []byte) error {
switch t := string(text); t {
case "1":
*nt = "downtime_start"
case "2":
*nt = "downtime_end"
case "4":
*nt = "downtime_removed"
case "8":
*nt = "custom"
case "16":
*nt = "acknowledgement"
case "32":
*nt = "problem"
case "64":
*nt = "recovery"
case "128":
*nt = "flapping_start"
case "256":
*nt = "flapping_end"
default:
*nt = NotificationType(t)
}
return nil
}
// Value implements the driver.Valuer interface.
func (nt NotificationType) Value() (driver.Value, error) { return string(nt), nil }
// Assert interface compliance.
var (
_ UpserterEntity = (*NotificationHistory)(nil)
_ UpserterEntity = (*UserNotificationHistory)(nil)
_ database.TableNamer = (*HistoryNotification)(nil)
_ UpserterEntity = (*HistoryNotification)(nil)
_ UpserterEntity = (*NotificationHistory)(nil)
_ UpserterEntity = (*UserNotificationHistory)(nil)
_ database.TableNamer = (*HistoryNotification)(nil)
_ UpserterEntity = (*HistoryNotification)(nil)
_ encoding.TextUnmarshaler = (*NotificationType)(nil)
_ driver.Valuer = NotificationType("")
)