1
|
package eu.dnetlib.msro.notification;
|
2
|
|
3
|
import java.io.StringReader;
|
4
|
import java.util.Date;
|
5
|
import java.util.HashMap;
|
6
|
import java.util.Map;
|
7
|
import java.util.Properties;
|
8
|
import java.util.concurrent.BlockingQueue;
|
9
|
import java.util.concurrent.LinkedBlockingQueue;
|
10
|
import javax.mail.*;
|
11
|
import javax.mail.internet.InternetAddress;
|
12
|
import javax.mail.internet.MimeMessage;
|
13
|
|
14
|
import com.google.common.base.Splitter;
|
15
|
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
|
16
|
import eu.dnetlib.msro.workflows.procs.WorkflowProcess;
|
17
|
import eu.dnetlib.msro.workflows.procs.WorkflowProcess.Status;
|
18
|
import eu.dnetlib.rmi.enabling.ISLookUpService;
|
19
|
import org.antlr.stringtemplate.StringTemplate;
|
20
|
import org.apache.commons.lang3.StringUtils;
|
21
|
import org.apache.commons.logging.Log;
|
22
|
import org.apache.commons.logging.LogFactory;
|
23
|
import org.dom4j.Document;
|
24
|
import org.dom4j.io.SAXReader;
|
25
|
import org.springframework.beans.factory.annotation.Autowired;
|
26
|
import org.springframework.beans.factory.annotation.Required;
|
27
|
|
28
|
public class EmailDispatcher {
|
29
|
|
30
|
private static final Log log = LogFactory.getLog(EmailDispatcher.class);
|
31
|
private final BlockingQueue<Message> queue = new LinkedBlockingQueue<Message>();
|
32
|
private String from;
|
33
|
private String fromName;
|
34
|
private String cc;
|
35
|
private String smtpHost;
|
36
|
private int smtpPort = 587;
|
37
|
private String smtpUser;
|
38
|
private String smtpPassword;
|
39
|
private String baseUrl;
|
40
|
private String infrastructure;
|
41
|
@Autowired
|
42
|
private UniqueServiceLocator serviceLocator;
|
43
|
|
44
|
public void sendMail(final String to, final String subject, final String message) {
|
45
|
try {
|
46
|
final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator());
|
47
|
|
48
|
final MimeMessage mimeMessage = new MimeMessage(session);
|
49
|
mimeMessage.setFrom(new InternetAddress(this.from, this.fromName));
|
50
|
mimeMessage.setSubject(subject);
|
51
|
mimeMessage.setContent(message, "text/html; charset=utf-8");
|
52
|
mimeMessage.setSentDate(new Date());
|
53
|
|
54
|
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
|
55
|
|
56
|
if ((this.cc != null) && !this.cc.isEmpty()) {
|
57
|
for (final String aCC : Splitter.on(",").omitEmptyStrings().trimResults().split(getCc())) {
|
58
|
mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(aCC));
|
59
|
}
|
60
|
}
|
61
|
|
62
|
this.queue.add(mimeMessage);
|
63
|
|
64
|
log.info("Mail to " + to + " in queue");
|
65
|
} catch (final Exception e) {
|
66
|
log.error("Error sending mail", e);
|
67
|
}
|
68
|
}
|
69
|
|
70
|
private String applyTemplate(final String template, final WorkflowProcess proc) {
|
71
|
final StringTemplate st = new StringTemplate(template);
|
72
|
st.setAttribute("proc", proc);
|
73
|
st.setAttribute("baseUrl", this.baseUrl);
|
74
|
st.setAttribute("infrastructure", this.infrastructure);
|
75
|
return st.toString();
|
76
|
}
|
77
|
|
78
|
public void processMailQueue() {
|
79
|
while (true) {
|
80
|
final Message message = this.queue.poll();
|
81
|
if (message == null) {
|
82
|
return;
|
83
|
} else {
|
84
|
try {
|
85
|
log.info("Sending mail...");
|
86
|
Transport.send(message);
|
87
|
log.info("...sent");
|
88
|
} catch (final MessagingException e) {
|
89
|
log.error("Error sending email", e);
|
90
|
this.queue.add(message);
|
91
|
return;
|
92
|
}
|
93
|
}
|
94
|
}
|
95
|
}
|
96
|
|
97
|
public void sendMails(final WorkflowProcess proc) {
|
98
|
|
99
|
final SAXReader reader = new SAXReader();
|
100
|
final Map<String, Document> emailProfiles = new HashMap<>();
|
101
|
|
102
|
try {
|
103
|
|
104
|
this.serviceLocator
|
105
|
.getService(ISLookUpService.class)
|
106
|
.quickSearchProfile("for $x in collection('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType') " +
|
107
|
"where $x//RESOURCE_IDENTIFIER/@value='" + proc.getProfileId() + "' " +
|
108
|
"or $x//RESOURCE_IDENTIFIER/@value='" + proc.getParentProfileId() + "' " +
|
109
|
"return $x//NOTIFICATIONS/EMAIL/concat(@condition , ' @@@ ', @messageProfileId, ' @@@ ', @address)")
|
110
|
.forEach(s -> {
|
111
|
final String[] arr = s.split("@@@");
|
112
|
if (StringUtils.isNoneBlank(arr[0].trim())) {
|
113
|
final NotificationCondition condition = NotificationCondition.valueOf(arr[0].trim());
|
114
|
final String emailProfileId = arr[1].trim();
|
115
|
final String to = arr[2].trim();
|
116
|
|
117
|
if (condition == NotificationCondition.ALWAYS ||
|
118
|
(condition == NotificationCondition.ONLY_FAILED && proc.getStatus() == Status.FAILURE) ||
|
119
|
(condition == NotificationCondition.ONLY_SUCCESS && proc.getStatus() == Status.SUCCESS)) {
|
120
|
try {
|
121
|
if (!emailProfiles.containsKey(emailProfileId)) {
|
122
|
final String profile = this.serviceLocator.getService(ISLookUpService.class).getResourceProfile(emailProfileId);
|
123
|
final Document doc = reader.read(new StringReader(profile));
|
124
|
emailProfiles.put(emailProfileId, doc);
|
125
|
}
|
126
|
final String subject = applyTemplate(emailProfiles.get(emailProfileId).valueOf("//SUBJECT_TEMPLATE").trim(), proc);
|
127
|
final String message = applyTemplate(emailProfiles.get(emailProfileId).valueOf("//EMAIL_TEMPLATE").trim(), proc);
|
128
|
|
129
|
sendMail(to, subject, message);
|
130
|
|
131
|
} catch (final Exception e) {
|
132
|
log.error("Error sending mail to " + to, e);
|
133
|
}
|
134
|
}
|
135
|
}
|
136
|
});
|
137
|
} catch (final Throwable e) {
|
138
|
log.error("Error generating sending mails for process: " + proc.getId(), e);
|
139
|
}
|
140
|
|
141
|
}
|
142
|
|
143
|
private Properties obtainProperties() {
|
144
|
final Properties props = new Properties();
|
145
|
props.put("mail.transport.protocol", "smtp");
|
146
|
props.put("mail.smtp.host", this.smtpHost);
|
147
|
props.put("mail.smtp.port", this.smtpPort);
|
148
|
props.put("mail.smtp.auth", Boolean.toString((this.smtpUser != null) && !this.smtpUser.isEmpty()));
|
149
|
return props;
|
150
|
}
|
151
|
|
152
|
private Authenticator obtainAuthenticator() {
|
153
|
if ((this.smtpUser == null) || this.smtpUser.isEmpty()) { return null; }
|
154
|
|
155
|
return new Authenticator() {
|
156
|
|
157
|
private final PasswordAuthentication authentication = new PasswordAuthentication(EmailDispatcher.this.smtpUser, EmailDispatcher.this.smtpPassword);
|
158
|
|
159
|
@Override
|
160
|
protected PasswordAuthentication getPasswordAuthentication() {
|
161
|
return this.authentication;
|
162
|
}
|
163
|
|
164
|
};
|
165
|
}
|
166
|
|
167
|
public String getFrom() {
|
168
|
return this.from;
|
169
|
}
|
170
|
|
171
|
@Required
|
172
|
public void setFrom(final String from) {
|
173
|
this.from = from;
|
174
|
}
|
175
|
|
176
|
public String getFromName() {
|
177
|
return this.fromName;
|
178
|
}
|
179
|
|
180
|
@Required
|
181
|
public void setFromName(final String fromName) {
|
182
|
this.fromName = fromName;
|
183
|
}
|
184
|
|
185
|
public String getCc() {
|
186
|
return this.cc;
|
187
|
}
|
188
|
|
189
|
@Required
|
190
|
public void setCc(final String cc) {
|
191
|
this.cc = cc;
|
192
|
}
|
193
|
|
194
|
public String getSmtpHost() {
|
195
|
return this.smtpHost;
|
196
|
}
|
197
|
|
198
|
@Required
|
199
|
public void setSmtpHost(final String smtpHost) {
|
200
|
this.smtpHost = smtpHost;
|
201
|
}
|
202
|
|
203
|
public int getSmtpPort() {
|
204
|
return this.smtpPort;
|
205
|
}
|
206
|
|
207
|
public void setSmtpPort(final int smtpPort) {
|
208
|
this.smtpPort = smtpPort;
|
209
|
}
|
210
|
|
211
|
public String getSmtpUser() {
|
212
|
return this.smtpUser;
|
213
|
}
|
214
|
|
215
|
public void setSmtpUser(final String smtpUser) {
|
216
|
this.smtpUser = smtpUser;
|
217
|
}
|
218
|
|
219
|
public String getSmtpPassword() {
|
220
|
return this.smtpPassword;
|
221
|
}
|
222
|
|
223
|
public void setSmtpPassword(final String smtpPassword) {
|
224
|
this.smtpPassword = smtpPassword;
|
225
|
}
|
226
|
|
227
|
public String getBaseUrl() {
|
228
|
return this.baseUrl;
|
229
|
}
|
230
|
|
231
|
@Required
|
232
|
public void setBaseUrl(final String baseUrl) {
|
233
|
this.baseUrl = baseUrl;
|
234
|
}
|
235
|
|
236
|
public String getInfrastructure() {
|
237
|
return this.infrastructure;
|
238
|
}
|
239
|
|
240
|
@Required
|
241
|
public void setInfrastructure(final String infrastructure) {
|
242
|
this.infrastructure = infrastructure;
|
243
|
}
|
244
|
|
245
|
}
|