@@ -10,11 +10,13 @@ import (
1010 "github.com/icinga/icingadb/pkg/icingaredis"
1111 "github.com/icinga/icingadb/pkg/icingaredis/telemetry"
1212 "github.com/icinga/icingadb/pkg/logging"
13+ "github.com/icinga/icingadb/pkg/types"
1314 "github.com/icinga/icingadb/pkg/utils"
1415 "github.com/pkg/errors"
1516 "go.uber.org/zap"
1617 "golang.org/x/sync/errgroup"
1718 "runtime"
19+ "strings"
1820 "time"
1921)
2022
@@ -85,7 +87,8 @@ func (s Sync) Sync(ctx context.Context, subject *common.SyncSubject) error {
8587
8688 actual , dbErrs := s .db .YieldAll (
8789 ctx , subject .FactoryForDelta (),
88- s .db .BuildSelectStmt (NewScopedEntity (subject .Entity (), e .Meta ()), subject .Entity ().Fingerprint ()), e .Meta (),
90+ s .db .BuildSelectStmt (NewScopedEntity (subject .Entity (), e .Meta ()), subject .Entity ().Fingerprint ()),
91+ true , e .Meta (),
8992 )
9093 // Let errors from DB cancel our group.
9194 com .ErrgroupReceive (g , dbErrs )
@@ -128,9 +131,31 @@ func (s Sync) ApplyDelta(ctx context.Context, delta *Delta) error {
128131 entities = delta .Create .Entities (ctx )
129132 }
130133
134+ var slaTrailEntities chan contracts.Entity
135+ onSuccessHandlers := []OnSuccess [contracts.Entity ]{
136+ OnSuccessIncrement [contracts.Entity ](stat ),
137+ }
138+
139+ switch delta .Subject .Entity ().(type ) {
140+ case * v1.Host , * v1.Service :
141+ slaTrailEntities = make (chan contracts.Entity )
142+ onSuccessHandlers = append (onSuccessHandlers , OnSuccessSendTo [contracts.Entity ](slaTrailEntities ))
143+ }
144+
131145 g .Go (func () error {
132- return s .db .CreateStreamed (ctx , entities , OnSuccessIncrement [contracts.Entity ](stat ))
146+ if slaTrailEntities != nil {
147+ defer close (slaTrailEntities )
148+ }
149+
150+ return s .db .CreateStreamed (ctx , entities , onSuccessHandlers ... )
133151 })
152+
153+ if slaTrailEntities != nil {
154+ s .logger .Infof ("Inserting %d items of type %s sla history trails of type create" , len (delta .Create ), utils .Key (utils .Name (delta .Subject .Entity ()), ' ' ))
155+ g .Go (func () error {
156+ return s .db .CreateStreamed (ctx , CheckableToSlaTrailEntities (ctx , g , slaTrailEntities , "create" ))
157+ })
158+ }
134159 }
135160
136161 // Update
@@ -160,6 +185,60 @@ func (s Sync) ApplyDelta(ctx context.Context, delta *Delta) error {
160185 // Delete
161186 if len (delta .Delete ) > 0 {
162187 s .logger .Infof ("Deleting %d items of type %s" , len (delta .Delete ), utils .Key (utils .Name (delta .Subject .Entity ()), ' ' ))
188+ entity := delta .Subject .Entity ()
189+ switch entity .(type ) {
190+ case * v1.Host , * v1.Service :
191+ s .logger .Infof ("Inserting %d items of type %s sla history trails of type delete" , len (delta .Delete ), utils .Key (utils .Name (entity ), ' ' ))
192+ if _ , ok := entity .(* v1.Host ); ok {
193+ entities := make (chan contracts.Entity , 1 )
194+ g .Go (func () error {
195+ defer close (entities )
196+
197+ env , ok := v1 .EnvironmentFromContext (ctx )
198+ if ! ok {
199+ return errors .New ("can't get environment from context" )
200+ }
201+
202+ now := time .Now ()
203+ for _ , id := range delta .Delete .IDs () {
204+ sht := & SlaHistoryTrail {
205+ EnvironmentMeta : v1.EnvironmentMeta {EnvironmentId : env .Id },
206+ HostId : id .(types.Binary ),
207+ EventType : "delete" ,
208+ EventTime : types .UnixMilli (now ),
209+ }
210+
211+ entities <- sht
212+ }
213+
214+ return nil
215+ })
216+
217+ g .Go (func () error {
218+ return s .db .CreateStreamed (ctx , entities )
219+ })
220+ } else {
221+ g .Go (func () error {
222+ columns := & SlaServiceHistoryTrailColumns {}
223+ query := s .db .BuildSelectStmt (entity , columns )
224+ if len (delta .Delete ) == 1 {
225+ query += ` WHERE id = ?`
226+ } else {
227+ var placeholders []string
228+ for i := 0 ; i < len (delta .Delete ); i ++ {
229+ placeholders = append (placeholders , "?" )
230+ }
231+
232+ query += fmt .Sprintf (` WHERE id IN (%s)` , strings .Join (placeholders , `, ` ))
233+ }
234+ entities , err := s .db .YieldAll (ctx , delta .Subject .Factory (), query , false , delta .Delete .IDs ()... )
235+ com .ErrgroupReceive (g , err )
236+
237+ return s .db .CreateStreamed (ctx , entities )
238+ })
239+ }
240+ }
241+
163242 g .Go (func () error {
164243 return s .db .Delete (ctx , delta .Subject .Entity (), delta .Delete .IDs (), OnSuccessIncrement [any ](stat ))
165244 })
@@ -187,7 +266,8 @@ func (s Sync) SyncCustomvars(ctx context.Context) error {
187266
188267 actualCvs , errs := s .db .YieldAll (
189268 ctx , cv .FactoryForDelta (),
190- s .db .BuildSelectStmt (NewScopedEntity (cv .Entity (), e .Meta ()), cv .Entity ().Fingerprint ()), e .Meta (),
269+ s .db .BuildSelectStmt (NewScopedEntity (cv .Entity (), e .Meta ()), cv .Entity ().Fingerprint ()),
270+ true , e .Meta (),
191271 )
192272 com .ErrgroupReceive (g , errs )
193273
@@ -199,7 +279,8 @@ func (s Sync) SyncCustomvars(ctx context.Context) error {
199279
200280 actualFlatCvs , errs := s .db .YieldAll (
201281 ctx , flatCv .FactoryForDelta (),
202- s .db .BuildSelectStmt (NewScopedEntity (flatCv .Entity (), e .Meta ()), flatCv .Entity ().Fingerprint ()), e .Meta (),
282+ s .db .BuildSelectStmt (NewScopedEntity (flatCv .Entity (), e .Meta ()), flatCv .Entity ().Fingerprint ()),
283+ true , e .Meta (),
203284 )
204285 com .ErrgroupReceive (g , errs )
205286
0 commit comments