@@ -8,12 +8,11 @@ import (
88 "sync"
99 "time"
1010
11- "github.com/icinga/icinga-go-library/backoff"
1211 "github.com/icinga/icinga-go-library/database"
1312 "github.com/icinga/icinga-go-library/logging"
1413 "github.com/icinga/icinga-go-library/notifications"
1514 "github.com/icinga/icinga-go-library/notifications/event"
16- "github.com/icinga/icinga-go-library/retry "
15+ "github.com/icinga/icinga-go-library/redis "
1716 "github.com/icinga/icinga-go-library/types"
1817 "github.com/icinga/icinga-go-library/utils"
1918 "github.com/icinga/icingadb/pkg/common"
@@ -41,6 +40,7 @@ type Source struct {
4140 ctxCancel context.CancelFunc
4241
4342 notificationsClient * notifications.Client // The Icinga Notifications client used to interact with the API.
43+ redisClient * redis.Client // redisClient is the Redis client used to fetch host and service names for events.
4444}
4545
4646// NewNotificationsSource creates a new Source connected to an existing database and logger.
@@ -49,6 +49,7 @@ type Source struct {
4949func NewNotificationsSource (
5050 ctx context.Context ,
5151 db * database.DB ,
52+ rc * redis.Client ,
5253 logger * logging.Logger ,
5354 cfg notifications.Config ,
5455) * Source {
@@ -61,7 +62,8 @@ func NewNotificationsSource(
6162 db : db ,
6263 logger : logger ,
6364
64- rules : & notifications.SourceRulesInfo {Version : notifications .EmptyRulesVersion },
65+ rules : & notifications.SourceRulesInfo {Version : notifications .EmptyRulesVersion },
66+ redisClient : rc ,
6567
6668 ctx : ctx ,
6769 ctxCancel : ctxCancel ,
@@ -136,63 +138,36 @@ func (s *Source) evaluateRulesForObject(ctx context.Context, entity database.Ent
136138 return outRuleIds [:len (outRuleIds ):len (outRuleIds )], nil
137139}
138140
139- // fetchHostServiceName for a host ID and a potential service ID from the Icinga DB relational database.
140- func (s * Source ) fetchHostServiceName (ctx context.Context , hostId , serviceId , envId types.Binary ) (host , service string , err error ) {
141- err = retry .WithBackoff (
142- ctx ,
143- func (ctx context.Context ) error {
144- queryHost := s .db .Rebind ("SELECT name FROM host WHERE id = ? AND environment_id = ?" )
145- err := s .db .QueryRowxContext (ctx , queryHost , hostId , envId ).Scan (& host )
146- if err != nil {
147- return errors .Wrap (err , "cannot select host" )
148- }
149-
150- if serviceId != nil {
151- queryService := s .db .Rebind ("SELECT name FROM service WHERE id = ? AND environment_id = ?" )
152- err := s .db .QueryRowxContext (ctx , queryService , serviceId , envId ).Scan (& service )
153- if err != nil {
154- return errors .Wrap (err , "cannot select service" )
155- }
156- }
157-
158- return nil
159- },
160- retry .Retryable ,
161- backoff .DefaultBackoff ,
162- retry.Settings {Timeout : retry .DefaultTimeout })
163- return
164- }
165-
166141// buildCommonEvent creates an event.Event based on Host and (optional) Service names.
167142//
168143// This function is used by all event builders to create a common event structure that includes the host and service
169144// names, the absolute URL to the Icinga Web 2 Icinga DB page for the host or service, and the tags for the event.
170145// Any event type-specific information (like severity, message, etc.) is added by the specific event builders.
171- func (s * Source ) buildCommonEvent (host , service string ) (* event.Event , error ) {
146+ func (s * Source ) buildCommonEvent (rlr * redisLookupResult ) (* event.Event , error ) {
172147 var (
173148 eventName string
174149 eventUrl * url.URL
175150 eventTags map [string ]string
176151 )
177152
178- if service != "" {
179- eventName = host + "!" + service
153+ if rlr . ServiceName != "" {
154+ eventName = rlr . HostName + "!" + rlr . ServiceName
180155
181156 eventUrl = s .notificationsClient .JoinIcingaWeb2Path ("/icingadb/service" )
182- eventUrl .RawQuery = "name=" + utils .RawUrlEncode (service ) + "&host.name=" + utils .RawUrlEncode (host )
157+ eventUrl .RawQuery = "name=" + utils .RawUrlEncode (rlr . ServiceName ) + "&host.name=" + utils .RawUrlEncode (rlr . HostName )
183158
184159 eventTags = map [string ]string {
185- "host" : host ,
186- "service" : service ,
160+ "host" : rlr . HostName ,
161+ "service" : rlr . ServiceName ,
187162 }
188163 } else {
189- eventName = host
164+ eventName = rlr . HostName
190165
191166 eventUrl = s .notificationsClient .JoinIcingaWeb2Path ("/icingadb/host" )
192- eventUrl .RawQuery = "name=" + utils .RawUrlEncode (host )
167+ eventUrl .RawQuery = "name=" + utils .RawUrlEncode (rlr . HostName )
193168
194169 eventTags = map [string ]string {
195- "host" : host ,
170+ "host" : rlr . HostName ,
196171 }
197172 }
198173
@@ -208,19 +183,19 @@ func (s *Source) buildCommonEvent(host, service string) (*event.Event, error) {
208183// The resulted event will have all the necessary information for a state change event, and must
209184// not be further modified by the caller.
210185func (s * Source ) buildStateHistoryEvent (ctx context.Context , h * v1history.StateHistory ) (* event.Event , error ) {
211- hostName , serviceName , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId , h . EnvironmentId )
186+ res , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId )
212187 if err != nil {
213- return nil , errors . Wrap ( err , "cannot fetch host/service information" )
188+ return nil , err
214189 }
215190
216- ev , err := s .buildCommonEvent (hostName , serviceName )
191+ ev , err := s .buildCommonEvent (res )
217192 if err != nil {
218- return nil , errors .Wrapf (err , "cannot build event for %q,%q" , hostName , serviceName )
193+ return nil , errors .Wrapf (err , "cannot build event for %q,%q" , res . HostName , res . ServiceName )
219194 }
220195
221196 ev .Type = event .TypeState
222197
223- if serviceName != "" {
198+ if res . ServiceName != "" {
224199 switch h .HardState {
225200 case 0 :
226201 ev .Severity = event .SeverityOK
@@ -256,14 +231,14 @@ func (s *Source) buildStateHistoryEvent(ctx context.Context, h *v1history.StateH
256231
257232// buildDowntimeHistoryEvent from a downtime history entry.
258233func (s * Source ) buildDowntimeHistoryEvent (ctx context.Context , h * v1history.DowntimeHistory ) (* event.Event , error ) {
259- hostName , serviceName , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId , h . EnvironmentId )
234+ res , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId )
260235 if err != nil {
261- return nil , errors . Wrap ( err , "cannot fetch host/service information" )
236+ return nil , err
262237 }
263238
264- ev , err := s .buildCommonEvent (hostName , serviceName )
239+ ev , err := s .buildCommonEvent (res )
265240 if err != nil {
266- return nil , errors .Wrapf (err , "cannot build event for %q,%q" , hostName , serviceName )
241+ return nil , errors .Wrapf (err , "cannot build event for %q,%q" , res . HostName , res . ServiceName )
267242 }
268243
269244 if h .HasBeenCancelled .Valid && h .HasBeenCancelled .Bool {
@@ -289,14 +264,14 @@ func (s *Source) buildDowntimeHistoryEvent(ctx context.Context, h *v1history.Dow
289264
290265// buildFlappingHistoryEvent from a flapping history entry.
291266func (s * Source ) buildFlappingHistoryEvent (ctx context.Context , h * v1history.FlappingHistory ) (* event.Event , error ) {
292- hostName , serviceName , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId , h . EnvironmentId )
267+ res , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId )
293268 if err != nil {
294- return nil , errors . Wrap ( err , "cannot fetch host/service information" )
269+ return nil , err
295270 }
296271
297- ev , err := s .buildCommonEvent (hostName , serviceName )
272+ ev , err := s .buildCommonEvent (res )
298273 if err != nil {
299- return nil , errors .Wrapf (err , "cannot build event for %q,%q" , hostName , serviceName )
274+ return nil , errors .Wrapf (err , "cannot build event for %q,%q" , res . HostName , res . ServiceName )
300275 }
301276
302277 if h .PercentStateChangeEnd .Valid {
@@ -320,14 +295,14 @@ func (s *Source) buildFlappingHistoryEvent(ctx context.Context, h *v1history.Fla
320295
321296// buildAcknowledgementHistoryEvent from an acknowledgment history entry.
322297func (s * Source ) buildAcknowledgementHistoryEvent (ctx context.Context , h * v1history.AcknowledgementHistory ) (* event.Event , error ) {
323- hostName , serviceName , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId , h . EnvironmentId )
298+ res , err := s .fetchHostServiceName (ctx , h .HostId , h .ServiceId )
324299 if err != nil {
325- return nil , errors . Wrap ( err , "cannot fetch host/service information" )
300+ return nil , err
326301 }
327302
328- ev , err := s .buildCommonEvent (hostName , serviceName )
303+ ev , err := s .buildCommonEvent (res )
329304 if err != nil {
330- return nil , errors .Wrapf (err , "cannot build event for %q,%q" , hostName , serviceName )
305+ return nil , errors .Wrapf (err , "cannot build event for %q,%q" , res . HostName , res . ServiceName )
331306 }
332307
333308 if ! h .ClearTime .Time ().IsZero () {
0 commit comments