Merge branch '16265-security-updates' into dependabot/bundler/services/api/rake-13.0.1
[arvados.git] / services / ws / event.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "database/sql"
9         "sync"
10         "time"
11
12         "git.arvados.org/arvados.git/sdk/go/arvados"
13         "github.com/ghodss/yaml"
14 )
15
16 type eventSink interface {
17         Channel() <-chan *event
18         Stop()
19 }
20
21 type eventSource interface {
22         NewSink() eventSink
23         DB() *sql.DB
24         DBHealth() error
25 }
26
27 type event struct {
28         LogID    uint64
29         Received time.Time
30         Ready    time.Time
31         Serial   uint64
32
33         db     *sql.DB
34         logRow *arvados.Log
35         err    error
36         mtx    sync.Mutex
37 }
38
39 // Detail returns the database row corresponding to the event. It can
40 // be called safely from multiple goroutines. Only one attempt will be
41 // made. If the database row cannot be retrieved, Detail returns nil.
42 func (e *event) Detail() *arvados.Log {
43         e.mtx.Lock()
44         defer e.mtx.Unlock()
45         if e.logRow != nil || e.err != nil {
46                 return e.logRow
47         }
48         var logRow arvados.Log
49         var propYAML []byte
50         e.err = e.db.QueryRow(`SELECT id, uuid, object_uuid, COALESCE(object_owner_uuid,''), COALESCE(event_type,''), event_at, created_at, properties FROM logs WHERE id = $1`, e.LogID).Scan(
51                 &logRow.ID,
52                 &logRow.UUID,
53                 &logRow.ObjectUUID,
54                 &logRow.ObjectOwnerUUID,
55                 &logRow.EventType,
56                 &logRow.EventAt,
57                 &logRow.CreatedAt,
58                 &propYAML)
59         if e.err != nil {
60                 logger(nil).WithField("LogID", e.LogID).WithError(e.err).Error("QueryRow failed")
61                 return nil
62         }
63         e.err = yaml.Unmarshal(propYAML, &logRow.Properties)
64         if e.err != nil {
65                 logger(nil).WithField("LogID", e.LogID).WithError(e.err).Error("yaml decode failed")
66                 return nil
67         }
68         e.logRow = &logRow
69         return e.logRow
70 }