Compare commits

...

11 Commits

15 changed files with 1737 additions and 297 deletions

View File

@ -1,5 +1,10 @@
# Changelog
## [v2.9.2-SNAPSHOT] - 2023-11-05
- Replace Astyanx Java client for Cassandra 2 with Datastax client for Cassandra 4
- Add REST resources for all the functions in social networking library
## [v2.9.1] - 2023-09-28
- Fix for Bug #25760 not closing connection to distributed cached

View File

@ -22,10 +22,12 @@ See [Releases](https://code-repo.d4science.org/gCubeSystem/social-networking-lib
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Costantino Perciante**
* **Ahmed Ibrahim** ([ORCID](https://orcid.org/0009-0001-3009-5755)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/en/about/people-detail/976/Ahmed_Salah_Tawfik_Ibrahim)
## Maintainers
* **Massimiliano Assante** ([ORCID](https://orcid.org/0000-0002-3761-1492)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/People/M.Assante)
* **Ahmed Ibrahim** ([ORCID](https://orcid.org/0009-0001-3009-5755)) - [ISTI-CNR Infrascience Group](https://www.isti.cnr.it/en/about/people-detail/976/Ahmed_Salah_Tawfik_Ibrahim)
## License
@ -38,4 +40,4 @@ open-source software toolkit used for building and operating Hybrid Data
Infrastructures enabling the dynamic deployment of Virtual Research Environments
by favouring the realisation of reuse oriented policies.
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)

92
pom.xml
View File

@ -1,24 +1,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-parent</artifactId>
<version>1.2.0</version>
<version>1.1.0</version>
</parent>
<groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library-ws</artifactId>
<packaging>war</packaging>
<version>2.9.1</version>
<version>2.9.2-SNAPSHOT</version>
<name>social-networking-library-ws</name>
<description>Rest interface for the social networking library.</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<enunciate.version>2.14.0</enunciate.version>
<cassandra.driver.oss.version>4.13.0</cassandra.driver.oss.version>
<jackson.version>2.8.11</jackson.version>
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -93,7 +94,7 @@
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId>
<!-- <version>2.0.0-SNAPSHOT</version> -->
<!-- <version>2.0.0-SNAPSHOT</version> -->
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
@ -124,58 +125,6 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>jersey-client</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-bundle</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-apache-client4</artifactId>
<groupId>com.sun.jersey.contribs</groupId>
</exclusion>
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.mortbay.jetty</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-thrift</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-cassandra</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.netflix.astyanax</groupId>
<artifactId>astyanax-core</artifactId>
<version>2.0.2</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.gcube.socialnetworking</groupId>
<artifactId>social-util-library</artifactId>
@ -185,7 +134,7 @@
<dependency>
<groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library</artifactId>
<version>[1.18.0-SNAPSHOT, 2.0.0-SNAPSHOT)</version>
<version>[2.0.0-SNAPSHOT, 3.0.0)</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -245,8 +194,23 @@
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-query-builder</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-mapper-runtime</artifactId>
<version>${cassandra.driver.oss.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- Please note that the elasticsearch client needs a compress-lzf version
<!-- Please note that the elasticsearch client needs a compress-lzf version
>= 1.0.2 -->
<dependency>
<groupId>com.ning</groupId>
@ -312,6 +276,16 @@
<version>4.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.22</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>

View File

@ -30,7 +30,7 @@ public class GroupsCache {
/**
* Retrieve an entry
* @param id
* @param groupId
* @return user associated to the user
*/
public GCubeGroup getGroup(long groupId){
@ -44,7 +44,7 @@ public class GroupsCache {
/**
* Save an entry into the cache
* @param id
* @param user
* @param group
*/
public void pushEntry(long id, GCubeGroup group){
Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE);

View File

@ -59,7 +59,7 @@ public class UsersCache{
/**
* Retrieve an entry
* @param id
* @param userId
* @return user associated to the user
*/
public GCubeUser getUser(long userId){

View File

@ -39,8 +39,7 @@ public class CommentInputBean implements Serializable{
/**
* @param text
* @param postid
* @param params
*/
*/
public CommentInputBean(String text, String postid) {
super();
this.text = text;

View File

@ -46,11 +46,12 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (comments).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/comments")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class Comments {
@ -59,20 +60,20 @@ public class Comments {
/*
* Retrieve the list of comments belonging to the post id (key) of the token in the related context
* @param key the key as in the POST JSON representation
* @param key the key as in the POST JSON representation
* @pathExample /get-comments-by-post-id?key=9ea137e9-6606-45ff-a1a2-94d4e8760583
* @return the list of comments belonging to the post identified by the key in the context identified by the token
* @return the list of comments belonging to the post identified by the key in the context identified by the token
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-by-post-id")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllCommentsByPostId(
@NotNull
@QueryParam("key")
@QueryParam("key")
String key) {
ResponseBean responseBean = new ResponseBean();
@ -105,8 +106,8 @@ public class Comments {
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getCommentsUser() {
@ -140,10 +141,10 @@ public class Comments {
@Produces(MediaType.APPLICATION_JSON)
@Path("get-comments-user-by-time")
public Response getCommentsUserByTime(
@QueryParam("time")
@Min(value = 0, message="time cannot be negative")
@QueryParam("time")
@Min(value = 0, message="time cannot be negative")
long timeInMillis
) throws ValidationException{
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
@ -179,12 +180,12 @@ public class Comments {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Successfull created, the new comment is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Successfull created, the new comment is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response writeComment(
@NotNull(message="Comment to write is missing")
@Valid
@NotNull(message="Comment to write is missing")
@Valid
CommentInputBean comment) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
@ -220,7 +221,7 @@ public class Comments {
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
catch(Exception e) {
logger.error("Unable to write comment", e);
responseBean.setMessage("Could not reach the DB to write the comment, something went wrong");
@ -229,6 +230,4 @@ public class Comments {
return Response.status(status).entity(responseBean).build();
}
}
}

View File

@ -1,10 +1,13 @@
package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.List;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@ -13,6 +16,7 @@ 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.server.DatabookStore;
import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
import org.gcube.portal.social.networking.ws.outputs.ResponseBean;
import org.gcube.portal.social.networking.ws.utils.CassandraConnection;
@ -26,12 +30,13 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (hash tags).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/hashtags")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class HashTags {
// Logger
@ -41,8 +46,8 @@ public class HashTags {
@Path("get-hashtags-and-occurrences/")
@Produces({MediaType.APPLICATION_JSON})
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Hashtags and occurrences retrieved, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Hashtags and occurrences retrieved, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
/**
* @return hashtags in the context bound to the auth token
@ -76,5 +81,4 @@ public class HashTags {
return Response.status(status).entity(responseBean).build();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -35,11 +35,12 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (likes).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/likes")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class Likes {
@ -48,20 +49,20 @@ public class Likes {
/*
* Retrieve the list of likes belonging to the post id (key) of the token in the related context
* @param key the key as in the POST JSON representation
* @param key the key as in the POST JSON representation
* @pathExample /get-likes-by-post-id?key=9ea137e9-6606-45ff-a1a2-94d4e8760583
* @return the list of likes belonging to the post identified by the key in the context identified by the token
* @return the list of likes belonging to the post identified by the key in the context identified by the token
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("get-likes-by-post-id")
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The list of likes is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "The list of likes is put into the 'result' field"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllLikesByPostId(
@NotNull
@QueryParam("key")
@QueryParam("key")
String key) {
ResponseBean responseBean = new ResponseBean();
@ -89,7 +90,7 @@ public class Likes {
/**
* Create a new like to a post in the context of the token
* @param postid The post id to be liked
* @return true if everything is OK
* @return true if everything is OK
* @throws ValidationException
*/
@POST
@ -97,12 +98,12 @@ public class Likes {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Successful created, the like operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Successful created, the like operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response like(
@NotNull(message="Post to like is missing")
@Valid
@NotNull(message="Post to like is missing")
@Valid
PostId post) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
@ -125,7 +126,7 @@ public class Likes {
responseBean.setSuccess(true);
return Response.status(status).entity(responseBean).build();
}
/**
* Unlike to a post in the context of the token
* @param postid The post id to be liked
@ -137,12 +138,12 @@ public class Likes {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "The unlike operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "The unlike operation result is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response unlike(
@NotNull(message="Post to unlike is missing")
@Valid
@NotNull(message="Post to unlike is missing")
@Valid
LikeInputBean likeInputBean) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.ValidationException;
@ -31,6 +32,8 @@ import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.portal.databook.shared.Notification;
import org.gcube.portal.databook.shared.NotificationChannelType;
import org.gcube.portal.databook.shared.NotificationType;
import org.gcube.portal.databook.shared.RunningJob;
import org.gcube.portal.notifications.bean.GenericItemBean;
import org.gcube.portal.notifications.thread.JobStatusNotificationThread;
@ -75,11 +78,12 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (notifications).
* @author Ahmed Ibrahim ISTI-CNR
*/
@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")
@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 {
@ -98,15 +102,15 @@ public class Notifications {
@Path("get-range-notifications/")
@Produces(MediaType.APPLICATION_JSON)
@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)
@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")
@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")
@DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity must be greater or equal to 0")
int quantity
) throws ValidationException{
) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
String username = caller.getClient().getId();
@ -139,19 +143,19 @@ public class Notifications {
* @responseExample application/json { "success": true, "message": null "result": true }
* @param username the username you want to check
* @return true if the notification for the user are disabled (Catalogue and Workspace ones)
*
*
*/
@GET
@Path("is-user-disabled/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "true if the notification for the username given as query param are disabled (Catalogue and Workspace ones), false otherwise"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "true if the notification for the username given as query param are disabled (Catalogue and Workspace ones), false otherwise"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
public Response isUserDisabled(
@QueryParam("username") @NotNull(message="username cannot be null")
@QueryParam("username") @NotNull(message="username cannot be null")
String username) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
@ -186,8 +190,8 @@ public class Notifications {
// })
// @AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE}, exception=AuthException.class)
// public Response setUserNotifications(
// @NotNull(message="input is missing")
// @Valid
// @NotNull(message="input is missing")
// @Valid
// UserSetNotificationBean setting) throws ValidationException{
//
// Caller caller = AuthorizationProvider.instance.get();
@ -220,10 +224,10 @@ public class Notifications {
// }
/**
* @deprecated
* @deprecated
* @param usernameToCheck
* @return true if notification are enabled for this user
* @throws IOException
* @throws IOException
*/
private boolean isNotificationEnabled(String usernameToCheck) throws IOException {
// MemcachedClient entries = new DistributedCacheClient().getMemcachedClient();
@ -236,12 +240,12 @@ public class Notifications {
return true;
}
// /**
// *
// *
// * @param username the user you want to disable or enable notifications (max 29 days)
// * @param callerId the username or clientid of the operation executor
// * @param disable true if you want to disable the notifications for this user
// * @return true if the operation was performed
// * @throws IOException
// * @throws IOException
// */
// private Boolean setUserNotificationsOnOff(String username, boolean disable, String callerId) throws IOException {
// MemcachedClient entries = new DistributedCacheClient().getMemcachedClient();
@ -274,12 +278,12 @@ public class Notifications {
@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)
@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
@NotNull(message="input is missing")
@Valid
JobNotificationBean job) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
@ -330,12 +334,12 @@ public class Notifications {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Catalogue Notification is sent correctly"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Catalogue Notification is sent correctly"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response catalogue(
@NotNull(message="input is missing")
@Valid
@NotNull(message="input is missing")
@Valid
CatalogueEvent event) throws ValidationException, UserManagementSystemException, UserRetrievalFault{
Caller caller = AuthorizationProvider.instance.get();
@ -351,14 +355,14 @@ public class Notifications {
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username);
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}else{
username = caller.getClient().getId();
senderUser = um.getUserByUsername(username);
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
}
}
String context = ScopeProvider.instance.get();
logger.debug("catalogue notifications from user = " + username);
@ -368,9 +372,9 @@ public class Notifications {
try {
logger.debug("catalogue notifications type is " + event.getType());
SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(context);
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) {
@ -379,7 +383,7 @@ public class Notifications {
if (isNotificationEnabled(userIdToNotify)) {
String username2Notify = null;
try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
}
catch (Exception e) {
status = Status.BAD_REQUEST;
@ -389,14 +393,14 @@ public class Notifications {
return Response.status(status).entity(responseBean).build();
}
deliveryResult =
deliveryResult =
nm.notifyCatalogueEvent(
CatalogueEventTypeMapper.getType(event.getType()),
username2Notify,
event.getItemId(),
event.getNotifyText(),
CatalogueEventTypeMapper.getType(event.getType()),
username2Notify,
event.getItemId(),
event.getNotifyText(),
event.getItemURL());
}
}
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
@ -417,20 +421,20 @@ public class Notifications {
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify)) {
deliveryResult =
if (isNotificationEnabled(userIdToNotify)) {
deliveryResult =
nm.notifyCatalogueEvent(
CatalogueEventTypeMapper.getType(event.getType()),
userIdToNotify,
event.getItemId(),
event.getNotifyText(),
CatalogueEventTypeMapper.getType(event.getType()),
userIdToNotify,
event.getItemId(),
event.getNotifyText(),
event.getItemURL());
} else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
}
}
}
catch(IllegalArgumentException e) {
status = Status.BAD_REQUEST;
logger.error("Context not valid", e);
@ -470,12 +474,12 @@ public class Notifications {
@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)
@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
@NotNull(message="input is missing")
@Valid
WorkspaceEvent event) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
@ -499,23 +503,23 @@ public class Notifications {
SecurityTokenProvider.instance.set(LiferayJSONWsCredentials.getSingleton().getNotifierUserToken());
username = jarvis.getUsername();
fullName = caller.getClient().getId().replace("service-account-", ""); // the actual name of the IAM Client
senderUser = um.getUserByUsername(username);
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), fullName, senderUser.getUserAvatarURL());
}else{
username = caller.getClient().getId();
senderUser = um.getUserByUsername(username);
senderUser = um.getUserByUsername(username);
user = new SocialNetworkingUser(senderUser.getUsername(), senderUser.getEmail(), senderUser.getFullname(), senderUser.getUserAvatarURL());
}
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
}
NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, user);
String[] idsToNotify = event.getIdsToNotify();
if (! event.idsAsGroup()) {
for (int i = 0; i < idsToNotify.length; i++) {
String userIdToNotify = idsToNotify[i];
if (isNotificationEnabled(userIdToNotify)) {
if (isNotificationEnabled(userIdToNotify)) {
String username2Notify = "";
try {
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
username2Notify = um.getUserByUsername(userIdToNotify).getUsername();
}
catch (Exception e) {
status = Status.NOT_ACCEPTABLE;
@ -545,14 +549,14 @@ public class Notifications {
String[] userIdsToNotify = getUsernamesByContext(scope).toArray(new String[0]); //resolve the members
for (int j = 0; j < userIdsToNotify.length; j++) {
String userIdToNotify = userIdsToNotify[j];
if (isNotificationEnabled(userIdToNotify))
if (isNotificationEnabled(userIdToNotify))
deliveryResult = notifyWorkspaceEvent(event, nm, userIdToNotify);
else {
Log.info("Notification disabled (admin) for user "+userIdToNotify + " will not notify");
}
}
}
}
}
catch(IllegalArgumentException e) {
status = Status.BAD_REQUEST;
logger.error("Context not valid", e);
@ -581,7 +585,7 @@ public class Notifications {
return Response.status(status).entity(responseBean).build();
}
/**
*
*
* @param event
* @param nm
* @param idToNotify
@ -590,49 +594,49 @@ public class Notifications {
private boolean notifyWorkspaceEvent(WorkspaceEvent event, NotificationsManager nm, String idToNotify) {
try {
switch (event.getType()) {
case ITEM_NEW: {
AddedItemEvent itemBean = (AddedItemEvent) event;
return nm.notifyAddedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
}
case ITEM_UPDATE: {
UpdatedItemEvent itemBean = (UpdatedItemEvent) event;
return nm.notifyUpdatedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
}
case ITEM_DELETE: {
DeletedItemEvent itemBean = (DeletedItemEvent) event;
return nm.notifyRemovedItem(idToNotify, itemBean.getItemName(), WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_SHARE: {
SharedFolderEvent itemBean = (SharedFolderEvent) event;
return nm.notifyFolderSharing(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_UNSHARE: {
UnsharedFolderEvent itemBean = (UnsharedFolderEvent) event;
return nm.notifyFolderUnsharing(idToNotify, itemBean.getUnsharedFolderId(), itemBean.getUnsharedFolderName());
}
case FOLDER_RENAME: {
RenamedFolderEvent itemBean = (RenamedFolderEvent) event;
return nm.notifyFolderRenaming(idToNotify, itemBean.getPreviousName(), itemBean.getNewName(), itemBean.getRenamedFolderId());
}
case FOLDER_ADMIN_UPGRADE: {
FolderAdminUpgradeEvent itemBean = (FolderAdminUpgradeEvent) event;
return nm.notifyAdministratorUpgrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_ADMIN_DOWNGRADE: {
FolderAdminDowngradeEvent itemBean = (FolderAdminDowngradeEvent) event;
return nm.notifyAdministratorDowngrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_ADDEDUSER: {
FolderAddedUserEvent itemBean = (FolderAddedUserEvent) event;
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
return nm.notifyFolderAddedUsers(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()), itemBean.getNewAddedUserIds(), userManager);
}
case FOLDER_REMOVEDUSER: {
FolderRemovedUserEvent itemBean = (FolderRemovedUserEvent) event;
return nm.notifyFolderRemovedUser(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
default:
break;
case ITEM_NEW: {
AddedItemEvent itemBean = (AddedItemEvent) event;
return nm.notifyAddedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
}
case ITEM_UPDATE: {
UpdatedItemEvent itemBean = (UpdatedItemEvent) event;
return nm.notifyUpdatedItem(idToNotify, WorkspaceItemMapper.getFileItem(itemBean.getItem()), WorkspaceItemMapper.getSharedFolder(itemBean.getItem().getParent()));
}
case ITEM_DELETE: {
DeletedItemEvent itemBean = (DeletedItemEvent) event;
return nm.notifyRemovedItem(idToNotify, itemBean.getItemName(), WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_SHARE: {
SharedFolderEvent itemBean = (SharedFolderEvent) event;
return nm.notifyFolderSharing(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_UNSHARE: {
UnsharedFolderEvent itemBean = (UnsharedFolderEvent) event;
return nm.notifyFolderUnsharing(idToNotify, itemBean.getUnsharedFolderId(), itemBean.getUnsharedFolderName());
}
case FOLDER_RENAME: {
RenamedFolderEvent itemBean = (RenamedFolderEvent) event;
return nm.notifyFolderRenaming(idToNotify, itemBean.getPreviousName(), itemBean.getNewName(), itemBean.getRenamedFolderId());
}
case FOLDER_ADMIN_UPGRADE: {
FolderAdminUpgradeEvent itemBean = (FolderAdminUpgradeEvent) event;
return nm.notifyAdministratorUpgrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_ADMIN_DOWNGRADE: {
FolderAdminDowngradeEvent itemBean = (FolderAdminDowngradeEvent) event;
return nm.notifyAdministratorDowngrade(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
case FOLDER_ADDEDUSER: {
FolderAddedUserEvent itemBean = (FolderAddedUserEvent) event;
UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
return nm.notifyFolderAddedUsers(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()), itemBean.getNewAddedUserIds(), userManager);
}
case FOLDER_REMOVEDUSER: {
FolderRemovedUserEvent itemBean = (FolderRemovedUserEvent) event;
return nm.notifyFolderRemovedUser(idToNotify, WorkspaceItemMapper.getSharedFolder(itemBean.getFolder()));
}
default:
break;
}
} catch(Exception e){
logger.error("Unable to send job notification", e);
@ -641,7 +645,7 @@ public class Notifications {
return false;
}
/**
*
*
* @param context
* @return
* @throws Exception
@ -670,5 +674,4 @@ public class Notifications {
}
return usernames;
}
}

View File

@ -3,6 +3,7 @@ package org.gcube.portal.social.networking.ws.methods.v2;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.ValidationException;
@ -18,15 +19,13 @@ 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.portal.databook.shared.PostWithAttachment;
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.server.DatabookStore;
import org.gcube.portal.databook.shared.ApplicationProfile;
import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.Post;
import org.gcube.portal.databook.shared.RangePosts;
import org.gcube.portal.databook.shared.*;
import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException;
@ -46,17 +45,18 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* REST interface for the social networking library (posts).
* @author Ahmed Ibrahim ISTI-CNR
*/
@Path("2/posts")
@RequestHeaders ({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
@RequestHeader( name = "Content-Type", description = "application/json")
})
public class Posts {
// Logger
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Posts.class);
/**
* Retrieve posts of the auth token's owner, and allow to filter them by time"
* @param timeInMillis The reference time since when retrieving posts
@ -67,13 +67,13 @@ public class Posts {
@Path("get-posts-user-since/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getRecentPostsByUserAndDate(
@QueryParam("time") @Min(value = 0, message="time cannot be negative")
@QueryParam("time") @Min(value = 0, message="time cannot be negative")
long timeInMillis
) throws ValidationException{
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
@ -100,8 +100,8 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve all user's posts
* @return all posts of the auth token's owner in the context identified by the token
@ -110,8 +110,8 @@ public class Posts {
@Path("get-posts-user/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllPostsByUser() {
@ -138,7 +138,7 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve a post by id
* @return the post if the post id belongs to a post in the context identified by the token
@ -147,18 +147,18 @@ public class Posts {
@Path("get-post/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getPost(@QueryParam("id") String id) {
String context = ScopeProvider.instance.get();
String context = ScopeProvider.instance.get();
Caller caller = AuthorizationProvider.instance.get();
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
List<Post> posts = new ArrayList<>();
try{
logger.debug("Retrieving post with id " + id);
try {
try {
posts.add(CassandraConnection.getInstance().getDatabookStore().readPost(id));
} catch(FeedIDNotFoundException e){
responseBean.setMessage("The post with id " + id + " does not exist in context " + context);
@ -185,7 +185,7 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve a given quantity of latest user's posts
* @param quantity the number of latest post to get
@ -197,13 +197,13 @@ public class Posts {
@Path("get-posts-user-quantity/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getQuantityPostsByUser(
@DefaultValue("10")
@QueryParam("quantity")
@Min(value=0, message="quantity cannot be negative")
@DefaultValue("10")
@QueryParam("quantity")
@Min(value=0, message="quantity cannot be negative")
int quantity) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
@ -239,7 +239,7 @@ public class Posts {
}
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new user post having as owner the auth token's owner
* @param post The post to be written
@ -251,12 +251,12 @@ public class Posts {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response writePostUser(
@NotNull(message="Post to write is missing")
@Valid
@NotNull(message="Post to write is missing")
@Valid
PostInputBean post) throws ValidationException{
logger.debug("Request of writing a feed coming from user " + post);
@ -286,15 +286,15 @@ public class Posts {
logger.debug("Trying to share user post...");
Post res = SocialUtils.shareUserUpdate(
username,
postText,
context,
postText,
context,
previewTitle,
previewDescription,
previewHost,
previewUrl,
httpImageUrl,
httpImageUrl,
enableNotification
);
);
if(res != null){
logger.debug("Post correctly written by user " + username);
@ -311,7 +311,7 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve the application's posts
* @return the application (IAM Client) posts belonging to the token's owner (i.e., an application)"
@ -320,9 +320,9 @@ public class Posts {
@Path("get-posts-app/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllPostsByApp() {
@ -362,7 +362,7 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Create a new application post having as owner-application the token's owner (the IAM Client), note that the application must be registered on the Information System
* @param post The post to be written
@ -373,13 +373,13 @@ public class Posts {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"),
@ResponseCode ( code = 403, condition = "\"There is no application profile with such token"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response writePostApp(
@NotNull(message="Post to write is null")
@Valid
@NotNull(message="Post to write is null")
@Valid
PostInputBean post){
Caller caller = AuthorizationProvider.instance.get();
@ -417,15 +417,15 @@ public class Posts {
// write post + notification if it is the case
Post written = SocialUtils.shareApplicationUpdate(
postText,
params,
previewTitle,
previewDescription,
httpImageUrl,
appProfile,
postText,
params,
previewTitle,
previewDescription,
httpImageUrl,
appProfile,
caller,
enableNotification
);
);
if(written != null){
responseBean.setResult(written);
@ -441,15 +441,15 @@ public class Posts {
}
/**
*
*
* @return all the posts in the context bound to the auth token
*/
@GET
@Path("get-posts-vre/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllPostsByVRE() {
@ -476,28 +476,28 @@ public class Posts {
/**
* return the most recent posts for this vre up to quantity param and the last index of the posts in the timeline
* lastReturnedPostTimelineIndex is useful to know from where to start the range the next time you ask, because there are deletions
*
*
* @param from the range start (most recent feeds for this vre) has to be greater than 0
* @param quantity the number of most recent feeds for this vre starting from "from" param
* @pathExample /get-recent-posts-vre-by-range?from=1&quantity=10
* @return a <class>RangePosts</class> containing of most recent feeds for this vre
* @throws FeedTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
* @throws FeedTypeNotFoundException
* @throws PrivacyLevelTypeNotFoundException
* @throws ColumnNameNotFoundException
*/
@GET
@Path("get-recent-posts-vre-by-range/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getRecentPostsByVREAndRange(
@QueryParam("from")
@Min(value=1, message="from cannot be negative")
@QueryParam("from")
@Min(value=1, message="from cannot be negative")
int from,
@QueryParam("quantity")
@Min(value=1, message="quantity cannot be negative")
@QueryParam("quantity")
@Min(value=1, message="quantity cannot be negative")
int quantity) throws ValidationException {
String context = ScopeProvider.instance.get();
@ -531,12 +531,12 @@ public class Posts {
@Path("get-posts-by-hashtag/")
@Produces({MediaType.APPLICATION_JSON})
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getPostsByHashTags(
@QueryParam("hashtag")
@NotNull(message="hashtag cannot be missing")
@QueryParam("hashtag")
@NotNull(message="hashtag cannot be missing")
String hashtag) throws ValidationException {
Caller caller = AuthorizationProvider.instance.get();
@ -558,7 +558,7 @@ public class Posts {
}
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve ids (UUID) of the liked posts by the user
* @return ids (UUID) of the liked posts by the user in the context bound to the auth token
@ -567,8 +567,8 @@ public class Posts {
@Path("get-id-liked-posts/")
@Produces({MediaType.APPLICATION_JSON})
@StatusCodes ({
@ResponseCode ( code = 201, condition = "Sccessfull retrieved ids, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 201, condition = "Sccessfull retrieved ids, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllLikedPostIdsByUser() {
@ -597,7 +597,7 @@ public class Posts {
return Response.status(status).entity(responseBean).build();
}
/**
* Retrieve posts liked by the user
* @param limit The maximum number of posts to be retrieved
@ -608,13 +608,13 @@ public class Posts {
@Path("get-liked-posts/")
@Produces(MediaType.APPLICATION_JSON)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "Successfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
@ResponseCode ( code = 200, condition = "Successfull retrieved posts, they are reported in the 'result' field of the returned object"),
@ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT)
})
public Response getAllLikedPostsByUser(
@DefaultValue("10")
@QueryParam("limit")
@Min(message="limit cannot be negative", value = 0)
@DefaultValue("10")
@QueryParam("limit")
@Min(message="limit cannot be negative", value = 0)
int limit) throws ValidationException{
Caller caller = AuthorizationProvider.instance.get();
@ -640,4 +640,63 @@ public class Posts {
}
return Response.status(status).entity(responseBean).build();
}
//libapi
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("save-user-post-attachments-lib")
public Response saveUserPostLib(
@NotNull(message="post to add is missing")
@Valid
PostWithAttachment postWithAttachment
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
Post post = postWithAttachment.getPost();
logger.info("Post is " + post);
List<Attachment> attachments = postWithAttachment.getAttachments();
logger.info("Attachments are " + attachments);
boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserPost(post,attachments);
responseBean.setResult(result);
responseBean.setMessage("");
responseBean.setSuccess(result);
}catch(Exception e){
logger.error("Unable to write comment.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("save-app-post-attachments-lib")
public Response saveAppPostLib(
@NotNull(message="post to add is missing")
@Valid
PostWithAttachment postWithAttachment
) throws ValidationException{
ResponseBean responseBean = new ResponseBean();
Status status = Status.OK;
try{
Post post = postWithAttachment.getPost();
List<Attachment> attachments = postWithAttachment.getAttachments();
boolean result = CassandraConnection.getInstance().getDatabookStore().saveAppPost(post,attachments);
responseBean.setResult(result);
responseBean.setMessage("");
responseBean.setSuccess(result);
}catch(Exception e){
logger.error("Unable to write comment.", e);
responseBean.setMessage(e.getMessage());
responseBean.setSuccess(false);
status = Status.INTERNAL_SERVER_ERROR;
}
return Response.status(status).entity(responseBean).build();
}
}

View File

@ -31,8 +31,7 @@ public class ResponseBean implements Serializable {
* @param success
* @param message
* @param result
* @param help
*/
*/
public ResponseBean(boolean success, String message, Object result) {
super();
this.success = success;

View File

@ -89,7 +89,7 @@ public class Filters {
* If the initial context is the root: all feeds are returned;
* If the initial context is a VO: feeds for vres within the vo are returned;
* If the initial context is a vre: feeds of the vre are returned;
* @param retrievedLikedFeeds
* @param feeds
* @param context
* @throws Exception
*/
@ -160,7 +160,7 @@ public class Filters {
/**
* Depending on the type of object provided (e.g. Feed, Comment etc), some information are removed
* @param comments
* @param toClear
* @throws Exception
*/
public static <T> void hideSensitiveInformation(List<T> toClear, String usernameCaller){

View File

@ -108,7 +108,7 @@ public class SocialUtils {
/**
* Method used when an application needs to publish something.
* @param feedText
* @param postText
* @param uriParams
* @param previewTitle
* @param previewDescription