Project

General

Profile

1
package eu.dnetlib.data.emailSender;
2

    
3
import eu.dnetlib.data.claims.entity.Claim;
4
import eu.dnetlib.data.claims.entity.Context;
5
import eu.dnetlib.data.claims.entity.Notification;
6
import eu.dnetlib.data.claims.entity.Project;
7
import eu.dnetlib.data.claims.handler.*;
8
import eu.dnetlib.data.claims.utils.ClaimUtils;
9
import eu.dnetlib.data.claims.utils.CommunityUtils;
10
import eu.dnetlib.data.claims.sql.SQLStoreException;
11
import org.apache.log4j.Logger;
12
import org.springframework.beans.factory.annotation.Autowired;
13

    
14
import javax.mail.*;
15
import javax.mail.internet.AddressException;
16
import javax.mail.internet.InternetAddress;
17
import javax.mail.internet.MimeMessage;
18
import java.text.SimpleDateFormat;
19
import java.util.*;
20

    
21
public class EmailSender implements Runnable {
22

    
23
    private static final Logger logger = Logger.getLogger(EmailSender.class);
24

    
25
    @Autowired
26
    private FetchClaimHandler fetchClaimHandler = null;
27
    @Autowired
28
    private FetchProjectHandler fetchProjectHandler = null;
29
    @Autowired
30
    private FetchNotificationHandler fetchNotificationHandler = null;
31
    @Autowired
32
    private NotificationHandler notificationHandler = null;
33
    @Autowired
34
    private FetchContextHandler fetchContextHandler = null;
35

    
36
    @Autowired
37
    private String defaultFrequencyInHours;
38

    
39
    private static String manageCommunityUserNotificationsPage;
40
    private static String openaireProjectClaimsPage;
41
    private static String openaireCommunityClaimsPage;
42
    private static String username;
43
    private static String password;
44
    private static String host;
45
    private static String port;
46
    private static String from;
47
    private static String auth;
48
    private static String contactMail;
49
    private static String specialRecipients;
50
    private static String enabledCommunities;
51
    private static boolean notifyCommunityManagers;
52
    private static boolean notifyProjectManagers;
53

    
54
    @Override
55
    public void run() {
56
        logger.info("EmailSender thread is running. " + host);
57
        logger.info("Special Recipients  " + specialRecipients);
58
        logger.info("Enabled Communities " + enabledCommunities);
59

    
60
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
61
        Date date = new Date();
62
        String dateTo = (format.format(date));
63
        if(notifyCommunityManagers){
64
            defaultEmails_For_CommunityClaims(dateTo, format);  // daily for managers not in notification table
65
            notificationEmails_For_CommunityClaims(dateTo, format);
66
        }
67
        if(notifyProjectManagers) {
68
//        defaultEmails_For_ProjectClaims(dateTo, format);    // daily for managers not in notification table
69
//        notificationEmails_For_ProjectClaims(dateTo, format);
70
        }
71
    }
72

    
73
    public void defaultEmails_For_ProjectClaims(String dateTo, SimpleDateFormat format) {
74
        Map<String, List<String>> managersOfProject = new HashMap<String, List<String>>();
75
        Project project;
76
        List<Claim> claims = null;
77
        List<String> types = new ArrayList<String>();
78

    
79
        types.add(ClaimUtils.PROJECT);
80

    
81
        Calendar calendar = Calendar.getInstance();
82
        calendar.add(Calendar.HOUR_OF_DAY, -(Integer.parseInt(defaultFrequencyInHours)-1));
83
        calendar.add(Calendar.MINUTE, -59);
84
        calendar.add(Calendar.SECOND, -59);
85
        Date date = calendar.getTime();
86
        String dateFrom=(format.format(date));
87

    
88
        logger.debug("Sending emails for project claims between " + dateFrom + " and "+dateTo);
89

    
90
        try {
91
            // Get all claims between dateFrom and dateTo which satisfy source_type == "project" or target_type == "project"
92
            claims = fetchClaimHandler.fetchClaimsByDate(dateFrom, dateTo, null, null, "", "source", true, types, false);
93
        } catch (SQLStoreException|Exception e) {
94
            logger.error("Could not fetch claims by date from "+dateFrom+" to "+dateTo, e);
95
        }
96

    
97
        for (Claim claim: claims) {
98
            if (claim.getSourceType().equals("project")) {
99
                project = (Project)claim.getSource();
100
            } else {
101
                project = (Project)claim.getTarget();
102
            }
103

    
104
            if (!managersOfProject.containsKey(project.getOpenaireId())) {
105

    
106
                // specialRecipients are used currently for testing purposes
107
                List<String> tmpManagers = null;
108
                if (specialRecipients != null && !specialRecipients.isEmpty()) {
109
                    tmpManagers = new ArrayList<>(Arrays.asList(specialRecipients.split("\\s*,\\s*")));
110
                    logger.debug("Special recipients: " + specialRecipients);
111

    
112
                    if(tmpManagers != null) {
113
                        Iterator itr = tmpManagers.iterator();
114
                        while (itr.hasNext()) {
115
                            String manager = (String) itr.next();
116
                            Notification notification = null;
117
                            try {
118
                                notification = fetchNotificationHandler.fetchNotification(project.getOpenaireId(), manager);
119
                            } catch (Exception e) {
120
                                e.printStackTrace();
121
                            } catch (SQLStoreException e) {
122
                                e.printStackTrace();
123
                            }
124
                            if (notification != null) {
125
                                itr.remove();
126
                            }
127
                        }
128
                    }
129

    
130
                    managersOfProject.put(project.getOpenaireId(), tmpManagers);
131
                }
132

    
133
                // Send emails to actual project managers instead of special recipients
134
                List<String> managers = null;
135
                try {
136
                    managers = fetchProjectHandler.fetchContactEmailsByProjectId(project.getOpenaireId());
137
                    logger.debug("All actual Managers of project " + project.getOpenaireId() + ": "+managers);
138

    
139
                    if(managers != null) {
140
                        Iterator itr = managers.iterator();
141
                        while (itr.hasNext()) {
142
                            String manager = (String) itr.next();
143
                            Notification notification = fetchNotificationHandler.fetchNotification(project.getOpenaireId(), manager);
144
                            //if (notification != null && (!notification.isNotify() || notification.getFrequency() != 24)) {
145
                            if (notification != null) {
146
                                itr.remove();
147
                            }
148
                        }
149
                    }
150
                } catch (Exception e) {
151
                    e.printStackTrace();
152
                } catch (SQLStoreException e) {
153
                    e.printStackTrace();
154
                }
155

    
156
                logger.debug("Managers of project (not in notification table) " + project.getOpenaireId() + ": "+managers);
157
                /*
158
                managersOfProject.put(project.getOpenaireId(), managers);
159
                */
160

    
161
                if (managersOfProject.get(project.getOpenaireId()) != null &&
162
                        !managersOfProject.get(project.getOpenaireId()).isEmpty()) {
163
                    send(project.getOpenaireId(), project.getName(), "project", managersOfProject.get(project.getOpenaireId()));
164
                }
165
            }
166
        }
167
    }
168

    
169
    public void defaultEmails_For_CommunityClaims(String dateTo, SimpleDateFormat format) {
170
        Map<String, List<String>> managersOfCommunity = new HashMap<String, List<String>>();
171
        Context context;
172
        List<Claim> claims = null;
173
        List<String> types = new ArrayList<String>();
174

    
175
        types.add(ClaimUtils.CONTEXT);
176

    
177
        Calendar calendar = Calendar.getInstance();
178
        calendar.add(Calendar.HOUR_OF_DAY, -(Integer.parseInt(defaultFrequencyInHours)-1));
179
        calendar.add(Calendar.MINUTE, -59);
180
        calendar.add(Calendar.SECOND, -59);
181
        Date date = calendar.getTime();
182
        String dateFrom=(format.format(date));
183

    
184
        List<String> enabledCommunitiesList = null;
185
        if (enabledCommunities != null && !enabledCommunities.isEmpty()) {
186
            enabledCommunitiesList = Arrays.asList(enabledCommunities.split("\\s*,\\s*"));
187
        }
188

    
189
        logger.debug("Sending emails for community claims between " + dateFrom + " and "+dateTo);
190

    
191
        try {
192
            // Get all claims between dateFrom and dateTo which satisfy source_type == "context" or target_type == "context"
193
            claims = fetchClaimHandler.fetchClaimsByDate(dateFrom, dateTo, null, null, "", "source", true, types, false);
194
        } catch (SQLStoreException|Exception e) {
195
            logger.error("Could not fetch claims by date from "+dateFrom+" to "+dateTo, e);
196
        }
197

    
198
        for (Claim claim: claims) {
199
            if (claim.getSourceType().equals("context")) {
200
                context = (Context)claim.getSource();
201
            } else {
202
                context = (Context)claim.getTarget();
203
            }
204

    
205
            String openaireId = context.getOpenaireId().split("::")[0];
206
            if (!managersOfCommunity.containsKey(openaireId) && enabledCommunitiesList != null && enabledCommunitiesList.contains(openaireId)) {
207

    
208
                /*
209
                // specialRecipients are used currently for testing purposes
210
                List<String> tmpManagers = null;
211
                if (specialRecipients != null && !specialRecipients.isEmpty()) {
212
                    tmpManagers = Arrays.asList(specialRecipients.split("\\s*,\\s*"));
213
                    logger.debug("Special recipients: " + specialRecipients);
214
                    managersOfCommunity.put(openaireId, tmpManagers);
215
                }
216
                */
217

    
218

    
219
                // Send emails to actual project managers instead of special recipients
220
                List<String> managers = null;
221
                try {
222
                    CommunityUtils communityInfo = CommunityUtils.getCommunityInfo(openaireId);
223
                    managers = communityInfo.getManagers();
224
                    if(managers != null) {
225
                        Iterator itr = managers.iterator();
226
                        while (itr.hasNext()) {
227
                            String manager = (String) itr.next();
228
                            Notification notification = fetchNotificationHandler.fetchNotification(openaireId, manager);
229
                            if (notification != null) {
230
                                itr.remove();
231
                            } else {
232
                                logger.debug("Sending email to community manager: "+ manager);
233
                            }
234
                        }
235
                    }
236
                    else {
237
                        logger.debug("Community Managers: null");
238
                    }
239
                } catch (Exception e) {
240
                    e.printStackTrace();
241
                } catch (SQLStoreException e) {
242
                    e.printStackTrace();
243
                }
244

    
245
                logger.debug("Managers of community " + openaireId + ": "+managers);
246
                managersOfCommunity.put(openaireId, managers);
247

    
248

    
249
                if (managersOfCommunity.get(openaireId) != null &&
250
                        !managersOfCommunity.get(openaireId).isEmpty()) {
251
                    send(openaireId, context.getTitle().split(">")[0], "community", managersOfCommunity.get(openaireId));
252
                }
253
            } else if(enabledCommunitiesList == null || !enabledCommunitiesList.contains(openaireId)) {
254
                logger.debug("Community "+openaireId+" is not enabled");
255
            }
256
        }
257
    }
258

    
259
    public void notificationEmails_For_ProjectClaims(String dateTo, SimpleDateFormat format) {
260
        Project project = null;
261
        List<String> types = new ArrayList<String>();
262

    
263
        types.add(ClaimUtils.PROJECT);
264

    
265
        logger.debug("Sending email for project claims from notification table");
266

    
267
        try {
268
            List<Notification> trueNotifications = fetchNotificationHandler.fetchTrueNotifications();
269
            logger.debug(trueNotifications);
270
            if(trueNotifications != null) {
271
                for(Notification notification : trueNotifications) {
272
                    List<String> managers = fetchProjectHandler.fetchContactEmailsByProjectId(notification.getOpenaireId());
273
                    if(managers != null && managers.contains(notification.getUserMail())) {
274

    
275
                        Date _dateTo = format.parse(dateTo);
276

    
277
                        Date _last_interaction_date = notification.getDate();
278
                        Calendar cal = Calendar.getInstance();
279
                        cal.setTime(_last_interaction_date);
280
                        cal.add(Calendar.SECOND, 1);
281
                        _last_interaction_date = cal.getTime();
282

    
283
                        String last_interaction_date = (format.format(_last_interaction_date));
284

    
285
                        long diff = _dateTo.getTime() - notification.getDate().getTime();
286
                        diff = diff / 1000;
287

    
288
                        if (diff >= (notification.getFrequency() * 3600)) {
289
                            if (fetchClaimHandler.fetchNumberOfClaimsByDateAndOpenaireId(last_interaction_date, dateTo, notification.getOpenaireId(), null, null, "", null, true, types, false) > 0) {
290
                                List<String> managersByNotification = new ArrayList<>();
291
                                managersByNotification.add(notification.getUserMail());
292

    
293
                                project = fetchProjectHandler.fetchProjectById(notification.getOpenaireId());
294

    
295
                                logger.debug("Sending email for project claims between " + last_interaction_date + " and " + dateTo + " to " + notification.getUserMail());
296

    
297
                                send(project.getOpenaireId(), project.getName(), "project", managersByNotification);
298
                            }
299

    
300
                            notificationHandler.updateNotificationLastInteractionDate(notification.getOpenaireId(), notification.getUserMail(), _dateTo);
301
                        }
302
                    } else {
303
                        logger.debug("managers do not contain "+notification.getUserMail());
304
                    }
305
                }
306
            } else {
307
                logger.debug("true notifications: null");
308
            }
309
        } catch (Exception e) {
310
            e.printStackTrace();
311
        } catch (SQLStoreException e) {
312
            e.printStackTrace();
313
        }
314
    }
315

    
316
    public void notificationEmails_For_CommunityClaims(String dateTo, SimpleDateFormat format) {
317
        Context context = null;
318
        List<String> types = new ArrayList<String>();
319

    
320
        types.add(ClaimUtils.CONTEXT);
321

    
322
        List<String> enabledCommunitiesList = null;
323
        if (enabledCommunities != null && !enabledCommunities.isEmpty()) {
324
            enabledCommunitiesList = Arrays.asList(enabledCommunities.split("\\s*,\\s*"));
325
        }
326

    
327
        logger.debug("Sending email for community claims from notification table");
328

    
329
        try {
330
            List<Notification> trueNotifications = fetchNotificationHandler.fetchTrueNotifications();
331

    
332
            if(trueNotifications != null) {
333
                for(Notification notification : trueNotifications) {
334
                    if (enabledCommunitiesList != null && enabledCommunitiesList.contains(notification.getOpenaireId())) {
335

    
336
                        CommunityUtils communityInfo = CommunityUtils.getCommunityInfo(notification.getOpenaireId());
337
                        List<String> managers = null;
338
                        if (communityInfo != null) {
339
                            managers = communityInfo.getManagers();
340
                        }
341

    
342
                        if (managers != null && managers.contains(notification.getUserMail())) {
343
                            Date _dateTo = format.parse(dateTo);
344

    
345
                            Date _last_interaction_date = notification.getDate();
346
                            Calendar cal = Calendar.getInstance();
347
                            cal.setTime(_last_interaction_date);
348
                            cal.add(Calendar.SECOND, 1);
349
                            _last_interaction_date = cal.getTime();
350

    
351
                            String last_interaction_date = (format.format(_last_interaction_date));
352
                            long diff = _dateTo.getTime() - notification.getDate().getTime();
353
                            diff = diff / 1000;
354

    
355
                            if (diff >= (notification.getFrequency() * 3600)) {
356
                                if (fetchClaimHandler.fetchNumberOfClaimsByDateAndOpenaireId(last_interaction_date, dateTo, notification.getOpenaireId(), null, null, "", null, true, types, false) > 0) {
357
                                    List<String> managersByNotification = new ArrayList<>();
358
                                    managersByNotification.add(notification.getUserMail());
359

    
360
                                    // We need that to get name of community
361
                                    context = fetchContextHandler.fetchFirstContextByCommunityId(notification.getOpenaireId());
362

    
363
                                    logger.debug("Sending email for community claims between " + last_interaction_date + " and " + dateTo + " to " + notification.getUserMail());
364

    
365
                                    send(context.getOpenaireId().split("::")[0], context.getTitle().split(">")[0], "community", managersByNotification);
366
                                }
367

    
368
                                notificationHandler.updateNotificationLastInteractionDate(notification.getOpenaireId(), notification.getUserMail(), _dateTo);
369
                            }
370
                        }
371
                    } else {
372
                        logger.debug("Community "+notification.getOpenaireId()+" is not enabled");
373
                    }
374
                }
375
            }
376
        } catch (Exception e) {
377
            e.printStackTrace();
378
        } catch (SQLStoreException e) {
379
            e.printStackTrace();
380
        }
381
    }
382

    
383
    public void send(String openaire_id, String openaire_name, String type, List<String> managers) {
384
        logger.debug("Sending email");
385
        String openaireClaimsPageUrl = "";
386
        String manageUserNotificationsPage = "";
387
        String messageContent = "";
388
        String subject = "";
389

    
390
        if(type.equals("project")) {
391
            openaireClaimsPageUrl = openaireProjectClaimsPage + openaire_id;
392

    
393
            subject = "[OpenAIRE] Links notification";
394
            messageContent = "There are new Claims for: '" + openaire_name +"' project for which you seem to be a contact person." +
395
                    "<br>Click <a href=\""+openaireClaimsPageUrl+"\">here</a> to curate these Claims.";
396
        } else if(type.equals("community")) {
397
            openaireClaimsPageUrl = openaireCommunityClaimsPage + openaire_id;
398
            manageUserNotificationsPage = manageCommunityUserNotificationsPage + openaire_id;
399

    
400
            subject = "[OpenAIRE-Connect] "+openaire_name+": Links notification";
401
            messageContent =
402
                    " <div style=\"font-size:14px;\">" +
403
                    "    <p>" +
404
                    "       There are new links for '"+openaire_name+"' community. Click  <a href=\""+openaireClaimsPageUrl+"\">here</a> to view the links.\n" +
405
                    "    </p>" +
406
                    "    <p>OpenAIRE team<br/>" +
407
                    "       <a href=\"https://www.openaire.eu\">www.openaire.eu</a>" +
408
                    "    </p>" +
409
                    "    <p style=\"font-size:11px;\">You are receiving this e-mail as manager of the community  <a href=\"https://beta."+openaire_id+".openaire.eu\">"+openaire_name+"</a>." +
410
                    "    If you are not responsible for this community, please <a href=\"mailto:"+contactMail+"\">contact us</a>." +
411
                    "    <br/>" +
412
                    "    Click  <a href=\""+manageUserNotificationsPage+"\">here</a> to manage your notification settings. </p>" +
413
                    "    </div>"
414
                    ;
415
        }
416

    
417
        //logger.debug(messageContent);
418

    
419
        // Get system properties
420
        Properties properties = System.getProperties();
421
        properties.setProperty("mail.smtp.host", host);
422
        properties.put("mail.smtp.port", port);
423
        properties.put("mail.smtp.auth", auth); //enable authentication
424
        properties.put("mail.smtp.starttls.enable", "true");
425

    
426
        Session session = Session.getInstance(properties,
427
            new javax.mail.Authenticator() {
428
                protected PasswordAuthentication getPasswordAuthentication() {
429
                    return new PasswordAuthentication(username, password);
430
                }
431
            });
432

    
433
        try {
434
            // Create a default MimeMessage object.
435
            MimeMessage message = new MimeMessage(session);
436

    
437
            // Set From: header field of the header.
438
            message.setFrom(new InternetAddress(from));
439

    
440
            // Set To: header field of the header.
441
            for(String to : managers) {
442
                logger.debug(to);
443
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
444
            }
445
            message.addRecipient(Message.RecipientType.BCC, new InternetAddress("openaire.test@gmail.com"));
446

    
447
            // Set Subject: header field
448
            message.setSubject(subject);
449

    
450
            // For simple text setText() can be used instead of setContent()
451

    
452
            // Send the actual HTML message, as big as you like
453
            message.setContent(messageContent, "text/html");
454

    
455
            // Send message
456
            Transport.send(message);
457
            logger.debug("Sent message successfully....\n");
458

    
459
        } catch (AddressException ae) {
460
            logger.error("Email could not be send.", ae);
461

    
462
        } catch (MessagingException me) {
463
            logger.error("Email could not be send.", me);
464
        }
465
    }
466

    
467
    public void setFetchClaimHandler(FetchClaimHandler fetchClaimHandler) {
468
        this.fetchClaimHandler = fetchClaimHandler;
469
    }
470

    
471
    public void setFetchProjectHandler(FetchProjectHandler fetchProjectHandler) {
472
        this.fetchProjectHandler = fetchProjectHandler;
473
    }
474

    
475
    public void setFetchNotificationHandler(FetchNotificationHandler fetchNotificationHandler) {
476
        this.fetchNotificationHandler = fetchNotificationHandler;
477
    }
478

    
479
    public void setNotificationHandler(NotificationHandler notificationHandler) {
480
        this.notificationHandler = notificationHandler;
481
    }
482

    
483
    public void setFetchContextHandler(FetchContextHandler fetchContextHandler) {
484
        this.fetchContextHandler = fetchContextHandler;
485
    }
486

    
487
    public void setOpenaireProjectClaimsPage(String openaireProjectClaimsPage) {
488
        EmailSender.openaireProjectClaimsPage = openaireProjectClaimsPage;
489
    }
490

    
491
    public void setOpenaireCommunityClaimsPage(String openaireCommunityClaimsPage) {
492
        EmailSender.openaireCommunityClaimsPage = openaireCommunityClaimsPage;
493
    }
494

    
495
    public void setManageCommunityUserNotificationsPage(String manageCommunityUserNotificationsPage) {
496
        EmailSender.manageCommunityUserNotificationsPage = manageCommunityUserNotificationsPage;
497
    }
498

    
499
    public void setUsername(String username) {
500
        EmailSender.username = username;
501
    }
502

    
503
    public void setPassword(String password) {
504
        EmailSender.password = password;
505
    }
506

    
507
    public void setHost(String host) {
508
        EmailSender.host = host;
509
    }
510

    
511
    public void setPort(String port) {
512
        EmailSender.port = port;
513
    }
514

    
515
    public void setFrom(String from) {
516
        EmailSender.from = from;
517
    }
518

    
519
    public void setAuth(String auth) {
520
        EmailSender.auth = auth;
521
    }
522

    
523
    public void setContactMail(String contactMail) { EmailSender.contactMail = contactMail; }
524

    
525
    public void setSpecialRecipients(String specialRecipients) {
526
        EmailSender.specialRecipients = specialRecipients;
527
    }
528

    
529
    public void setDefaultFrequencyInHours(String defaultFrequencyInHours) {
530
        this.defaultFrequencyInHours = defaultFrequencyInHours;
531
    }
532

    
533
    public void setEnabledCommunities(String enabledCommunities) {
534
        EmailSender.enabledCommunities = enabledCommunities;
535
    }
536

    
537
    public static boolean isNotifyCommunityManagers() {
538
        return notifyCommunityManagers;
539
    }
540

    
541
    public static void setNotifyCommunityManagers(boolean notifyCommunityManagers) {
542
        EmailSender.notifyCommunityManagers = notifyCommunityManagers;
543
    }
544

    
545
    public static boolean isNotifyProjectManagers() {
546
        return notifyProjectManagers;
547
    }
548

    
549
    public static void setNotifyProjectManagers(boolean notifyProjectManagers) {
550
        EmailSender.notifyProjectManagers = notifyProjectManagers;
551
    }
552
}
(2-2/2)