Added support to job notifications. Added support for ticket #6342. Moved back to version 1.2.0 in pom.xml. Added a new notifyPost method that accepts set types for hashtags and mentioned vre groups to avoid duplicates.

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/application-support-layer/applicationSupportLayerSocial@141666 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
costantino.perciante 2017-01-20 13:45:53 +00:00
parent 1abe50026c
commit 54db46f5f4
7 changed files with 292 additions and 132 deletions

View File

@ -2,6 +2,8 @@
<Changeset component="org.gcube.applicationsupportlayer.aslsocial.1-2-0"
date="2017-01-16">
<Change>partially removed portal context dependency (where possible)</Change>
<Change>added support to job notifications</Change>
<Change>added support for ticket #6342</Change>
</Changeset>
<Changeset component="org.gcube.applicationsupportlayer.aslsocial.1-1-0"
date="2016-09-29">

View File

@ -10,7 +10,7 @@
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslsocial</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Social Portal ASL Extension</name>
<description>

View File

@ -3,6 +3,7 @@ package org.gcube.applicationsupportlayer.social;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.gcube.applicationsupportlayer.social.mailing.EmailPlugin;
@ -11,7 +12,6 @@ import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser;
import org.gcube.common.homelibrary.home.exceptions.InternalErrorException;
import org.gcube.common.homelibrary.home.workspace.WorkspaceItem;
import org.gcube.common.homelibrary.home.workspace.WorkspaceSharedFolder;
import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Notification;
import org.gcube.portal.databook.shared.NotificationChannelType;
import org.gcube.portal.databook.shared.NotificationType;
@ -127,6 +127,7 @@ public class ApplicationNotificationsManager extends SocialPortalBridge implemen
_log.info("senderEmail: " + senderEmail);
_log.info("portalName: " + senderEmail);
}
/**
* actually save the notification to the store
* @param notification2Save the notification instance to save
@ -153,7 +154,42 @@ public class ApplicationNotificationsManager extends SocialPortalBridge implemen
_log.error("Error While trying to save Notification");
}
if (channels.contains(NotificationChannelType.EMAIL)) {
EmailPlugin.getInstance(userManager, currScope).sendNotification(portalURL, siteLandingPagePath, notification2Save, currGroupName, portalName, senderEmail, hashtags);
EmailPlugin.getInstance(userManager, currScope).sendNotification(portalURL, siteLandingPagePath, notification2Save, currGroupName, portalName, senderEmail, null, hashtags);
}
if (channels.isEmpty()) {
_log.info("Notification was not needed as "+ notification2Save.getUserid() +" decided not to be notified for " + notification2Save.getType());
result = true;
}
return result;
}
/**
* actually save the notification to the store
* @param notification2Save the notification instance to save
* @return true if the notification was sent ok
*/
private boolean saveNotification(Notification notification2Save, Set<String> mentionedVREGroups, String ... hashtags) {
_log.trace("Trying to send notification to: " + notification2Save.getUserid() + " Type: " + notification2Save.getType());
if (notification2Save.getSenderid().compareTo(notification2Save.getUserid()) == 0) {
_log.trace("Sender and Receiver are the same " + notification2Save.getUserid() + " Notification Stopped");
return true; //I'm not sending notifications to the person who triggered it, pretend I sent it though
}
List<NotificationChannelType> channels = null;
try {
channels = getStoreInstance().getUserNotificationChannels(notification2Save.getUserid(), notification2Save.getType());
} catch (Exception e) {
e.printStackTrace();
}
boolean result = false;
if (channels.contains(NotificationChannelType.PORTAL)) {
result = getStoreInstance().saveNotification(notification2Save);
if (result)
_log.trace("Notification Saved Successfully! ");
else
_log.error("Error While trying to save Notification");
}
if (channels.contains(NotificationChannelType.EMAIL)) {
EmailPlugin.getInstance(userManager, currScope).sendNotification(portalURL, siteLandingPagePath, notification2Save, currGroupName, portalName, senderEmail, mentionedVREGroups, hashtags);
}
if (channels.isEmpty()) {
_log.info("Notification was not needed as "+ notification2Save.getUserid() +" decided not to be notified for " + notification2Save.getType());
@ -548,6 +584,31 @@ public class ApplicationNotificationsManager extends SocialPortalBridge implemen
currUser.getUserAvatarId());
return saveNotification(not, hashtags);
}
@Override
public boolean notifyPost(String userIdToNotify, String feedid,
String feedText, Set<String> mentionedVREGroups,
Set<String> hashtags) {
StringBuilder notificationText = new StringBuilder();
notificationText.append("posted on <b> ").append(currGroupName).append(":</b>") // has done something
.append("<br /><br /> ").append(feedText).append(" ")
.append("<br /><br />");
Notification not = new Notification(
UUID.randomUUID().toString(),
NotificationType.POST_ALERT,
userIdToNotify, //user no notify
feedid, //the post
new Date(),
getApplicationUrl()+"?oid="+feedid,
notificationText.toString(),
false,
currUser.getUsername(),
currUser.getFullname(),
currUser.getUserAvatarId());
return saveNotification(not, mentionedVREGroups, hashtags.toArray(new String[hashtags.size()]));
}
/**
* {@inheritDoc}
*/
@ -673,11 +734,81 @@ public class ApplicationNotificationsManager extends SocialPortalBridge implemen
* {@inheritDoc}
*/
@Override
public boolean notifyJobStatus(String userIdToNotify, ApplicationProfile executingJobApId, RunningJob job) {
//TODO: missing implementation
public boolean notifyJobStatus(String userIdToNotify, RunningJob job) {
//get job status
NotificationType statusToUse = null;
// notification final part
String notificationFinalPart = null;
switch(job.getStatus()){
case CANCELLED:
notificationFinalPart = " has been cancelled.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case CANCELLING:
notificationFinalPart = " is going to be cancelled.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case DELETED:
notificationFinalPart = " has been deleted.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case DELETING:
notificationFinalPart = " is going to be deleted.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case EXECUTING:
notificationFinalPart = " is executing.";
statusToUse = NotificationType.JOB_COMPLETED_OK;
break;
case FAILED:
notificationFinalPart = " is failed.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case NEW:
notificationFinalPart = " has been instanciated.";
statusToUse = NotificationType.JOB_COMPLETED_OK;
break;
case SUBMITTED:
notificationFinalPart = " has been submitted.";
statusToUse = NotificationType.JOB_COMPLETED_OK;
break;
case SUCCEEDED:
notificationFinalPart = " terminated correctly.";
statusToUse = NotificationType.JOB_COMPLETED_OK;
break;
case TIMED_OUT:
notificationFinalPart = " went in time out.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
case WAITING:
notificationFinalPart = " is waiting.";
statusToUse = NotificationType.JOB_COMPLETED_NOK;
break;
default:
_log.error("job status is missing, returning without sending notification");
return false;
}
Notification not = new Notification(
UUID.randomUUID().toString(),
statusToUse,
userIdToNotify, //user to notify
job.getServiceName(),
new Date(),
null,
"'s job with id " + job.getJobId() + ", named <b>" + job.getJobName() +"</b>" + notificationFinalPart +
(job.getMessage() != null && !job.getMessage().isEmpty() ?
" Additional information: " + job.getMessage() : ""),
false,
currUser.getUsername(),
job.getServiceName(),
currUser.getUserAvatarId());
return saveNotification(not);
}
/**
* {@inheritDoc}
*/

View File

@ -2,11 +2,11 @@ package org.gcube.applicationsupportlayer.social;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder;
import org.gcube.common.homelibrary.home.workspace.WorkspaceItem;
import org.gcube.common.homelibrary.home.workspace.WorkspaceSharedFolder;
import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.NotificationType;
import org.gcube.portal.databook.shared.RunningJob;
/**
@ -167,6 +167,7 @@ public interface NotificationsManager {
* @return true if the notification is correctly delivered, false otherwise
*/
boolean notifyDeletedCalendarEvent(String userIdToNotify, String eventTitle, String eventType, Date startDate, Date endingDate);
/**
* use to notify a user that someone created this post
*
@ -175,7 +176,21 @@ public interface NotificationsManager {
* @param feedText the liked feed text or a portion of it
* @return true if the notification is correctly delivered, false otherwise
*/
@Deprecated
boolean notifyPost(String userIdToNotify, String feedid, String feedText, String ... hashtags);
/**
* use to notify a user that someone created this post
*
* @param userIdToNotify the user you want to notify
* @param feedid the liked feedid
* @param feedText the liked feed text or a portion of it
* @param mentionedVREGroups the names of the mentioned vre's groups, if any
* @param hashtags the set of hashtags in the post, if any
* @return true if the notification is correctly delivered, false otherwise
*/
boolean notifyPost(String userIdToNotify, String feedid, String feedText, Set<String> mentionedVREGroups, Set<String> hashtags);
/**
* use to notify a user that someone commented on his post
*
@ -240,10 +255,9 @@ public interface NotificationsManager {
* use to notify a user he got one of his job finished
*
* @param userIdToNotify the user you want to notify
* @param executingApp the {@link ApplicationProfile} of the application from which the job was executed/lauched
* @return true if the notification is correctly delivered, false otherwise
*/
boolean notifyJobStatus(String userIdToNotify, ApplicationProfile executingJobApId, RunningJob job);
boolean notifyJobStatus(String userIdToNotify, RunningJob job);
boolean notifyTDMTabularResourceSharing(String userIdToNotify, String tabularResourceName, String encodedTabularResourceParams) throws Exception;
/**

View File

@ -1,6 +1,7 @@
package org.gcube.applicationsupportlayer.social.mailing;
import java.util.ArrayList;
import java.util.Set;
import org.gcube.portal.databook.shared.Notification;
import org.gcube.vomanagement.usermanagement.UserManager;
@ -44,8 +45,8 @@ public class EmailPlugin {
* @param portalName
* @param senderEmail
*/
public void sendNotification(String portalURL, String siteLandingPagePath, Notification notification2Save, String vreName, String portalName, String senderEmail, String ... hashtags) {
EmailNotificationProducer thread = new EmailNotificationProducer(new NotificationMail(userManager, portalURL, siteLandingPagePath, notification2Save, vreName, portalName, senderEmail, hashtags));
public void sendNotification(String portalURL, String siteLandingPagePath, Notification notification2Save, String vreName, String portalName, String senderEmail, Set<String> mentionedGroups, String ... hashtags) {
EmailNotificationProducer thread = new EmailNotificationProducer(new NotificationMail(userManager, portalURL, siteLandingPagePath, notification2Save, vreName, portalName, senderEmail, mentionedGroups, hashtags));
thread.start();
_log.trace("Thread notification Mail started OK");
}

View File

@ -3,6 +3,7 @@ package org.gcube.applicationsupportlayer.social.mailing;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.mail.Message;
import javax.mail.Multipart;
@ -38,10 +39,10 @@ public class NotificationMail {
private String portalURL;
private String siteLandingPagePath;
private String[] hashtags;
private Set<String> mentionedVReGroups;
private static DatabookStore store = new DBCassandraAstyanaxImpl();
public NotificationMail(UserManager userManager, String portalURL, String siteLandingPagePath, Notification notification2Send, String vreName, String portalName, String senderEmail, String ... hashtags) {
public NotificationMail(UserManager userManager, String portalURL, String siteLandingPagePath, Notification notification2Send, String vreName, String portalName, String senderEmail, Set<String> mentionedVReGroups, String ... hashtags) {
super();
this.userManager = userManager;
this.portalURL = portalURL;
@ -51,6 +52,7 @@ public class NotificationMail {
this.portalName = portalName;
this.senderEmail = senderEmail;
this.hashtags = hashtags;
this.mentionedVReGroups = mentionedVReGroups;
}
protected Message getMessageNotification(Session session) throws Exception {
@ -117,7 +119,7 @@ public class NotificationMail {
+ vreNameToUse + "[vreNameFromFeed is " + vreNameFromFeed + ", vreName is " + vreName + "]");
// set subject
msg2Return.setSubject(SocialMailingUtil.getSubjectByNotificationType(notification2Send, vreNameToUse, user.getFirstName(), hashtags));
msg2Return.setSubject(SocialMailingUtil.getSubjectByNotificationType(notification2Send, vreNameToUse, user.getFirstName(), mentionedVReGroups, hashtags));
final MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(SocialMailingUtil.getTextEmail(notification2Send, user.getFirstName(), portalURL, siteLandingPagePath, email, feed, comments, commentKey, hashtags), "text/plain; charset=UTF-8");
@ -136,9 +138,6 @@ public class NotificationMail {
return msg2Return;
}
protected Notification getNotification2Send() {
return notification2Send;
}
@ -167,4 +166,8 @@ public class NotificationMail {
return siteLandingPagePath;
}
public Set<String> getMentionedVReGroups() {
return mentionedVReGroups;
}
}

View File

@ -2,7 +2,10 @@ package org.gcube.applicationsupportlayer.social.mailing;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
import org.gcube.portal.databook.shared.Comment;
@ -74,8 +77,6 @@ public class SocialMailingUtil {
notification2Save.getType() == NotificationType.MENTION ||
notification2Save.getType() == NotificationType.OWN_COMMENT) {
body.append("<div>").append(WRITE_ABOVE_TO_REPLY).append("</div><br />");
}
String attachmentsNotice = "";
@ -193,7 +194,7 @@ public class SocialMailingUtil {
* @param vreName
* @return
*/
protected static String getSubjectByNotificationType(Notification notification2Save, String vreName, String userFirstName, String ...optionalParams) {
protected static String getSubjectByNotificationType(Notification notification2Save, String vreName, String userFirstName, Set<String> mentionedVReGroups, String ...optionalParams) {
switch (notification2Save.getType()) {
case LIKE:
return notification2Save.getSenderFullName()+" liked your post in " + (vreName == null? "" : vreName);
@ -229,17 +230,23 @@ public class SocialMailingUtil {
return notification2Save.getSenderFullName() + " mentioned you in " + (vreName == null? "" : vreName);
case POST_ALERT:
String toReturn = notification2Save.getSenderFullName() + " posted on " + vreName;
if(mentionedVReGroups != null && !mentionedVReGroups.isEmpty()){
for (String mentionedGroup : mentionedVReGroups) {
toReturn += " [" + mentionedGroup + "]";
}
}
if (optionalParams != null) { //in this case optionalParams are the hashtags
for (int i = 0; i < optionalParams.length; i++)
toReturn += " " + optionalParams[i];
Set<String> hashtags = new HashSet<String>(Arrays.asList(optionalParams));
for (String hashtag : hashtags)
toReturn += " " + hashtag;
}
return toReturn;
case REQUEST_CONNECTION:
return "Connection request";
case JOB_COMPLETED_NOK:
return "Job Completed";
return notification2Save.getSubjectid() + "'s job status notification"; // i.e. Name of the job + ...
case JOB_COMPLETED_OK:
return "Job Completed";
return notification2Save.getSubjectid() + "'s job status notification"; // i.e. Name of the job + ...
case CALENDAR_ADDED_EVENT:
return vreName +": New event in a shared calendar";
case CALENDAR_UPDATED_EVENT:
@ -309,10 +316,12 @@ public class SocialMailingUtil {
actionLink.append("\">").append(" Go to Contacts Center").append("</a>");
break;
case JOB_COMPLETED_NOK:
actionLink.append("\">").append(" Go to Application").append("</a>");
//actionLink.append("\">").append(" Go to Application").append("</a>");
actionLink.append("\">").append("").append("</a>");
break;
case JOB_COMPLETED_OK:
actionLink.append("\">").append(" Go to Application").append("</a>");
//actionLink.append("\">").append(" Go to Application").append("</a>");
actionLink.append("\">").append("").append("</a>");
break;
case CALENDAR_ADDED_EVENT:
actionLink.append("\">").append(" Go to Calendar").append("</a>");
@ -396,8 +405,7 @@ public class SocialMailingUtil {
try{
if(notification2Save.getType().equals(NotificationType.POST_ALERT) || feed == null)
return "";
if(notification2Save.getType().equals(NotificationType.COMMENT) || notification2Save.getType().equals(NotificationType.LIKE)){
String htmlPost = "<br />" + "<br />----<p>Original post:</p>";
// data formatter
@ -459,6 +467,7 @@ public class SocialMailingUtil {
}
return htmlPost;
}
}catch(Exception e){
_log.error("Unable to reconstruct html discussion to put into the email body.", e);
}
@ -477,8 +486,7 @@ public class SocialMailingUtil {
try{
if(notification2Save.getType().equals(NotificationType.POST_ALERT) || feed == null)
return "";
if(notification2Save.getType().equals(NotificationType.COMMENT) || notification2Save.getType().equals(NotificationType.LIKE)){
// build discussion
String discussion = "\n\n----\n\nOriginal post:";
@ -517,6 +525,7 @@ public class SocialMailingUtil {
return discussion;
}
}
catch(Exception e){
_log.error("Unable to reconstruct plain text discussion to put into the email body.", e);
}