social-networking-library-ws/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Notifications.java

238 lines
9.8 KiB
Java

package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.Arrays;
import java.util.List;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager;
import org.gcube.applicationsupportlayer.social.NotificationsManager;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portal.databook.shared.Notification;
import org.gcube.portal.databook.shared.RunningJob;
import org.gcube.portal.notifications.bean.GenericItemBean;
import org.gcube.portal.notifications.thread.JobStatusNotificationThread;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder;
import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
import org.gcube.portal.social.networking.ws.mappers.JobMapper;
import org.gcube.portal.social.networking.ws.mappers.WorkspaceItemMapper;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
import org.gcube.portal.social.networking.ws.utils.ErrorMessages;
import org.gcube.social_networking.socialnetworking.model.beans.JobNotificationBean;
import org.gcube.social_networking.socialnetworking.model.beans.WorkspaceNotification;
import org.gcube.social_networking.socialnetworking.model.beans.WorkspaceNotificationAddedItem;
import org.gcube.social_networking.socialnetworking.model.beans.WorkspaceNotificationSharedFolder;
import org.gcube.social_networking.socialnetworking.model.beans.WorkspaceNotificationUnsharedFolder;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (notifications).
*/
@Path("2/notifications")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class Notifications {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Notifications.class);
@GET
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
/**
* Retrieve notifications of the gcube-token's owner
* @param from must be greater or equal to 1, range[0, infinity]
* @param quantity quantity must be greater or equal to 0
* @return notifications up to quantity
* @throws ValidationException
*/
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Notifications retrieved and reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getRangeNotifications(
@DefaultValue("1") @QueryParam("from") @Min(value=1, message="from must be greater or equal to 1")
int from,
@DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity must be greater or equal to 0")
int quantity
) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
logger.debug("Retrieving " + quantity + " notifications of user = " + username + " from " + from);
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
List<Notification> notifications = null;
try{
notifications = CassandraConnection.getInstance().getDatabookStore().getRangeNotificationsByUser(username, from, quantity);
responseBean.setResult(notifications);
responseBean.setSuccess(true);
logger.debug("List of notifications retrieved");
}catch(Exception e){
logger.error("Unable to retrieve such notifications.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Send a JOB notification to a given recipient
* @param job The job bean
* @return
* @throws ValidationException
*/
@POST
@Path("notify-job-status/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Notification is sent correctly"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response notifyJobStatus(
@NotNull(message="input is missing")
@Valid
JobNotificationBean job) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
String appQualifier = caller.getClient().getId();
logger.info("Received request from app " + appQualifier + " to notify job status described by bean " + job);
try{
String recipient = job.getRecipient();
GCubeUser userRecipient = UserManagerWSBuilder.getInstance().getUserManager().getUserByUsername(recipient);
GenericItemBean recipientBean = new GenericItemBean(userRecipient.getUsername(), userRecipient.getUsername(), userRecipient.getFullname(), userRecipient.getUserAvatarURL());
// notifications are sent by using the user allowed to use liferay's json apis
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
GCubeUser senderUser = UserManagerWSBuilder.getInstance().getUserManager().getUserByEmail(LiferayJSONWsCredentials.getSingleton().getUser());
SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
RunningJob theJob = JobMapper.getJob(job);
new Thread(new JobStatusNotificationThread(theJob, Arrays.asList(recipientBean), nm)).start();
responseBean.setSuccess(true);
responseBean.setResult("Notification thread started");
}catch(Exception e){
logger.error("Unable to send job notification", e);
responseBean.setSuccess(false);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
/**
* Send a Workspace notification to a given user
* @param message
* @return
* @throws ValidationException
*/
@POST
@Path("workspace/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Workspace Notification is sent correctly"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response workspace(
@NotNull(message="input is missing")
@Valid
WorkspaceNotification message) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
String context = ScopeProvider.instance.get();
String username = caller.getClient().getId();
if (!message.getType().getNotificationClass().isInstance(message)) {
//invalid call
return Response.status(Status.BAD_REQUEST).build();
}
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
GCubeUser senderUser = UserManagerWSBuilder.getInstance().getUserManager().getUserByUsername(username);
SocialNetworkingUser user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
switch (message.getType()) {
case ITEM_NEW: {
WorkspaceNotificationAddedItem itemBean = (WorkspaceNotificationAddedItem) message;
String userIdToNotify = itemBean.getUserIdToNotify();
nm.notifyAddedItem(userIdToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
break;
}
case FOLDER_SHARE: {
WorkspaceNotificationSharedFolder itemBean = (WorkspaceNotificationSharedFolder) message;
String userIdToNotify = itemBean.getUserIdToNotify();
nm.notifyFolderSharing(userIdToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
break;
}
case FOLDER_UNSHARE: {
WorkspaceNotificationUnsharedFolder itemBean = (WorkspaceNotificationUnsharedFolder) message;
String userIdToNotify = itemBean.getUserIdToNotify();
nm.notifyFolderUnsharing(userIdToNotify, itemBean.getUnsharedFolderId(), itemBean.getUnsharedFolderName());
break;
}
default:
break;
}
} catch(Exception e){
logger.error("Unable to send job notification", e);
responseBean.setSuccess(false);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
}