Project

General

Profile

1
package eu.dnetlib.data.emailSender;
2

    
3
import eu.dnetlib.data.claims.migration.entity.Claim;
4
import eu.dnetlib.data.claims.migration.entity.Context;
5
import eu.dnetlib.data.claims.migration.entity.Notification;
6
import eu.dnetlib.data.claims.migration.entity.Project;
7
import eu.dnetlib.data.claims.migration.handler.*;
8
import eu.dnetlib.data.claimsDemo.ClaimUtils;
9
import eu.dnetlib.data.claimsDemo.CommunityUtils;
10
import eu.dnetlib.data.claimsDemo.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 contactMail;
48
    private static String specialRecipients;
49

    
50
    @Override
51
    public void run() {
52
        logger.info("EmailSender thread is running. " + host);
53
        logger.info("Special Recipients  " + specialRecipients);
54

    
55
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
56
        Date date = new Date();
57
        String dateTo = (format.format(date));
58

    
59
        defaultEmails_For_ProjectClaims(dateTo, format);    // daily for managers not in notification table
60
        defaultEmails_For_CommunityClaims(dateTo, format);  // daily for managers not in notification table
61

    
62
        notificationEmails_For_ProjectClaims(dateTo, format);
63
        notificationEmails_For_CommunityClaims(dateTo, format);
64
    }
65

    
66
    public void defaultEmails_For_ProjectClaims(String dateTo, SimpleDateFormat format) {
67
        Map<String, List<String>> managersOfProject = new HashMap<String, List<String>>();
68
        Project project;
69
        List<Claim> claims = null;
70
        List<String> types = new ArrayList<String>();
71

    
72
        types.add(ClaimUtils.PROJECT);
73

    
74
        Calendar calendar = Calendar.getInstance();
75
        calendar.add(Calendar.HOUR_OF_DAY, -(Integer.parseInt(defaultFrequencyInHours)-1));
76
        calendar.add(Calendar.MINUTE, -59);
77
        calendar.add(Calendar.SECOND, -59);
78
        Date date = calendar.getTime();
79
        String dateFrom=(format.format(date));
80

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

    
83
        try {
84
            // Get all claims between dateFrom and dateTo which satisfy source_type == "project" or target_type == "project"
85
            claims = fetchClaimHandler.fetchClaimsByDate(dateFrom, dateTo, null, null, "", "source", true, types, false);
86
        } catch (SQLStoreException|Exception e) {
87
            logger.error("Could not fetch claims by date from "+dateFrom+" to "+dateTo, e);
88
        }
89

    
90
        for (Claim claim: claims) {
91
            if (claim.getSourceType().equals("project")) {
92
                project = (Project)claim.getSource();
93
            } else {
94
                project = (Project)claim.getTarget();
95
            }
96

    
97
            if (!managersOfProject.containsKey(project.getOpenaireId())) {
98

    
99
                // specialRecipients are used currently for testing purposes
100
                List<String> tmpManagers = null;
101
                if (specialRecipients != null && !specialRecipients.isEmpty()) {
102
                    tmpManagers = new ArrayList<>(Arrays.asList(specialRecipients.split("\\s*,\\s*")));
103
                    logger.debug("Special recipients: " + specialRecipients);
104

    
105
                    if(tmpManagers != null) {
106
                        Iterator itr = tmpManagers.iterator();
107
                        while (itr.hasNext()) {
108
                            String manager = (String) itr.next();
109
                            Notification notification = null;
110
                            try {
111
                                notification = fetchNotificationHandler.fetchNotification(project.getOpenaireId(), manager);
112
                            } catch (Exception e) {
113
                                e.printStackTrace();
114
                            } catch (SQLStoreException e) {
115
                                e.printStackTrace();
116
                            }
117
                            if (notification != null) {
118
                                itr.remove();
119
                            }
120
                        }
121
                    }
122

    
123
                    managersOfProject.put(project.getOpenaireId(), tmpManagers);
124
                }
125

    
126
                // Send emails to actual project managers instead of special recipients
127
                List<String> managers = null;
128
                try {
129
                    managers = fetchProjectHandler.fetchContactEmailsByProjectId(project.getOpenaireId());
130
                    logger.debug("All actual Managers of project " + project.getOpenaireId() + ": "+managers);
131

    
132
                    if(managers != null) {
133
                        Iterator itr = managers.iterator();
134
                        while (itr.hasNext()) {
135
                            String manager = (String) itr.next();
136
                            Notification notification = fetchNotificationHandler.fetchNotification(project.getOpenaireId(), manager);
137
                            //if (notification != null && (!notification.isNotify() || notification.getFrequency() != 24)) {
138
                            if (notification != null) {
139
                                itr.remove();
140
                            }
141
                        }
142
                    }
143
                } catch (Exception e) {
144
                    e.printStackTrace();
145
                } catch (SQLStoreException e) {
146
                    e.printStackTrace();
147
                }
148

    
149
                logger.debug("Managers of project (not in notification table) " + project.getOpenaireId() + ": "+managers);
150
                /*
151
                managersOfProject.put(project.getOpenaireId(), managers);
152
                */
153

    
154
                if (managersOfProject.get(project.getOpenaireId()) != null &&
155
                        !managersOfProject.get(project.getOpenaireId()).isEmpty()) {
156
                    send(project.getOpenaireId(), project.getName(), "project", managersOfProject.get(project.getOpenaireId()));
157
                }
158
            }
159
        }
160
    }
161

    
162
    public void defaultEmails_For_CommunityClaims(String dateTo, SimpleDateFormat format) {
163
        Map<String, List<String>> managersOfCommunity = new HashMap<String, List<String>>();
164
        Context context;
165
        List<Claim> claims = null;
166
        List<String> types = new ArrayList<String>();
167

    
168
        types.add(ClaimUtils.CONTEXT);
169

    
170
        Calendar calendar = Calendar.getInstance();
171
        calendar.add(Calendar.HOUR_OF_DAY, -(Integer.parseInt(defaultFrequencyInHours)-1));
172
        calendar.add(Calendar.MINUTE, -59);
173
        calendar.add(Calendar.SECOND, -59);
174
        Date date = calendar.getTime();
175
        String dateFrom=(format.format(date));
176

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

    
179
        try {
180
            // Get all claims between dateFrom and dateTo which satisfy source_type == "context" or target_type == "context"
181
            claims = fetchClaimHandler.fetchClaimsByDate(dateFrom, dateTo, null, null, "", "source", true, types, false);
182
        } catch (SQLStoreException|Exception e) {
183
            logger.error("Could not fetch claims by date from "+dateFrom+" to "+dateTo, e);
184
        }
185

    
186
        for (Claim claim: claims) {
187
            if (claim.getSourceType().equals("context")) {
188
                context = (Context)claim.getSource();
189
            } else {
190
                context = (Context)claim.getTarget();
191
            }
192

    
193
            String openaireId = context.getOpenaireId().split("::")[0];
194
            if (!managersOfCommunity.containsKey(openaireId)) {
195

    
196
                /*
197
                // specialRecipients are used currently for testing purposes
198
                List<String> tmpManagers = null;
199
                if (specialRecipients != null && !specialRecipients.isEmpty()) {
200
                    tmpManagers = Arrays.asList(specialRecipients.split("\\s*,\\s*"));
201
                    logger.debug("Special recipients: " + specialRecipients);
202
                    managersOfCommunity.put(openaireId, tmpManagers);
203
                }
204
                */
205

    
206

    
207
                // Send emails to actual project managers instead of special recipients
208
                List<String> managers = null;
209
                try {
210
                    CommunityUtils communityInfo = CommunityUtils.getCommunityInfo(openaireId);
211
                    managers = communityInfo.getManagers();
212
                    if(managers != null) {
213
                        Iterator itr = managers.iterator();
214
                        while (itr.hasNext()) {
215
                            String manager = (String) itr.next();
216
                            Notification notification = fetchNotificationHandler.fetchNotification(openaireId, manager);
217
                            if (notification != null) {
218
                                itr.remove();
219
                            } else {
220
                                logger.debug("Sending email to community manager: "+ manager);
221
                            }
222
                        }
223
                    }
224
                    else {
225
                        logger.debug("Community Managers: null");
226
                    }
227
                } catch (Exception e) {
228
                    e.printStackTrace();
229
                } catch (SQLStoreException e) {
230
                    e.printStackTrace();
231
                }
232

    
233
                logger.debug("Managers of community " + openaireId + ": "+managers);
234
                managersOfCommunity.put(openaireId, managers);
235

    
236

    
237
                if (managersOfCommunity.get(openaireId) != null &&
238
                        !managersOfCommunity.get(openaireId).isEmpty()) {
239
                    send(openaireId, context.getTitle().split(">")[0], "community", managersOfCommunity.get(openaireId));
240
                }
241
            }
242
        }
243
    }
244

    
245
    public void notificationEmails_For_ProjectClaims(String dateTo, SimpleDateFormat format) {
246
        Project project = null;
247
        List<String> types = new ArrayList<String>();
248

    
249
        types.add(ClaimUtils.PROJECT);
250

    
251
        logger.debug("Sending email for project claims from notification table");
252

    
253
        try {
254
            List<Notification> trueNotifications = fetchNotificationHandler.fetchTrueNotifications();
255
            logger.debug(trueNotifications);
256
            if(trueNotifications != null) {
257
                for(Notification notification : trueNotifications) {
258
                    List<String> managers = fetchProjectHandler.fetchContactEmailsByProjectId(notification.getOpenaireId());
259
                    if(managers != null && managers.contains(notification.getUserMail())) {
260

    
261
                        Date _dateTo = format.parse(dateTo);
262

    
263
                        Date _last_interaction_date = notification.getDate();
264
                        Calendar cal = Calendar.getInstance();
265
                        cal.setTime(_last_interaction_date);
266
                        cal.add(Calendar.SECOND, 1);
267
                        _last_interaction_date = cal.getTime();
268

    
269
                        String last_interaction_date = (format.format(_last_interaction_date));
270

    
271
                        long diff = _dateTo.getTime() - notification.getDate().getTime();
272
                        diff = diff / 1000;
273

    
274
                        if (diff >= (notification.getFrequency() * 3600)) {
275
                            if (fetchClaimHandler.fetchNumberOfClaimsByDateAndOpenaireId(last_interaction_date, dateTo, notification.getOpenaireId(), null, null, "", null, true, types, false) > 0) {
276
                                List<String> managersByNotification = new ArrayList<>();
277
                                managersByNotification.add(notification.getUserMail());
278

    
279
                                project = fetchProjectHandler.fetchProjectById(notification.getOpenaireId());
280

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

    
283
                                send(project.getOpenaireId(), project.getName(), "project", managersByNotification);
284
                            }
285

    
286
                            notificationHandler.updateNotificationLastInteractionDate(notification.getOpenaireId(), notification.getUserMail(), _dateTo);
287
                        }
288
                    } else {
289
                        logger.debug("managers do not contain "+notification.getUserMail());
290
                    }
291
                }
292
            } else {
293
                logger.debug("true notifications: null");
294
            }
295
        } catch (Exception e) {
296
            e.printStackTrace();
297
        } catch (SQLStoreException e) {
298
            e.printStackTrace();
299
        }
300
    }
301

    
302
    public void notificationEmails_For_CommunityClaims(String dateTo, SimpleDateFormat format) {
303
        Context context = null;
304
        List<String> types = new ArrayList<String>();
305

    
306
        types.add(ClaimUtils.CONTEXT);
307

    
308
        logger.debug("Sending email for community claims from notification table");
309

    
310
        try {
311
            List<Notification> trueNotifications = fetchNotificationHandler.fetchTrueNotifications();
312

    
313
            if(trueNotifications != null) {
314
                for(Notification notification : trueNotifications) {
315
                    CommunityUtils communityInfo = CommunityUtils.getCommunityInfo(notification.getOpenaireId());
316
                    List<String> managers = null;
317
                    if(communityInfo != null) {
318
                        managers = communityInfo.getManagers();
319
                    }
320

    
321
                    if(managers != null && managers.contains(notification.getUserMail())) {
322
                        Date _dateTo = format.parse(dateTo);
323

    
324
                        Date _last_interaction_date = notification.getDate();
325
                        Calendar cal = Calendar.getInstance();
326
                        cal.setTime(_last_interaction_date);
327
                        cal.add(Calendar.SECOND, 1);
328
                        _last_interaction_date = cal.getTime();
329

    
330
                        String last_interaction_date = (format.format(_last_interaction_date));
331
                        long diff = _dateTo.getTime() - notification.getDate().getTime();
332
                        diff = diff / 1000;
333

    
334
                        if (diff >= (notification.getFrequency() * 3600)) {
335
                            if (fetchClaimHandler.fetchNumberOfClaimsByDateAndOpenaireId(last_interaction_date, dateTo, notification.getOpenaireId(), null, null, "", null, true, types, false) > 0) {
336
                                List<String> managersByNotification = new ArrayList<>();
337
                                managersByNotification.add(notification.getUserMail());
338

    
339
                                // We need that to get name of community
340
                                context = fetchContextHandler.fetchFirstContextByCommunityId(notification.getOpenaireId());
341

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

    
344
                                send(context.getOpenaireId().split("::")[0], context.getTitle().split(">")[0], "community", managersByNotification);
345
                            }
346

    
347
                            notificationHandler.updateNotificationLastInteractionDate(notification.getOpenaireId(), notification.getUserMail(), _dateTo);
348
                        }
349
                    }
350
                }
351
            }
352
        } catch (Exception e) {
353
            e.printStackTrace();
354
        } catch (SQLStoreException e) {
355
            e.printStackTrace();
356
        }
357
    }
358

    
359
    public void send(String openaire_id, String openaire_name, String type, List<String> managers) {
360
        logger.debug("Sending email");
361
        String openaireClaimsPageUrl = "";
362
        String manageUserNotificationsPage = "";
363
        String messageContent = "";
364
        String subject = "";
365

    
366
        if(type.equals("project")) {
367
            openaireClaimsPageUrl = openaireProjectClaimsPage + openaire_id;
368

    
369
            subject = "[OpenAIRE] Links notification";
370
            messageContent = "There are new Claims for: '" + openaire_name +"' project for which you seem to be a contact person." +
371
                    "<br>Click <a href=\""+openaireClaimsPageUrl+"\">here</a> to curate these Claims.";
372
        } else if(type.equals("community")) {
373
            openaireClaimsPageUrl = openaireCommunityClaimsPage + openaire_id;
374
            manageUserNotificationsPage = manageCommunityUserNotificationsPage + openaire_id;
375

    
376
            subject = "[OpenAIRE-Connect] "+openaire_name+": Links notification";
377
            messageContent =
378
                    " <div style=\"font-size:14px;\">" +
379
                    "    <p>" +
380
                    "       There are new links for '"+openaire_name+"' community. Click  <a href=\""+openaireClaimsPageUrl+"\">here</a> to view the links.\n" +
381
                    "    </p>" +
382
                    "    <p>OpenAIRE team<br/>" +
383
                    "       <a href=\"https://www.openaire.eu\">www.openaire.eu</a>" +
384
                    "    </p>" +
385
                    "    <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>." +
386
                    "    If you are not responsible for this community, please <a href=\"mailto:"+contactMail+"\">contact us</a>." +
387
                    "    <br/>" +
388
                    "    Click  <a href=\""+manageUserNotificationsPage+"\">here</a> to manage your notification settings. </p>" +
389
                    "    </div>"
390
                    ;
391
        }
392

    
393
        //logger.debug(messageContent);
394

    
395
        // Get system properties
396
        Properties properties = System.getProperties();
397
        properties.setProperty("mail.smtp.host", host);
398
        properties.put("mail.smtp.port", port);
399
        properties.put("mail.smtp.auth", "true"); //enable authentication
400
        properties.put("mail.smtp.starttls.enable", "true");
401

    
402
        Session session = Session.getInstance(properties,
403
            new javax.mail.Authenticator() {
404
                protected PasswordAuthentication getPasswordAuthentication() {
405
                    return new PasswordAuthentication(username, password);
406
                }
407
            });
408

    
409
        try {
410
            // Create a default MimeMessage object.
411
            MimeMessage message = new MimeMessage(session);
412

    
413
            // Set From: header field of the header.
414
            message.setFrom(new InternetAddress(from));
415

    
416
            // Set To: header field of the header.
417
            for(String to : managers) {
418
                logger.debug(to);
419
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
420
            }
421
            message.addRecipient(Message.RecipientType.BCC, new InternetAddress("openaire.test@gmail.com"));
422

    
423
            // Set Subject: header field
424
            message.setSubject(subject);
425

    
426
            // For simple text setText() can be used instead of setContent()
427

    
428
            // Send the actual HTML message, as big as you like
429
            message.setContent(messageContent, "text/html");
430

    
431
            // Send message
432
            Transport.send(message);
433
            logger.debug("Sent message successfully....\n");
434

    
435
        } catch (AddressException ae) {
436
            logger.error("Email could not be send.", ae);
437

    
438
        } catch (MessagingException me) {
439
            logger.error("Email could not be send.", me);
440
        }
441
    }
442

    
443
    public void setFetchClaimHandler(FetchClaimHandler fetchClaimHandler) {
444
        this.fetchClaimHandler = fetchClaimHandler;
445
    }
446

    
447
    public void setFetchProjectHandler(FetchProjectHandler fetchProjectHandler) {
448
        this.fetchProjectHandler = fetchProjectHandler;
449
    }
450

    
451
    public void setFetchNotificationHandler(FetchNotificationHandler fetchNotificationHandler) {
452
        this.fetchNotificationHandler = fetchNotificationHandler;
453
    }
454

    
455
    public void setNotificationHandler(NotificationHandler notificationHandler) {
456
        this.notificationHandler = notificationHandler;
457
    }
458

    
459
    public void setFetchContextHandler(FetchContextHandler fetchContextHandler) {
460
        this.fetchContextHandler = fetchContextHandler;
461
    }
462

    
463
    public static void setOpenaireProjectClaimsPage(String openaireProjectClaimsPage) {
464
        EmailSender.openaireProjectClaimsPage = openaireProjectClaimsPage;
465
    }
466

    
467
    public static void setOpenaireCommunityClaimsPage(String openaireCommunityClaimsPage) {
468
        EmailSender.openaireCommunityClaimsPage = openaireCommunityClaimsPage;
469
    }
470

    
471
    public static void setManageCommunityUserNotificationsPage(String manageCommunityUserNotificationsPage) {
472
        EmailSender.manageCommunityUserNotificationsPage = manageCommunityUserNotificationsPage;
473
    }
474

    
475
    public static void setUsername(String username) {
476
        EmailSender.username = username;
477
    }
478

    
479
    public static void setPassword(String password) {
480
        EmailSender.password = password;
481
    }
482

    
483
    public static void setHost(String host) {
484
        EmailSender.host = host;
485
    }
486

    
487
    public static void setPort(String port) {
488
        EmailSender.port = port;
489
    }
490

    
491
    public static void setFrom(String from) {
492
        EmailSender.from = from;
493
    }
494

    
495
    public static void setContactMail(String contactMail) { EmailSender.contactMail = contactMail; }
496

    
497
    public static void setSpecialRecipients(String specialRecipients) {
498
        EmailSender.specialRecipients = specialRecipients;
499
    }
500

    
501
    public void setDefaultFrequencyInHours(String defaultFrequencyInHours) {
502
        this.defaultFrequencyInHours = defaultFrequencyInHours;
503
    }
504
}
(2-2/2)