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
    @Autowired
40
    private CommunityUtils communityUtils;
41

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

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

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

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

    
82
        types.add(ClaimUtils.PROJECT);
83

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

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

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

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

    
107
            if (!managersOfProject.containsKey(project.getOpenaireId())) {
108

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

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

    
133
                    managersOfProject.put(project.getOpenaireId(), tmpManagers);
134
                }
135

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

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

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

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

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

    
178
        types.add(ClaimUtils.CONTEXT);
179

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

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

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

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

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

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

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

    
221

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

    
248
                logger.debug("Managers of community " + openaireId + ": "+managers);
249
                managersOfCommunity.put(openaireId, managers);
250

    
251

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

    
262
    public void notificationEmails_For_ProjectClaims(String dateTo, SimpleDateFormat format) {
263
        Project project = null;
264
        List<String> types = new ArrayList<String>();
265

    
266
        types.add(ClaimUtils.PROJECT);
267

    
268
        logger.debug("Sending email for project claims from notification table");
269

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

    
278
                        Date _dateTo = format.parse(dateTo);
279

    
280
                        Date _last_interaction_date = notification.getDate();
281
                        Calendar cal = Calendar.getInstance();
282
                        cal.setTime(_last_interaction_date);
283
                        cal.add(Calendar.SECOND, 1);
284
                        _last_interaction_date = cal.getTime();
285

    
286
                        String last_interaction_date = (format.format(_last_interaction_date));
287

    
288
                        long diff = _dateTo.getTime() - notification.getDate().getTime();
289
                        diff = diff / 1000;
290

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

    
296
                                project = fetchProjectHandler.fetchProjectById(notification.getOpenaireId());
297

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

    
300
                                send(project.getOpenaireId(), project.getName(), "project", managersByNotification);
301
                            }
302

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

    
319
    public void notificationEmails_For_CommunityClaims(String dateTo, SimpleDateFormat format) {
320
        Context context = null;
321
        List<String> types = new ArrayList<String>();
322

    
323
        types.add(ClaimUtils.CONTEXT);
324

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

    
330
        logger.debug("Sending email for community claims from notification table");
331

    
332
        try {
333
            List<Notification> trueNotifications = fetchNotificationHandler.fetchTrueNotifications();
334

    
335
            if(trueNotifications != null) {
336
                for(Notification notification : trueNotifications) {
337
                    if (enabledCommunitiesList != null && enabledCommunitiesList.contains(notification.getOpenaireId())) {
338

    
339
                        CommunityUtils communityInfo = this.communityUtils.getCommunityInfo(notification.getOpenaireId());
340
                        List<String> managers = null;
341
                        if (communityInfo != null) {
342
                            managers = communityInfo.getManagers();
343
                        }
344

    
345
                        if (managers != null && managers.contains(notification.getUserMail())) {
346
                            Date _dateTo = format.parse(dateTo);
347

    
348
                            Date _last_interaction_date = notification.getDate();
349
                            Calendar cal = Calendar.getInstance();
350
                            cal.setTime(_last_interaction_date);
351
                            cal.add(Calendar.SECOND, 1);
352
                            _last_interaction_date = cal.getTime();
353

    
354
                            String last_interaction_date = (format.format(_last_interaction_date));
355
                            long diff = _dateTo.getTime() - notification.getDate().getTime();
356
                            diff = diff / 1000;
357

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

    
363
                                    // We need that to get name of community
364
                                    context = fetchContextHandler.fetchFirstContextByCommunityId(notification.getOpenaireId());
365

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

    
368
                                    send(context.getOpenaireId().split("::")[0], context.getTitle().split(">")[0], "community", managersByNotification);
369
                                }
370

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

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

    
393
        if(type.equals("project")) {
394
            openaireClaimsPageUrl = openaireProjectClaimsPage + openaire_id;
395

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

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

    
420
        //logger.debug(messageContent);
421

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

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

    
436
        try {
437
            // Create a default MimeMessage object.
438
            MimeMessage message = new MimeMessage(session);
439

    
440
            // Set From: header field of the header.
441
            message.setFrom(new InternetAddress(from));
442

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

    
450
            // Set Subject: header field
451
            message.setSubject(subject);
452

    
453
            // For simple text setText() can be used instead of setContent()
454

    
455
            // Send the actual HTML message, as big as you like
456
            message.setContent(messageContent, "text/html");
457

    
458
            // Send message
459
            Transport.send(message);
460
            logger.debug("Sent message successfully....\n");
461

    
462
        } catch (AddressException ae) {
463
            logger.error("Email could not be send.", ae);
464

    
465
        } catch (MessagingException me) {
466
            logger.error("Email could not be send.", me);
467
        }
468
    }
469

    
470
    public void setFetchClaimHandler(FetchClaimHandler fetchClaimHandler) {
471
        this.fetchClaimHandler = fetchClaimHandler;
472
    }
473

    
474
    public void setFetchProjectHandler(FetchProjectHandler fetchProjectHandler) {
475
        this.fetchProjectHandler = fetchProjectHandler;
476
    }
477

    
478
    public void setFetchNotificationHandler(FetchNotificationHandler fetchNotificationHandler) {
479
        this.fetchNotificationHandler = fetchNotificationHandler;
480
    }
481

    
482
    public void setNotificationHandler(NotificationHandler notificationHandler) {
483
        this.notificationHandler = notificationHandler;
484
    }
485

    
486
    public void setFetchContextHandler(FetchContextHandler fetchContextHandler) {
487
        this.fetchContextHandler = fetchContextHandler;
488
    }
489

    
490
    public void setOpenaireProjectClaimsPage(String openaireProjectClaimsPage) {
491
        EmailSender.openaireProjectClaimsPage = openaireProjectClaimsPage;
492
    }
493

    
494
    public void setOpenaireCommunityClaimsPage(String openaireCommunityClaimsPage) {
495
        EmailSender.openaireCommunityClaimsPage = openaireCommunityClaimsPage;
496
    }
497

    
498
    public void setManageCommunityUserNotificationsPage(String manageCommunityUserNotificationsPage) {
499
        EmailSender.manageCommunityUserNotificationsPage = manageCommunityUserNotificationsPage;
500
    }
501

    
502
    public void setUsername(String username) {
503
        EmailSender.username = username;
504
    }
505

    
506
    public void setPassword(String password) {
507
        EmailSender.password = password;
508
    }
509

    
510
    public void setHost(String host) {
511
        EmailSender.host = host;
512
    }
513

    
514
    public void setPort(String port) {
515
        EmailSender.port = port;
516
    }
517

    
518
    public void setFrom(String from) {
519
        EmailSender.from = from;
520
    }
521

    
522
    public void setAuth(String auth) {
523
        EmailSender.auth = auth;
524
    }
525

    
526
    public void setContactMail(String contactMail) { EmailSender.contactMail = contactMail; }
527

    
528
    public void setSpecialRecipients(String specialRecipients) {
529
        EmailSender.specialRecipients = specialRecipients;
530
    }
531

    
532
    public void setDefaultFrequencyInHours(String defaultFrequencyInHours) {
533
        this.defaultFrequencyInHours = defaultFrequencyInHours;
534
    }
535

    
536
    public void setEnabledCommunities(String enabledCommunities) {
537
        EmailSender.enabledCommunities = enabledCommunities;
538
    }
539

    
540
    public static boolean isNotifyCommunityManagers() {
541
        return notifyCommunityManagers;
542
    }
543

    
544
    public static void setNotifyCommunityManagers(boolean notifyCommunityManagers) {
545
        EmailSender.notifyCommunityManagers = notifyCommunityManagers;
546
    }
547

    
548
    public static boolean isNotifyProjectManagers() {
549
        return notifyProjectManagers;
550
    }
551

    
552
    public static void setNotifyProjectManagers(boolean notifyProjectManagers) {
553
        EmailSender.notifyProjectManagers = notifyProjectManagers;
554
    }
555

    
556
    public void setCommunityUtils(CommunityUtils communityUtils) {
557
        this.communityUtils = communityUtils;
558
    }
559

    
560
    public CommunityUtils getCommunityUtils() {
561
        return communityUtils;
562
    }
563
}
(2-2/2)