@@ -7,11 +7,13 @@ import (
7
7
"html/template"
8
8
"net/url"
9
9
"path/filepath"
10
+ "strings"
10
11
11
12
"github.com/grafana/grafana/pkg/bus"
12
13
"github.com/grafana/grafana/pkg/events"
13
14
"github.com/grafana/grafana/pkg/log"
14
15
m "github.com/grafana/grafana/pkg/models"
16
+ "github.com/grafana/grafana/pkg/registry"
15
17
"github.com/grafana/grafana/pkg/setting"
16
18
"github.com/grafana/grafana/pkg/util"
17
19
)
@@ -21,20 +23,31 @@ var tmplResetPassword = "reset_password.html"
21
23
var tmplSignUpStarted = "signup_started.html"
22
24
var tmplWelcomeOnSignUp = "welcome_on_signup.html"
23
25
24
- func Init () error {
25
- initMailQueue ()
26
- initWebhookQueue ()
26
+ func init () {
27
+ registry .RegisterService (& NotificationService {})
28
+ }
29
+
30
+ type NotificationService struct {
31
+ Bus bus.Bus `inject:""`
32
+ mailQueue chan * Message
33
+ webhookQueue chan * Webhook
34
+ log log.Logger
35
+ }
27
36
28
- bus .AddHandler ("email" , sendResetPasswordEmail )
29
- bus .AddHandler ("email" , validateResetPasswordCode )
30
- bus .AddHandler ("email" , sendEmailCommandHandler )
37
+ func (ns * NotificationService ) Init () error {
38
+ ns .log = log .New ("notifications" )
39
+ ns .mailQueue = make (chan * Message , 10 )
40
+ ns .webhookQueue = make (chan * Webhook , 10 )
31
41
32
- bus .AddCtxHandler ("email" , sendEmailCommandHandlerSync )
42
+ ns .Bus .AddHandler (ns .sendResetPasswordEmail )
43
+ ns .Bus .AddHandler (ns .validateResetPasswordCode )
44
+ ns .Bus .AddHandler (ns .sendEmailCommandHandler )
33
45
34
- bus .AddCtxHandler ("webhook" , SendWebhookSync )
46
+ ns .Bus .AddCtxHandler (ns .sendEmailCommandHandlerSync )
47
+ ns .Bus .AddCtxHandler (ns .SendWebhookSync )
35
48
36
- bus . AddEventListener (signUpStartedHandler )
37
- bus . AddEventListener (signUpCompletedHandler )
49
+ ns . Bus . AddEventListener (ns . signUpStartedHandler )
50
+ ns . Bus . AddEventListener (ns . signUpCompletedHandler )
38
51
39
52
mailTemplates = template .New ("name" )
40
53
mailTemplates .Funcs (template.FuncMap {
@@ -58,8 +71,37 @@ func Init() error {
58
71
return nil
59
72
}
60
73
61
- func SendWebhookSync (ctx context.Context , cmd * m.SendWebhookSync ) error {
62
- return sendWebRequestSync (ctx , & Webhook {
74
+ func (ns * NotificationService ) Run (ctx context.Context ) error {
75
+ for {
76
+ select {
77
+ case webhook := <- ns .webhookQueue :
78
+ err := ns .sendWebRequestSync (context .Background (), webhook )
79
+
80
+ if err != nil {
81
+ ns .log .Error ("Failed to send webrequest " , "error" , err )
82
+ }
83
+ case msg := <- ns .mailQueue :
84
+ num , err := send (msg )
85
+ tos := strings .Join (msg .To , "; " )
86
+ info := ""
87
+ if err != nil {
88
+ if len (msg .Info ) > 0 {
89
+ info = ", info: " + msg .Info
90
+ }
91
+ ns .log .Error (fmt .Sprintf ("Async sent email %d succeed, not send emails: %s%s err: %s" , num , tos , info , err ))
92
+ } else {
93
+ ns .log .Debug (fmt .Sprintf ("Async sent email %d succeed, sent emails: %s%s" , num , tos , info ))
94
+ }
95
+ case <- ctx .Done ():
96
+ return ctx .Err ()
97
+ }
98
+ }
99
+
100
+ return nil
101
+ }
102
+
103
+ func (ns * NotificationService ) SendWebhookSync (ctx context.Context , cmd * m.SendWebhookSync ) error {
104
+ return ns .sendWebRequestSync (ctx , & Webhook {
63
105
Url : cmd .Url ,
64
106
User : cmd .User ,
65
107
Password : cmd .Password ,
@@ -74,7 +116,7 @@ func subjectTemplateFunc(obj map[string]interface{}, value string) string {
74
116
return ""
75
117
}
76
118
77
- func sendEmailCommandHandlerSync (ctx context.Context , cmd * m.SendEmailCommandSync ) error {
119
+ func ( ns * NotificationService ) sendEmailCommandHandlerSync (ctx context.Context , cmd * m.SendEmailCommandSync ) error {
78
120
message , err := buildEmailMessage (& m.SendEmailCommand {
79
121
Data : cmd .Data ,
80
122
Info : cmd .Info ,
@@ -89,24 +131,22 @@ func sendEmailCommandHandlerSync(ctx context.Context, cmd *m.SendEmailCommandSyn
89
131
}
90
132
91
133
_ , err = send (message )
92
-
93
134
return err
94
135
}
95
136
96
- func sendEmailCommandHandler (cmd * m.SendEmailCommand ) error {
137
+ func ( ns * NotificationService ) sendEmailCommandHandler (cmd * m.SendEmailCommand ) error {
97
138
message , err := buildEmailMessage (cmd )
98
139
99
140
if err != nil {
100
141
return err
101
142
}
102
143
103
- addToMailQueue (message )
104
-
144
+ ns .mailQueue <- message
105
145
return nil
106
146
}
107
147
108
- func sendResetPasswordEmail (cmd * m.SendResetPasswordEmailCommand ) error {
109
- return sendEmailCommandHandler (& m.SendEmailCommand {
148
+ func ( ns * NotificationService ) sendResetPasswordEmail (cmd * m.SendResetPasswordEmailCommand ) error {
149
+ return ns . sendEmailCommandHandler (& m.SendEmailCommand {
110
150
To : []string {cmd .User .Email },
111
151
Template : tmplResetPassword ,
112
152
Data : map [string ]interface {}{
@@ -116,7 +156,7 @@ func sendResetPasswordEmail(cmd *m.SendResetPasswordEmailCommand) error {
116
156
})
117
157
}
118
158
119
- func validateResetPasswordCode (query * m.ValidateResetPasswordCodeQuery ) error {
159
+ func ( ns * NotificationService ) validateResetPasswordCode (query * m.ValidateResetPasswordCodeQuery ) error {
120
160
login := getLoginForEmailCode (query .Code )
121
161
if login == "" {
122
162
return m .ErrInvalidEmailCode
@@ -135,18 +175,18 @@ func validateResetPasswordCode(query *m.ValidateResetPasswordCodeQuery) error {
135
175
return nil
136
176
}
137
177
138
- func signUpStartedHandler (evt * events.SignUpStarted ) error {
178
+ func ( ns * NotificationService ) signUpStartedHandler (evt * events.SignUpStarted ) error {
139
179
if ! setting .VerifyEmailEnabled {
140
180
return nil
141
181
}
142
182
143
- log .Info ("User signup started: %s " , evt .Email )
183
+ ns . log .Info ("User signup started" , "email " , evt .Email )
144
184
145
185
if evt .Email == "" {
146
186
return nil
147
187
}
148
188
149
- err := sendEmailCommandHandler (& m.SendEmailCommand {
189
+ err := ns . sendEmailCommandHandler (& m.SendEmailCommand {
150
190
To : []string {evt .Email },
151
191
Template : tmplSignUpStarted ,
152
192
Data : map [string ]interface {}{
@@ -155,6 +195,7 @@ func signUpStartedHandler(evt *events.SignUpStarted) error {
155
195
"SignUpUrl" : setting .ToAbsUrl (fmt .Sprintf ("signup/?email=%s&code=%s" , url .QueryEscape (evt .Email ), url .QueryEscape (evt .Code ))),
156
196
},
157
197
})
198
+
158
199
if err != nil {
159
200
return err
160
201
}
@@ -163,12 +204,12 @@ func signUpStartedHandler(evt *events.SignUpStarted) error {
163
204
return bus .Dispatch (& emailSentCmd )
164
205
}
165
206
166
- func signUpCompletedHandler (evt * events.SignUpCompleted ) error {
207
+ func ( ns * NotificationService ) signUpCompletedHandler (evt * events.SignUpCompleted ) error {
167
208
if evt .Email == "" || ! setting .Smtp .SendWelcomeEmailOnSignUp {
168
209
return nil
169
210
}
170
211
171
- return sendEmailCommandHandler (& m.SendEmailCommand {
212
+ return ns . sendEmailCommandHandler (& m.SendEmailCommand {
172
213
To : []string {evt .Email },
173
214
Template : tmplWelcomeOnSignUp ,
174
215
Data : map [string ]interface {}{
0 commit comments