package org.gcube.social_networking.server; import java.time.Instant; import java.util.*; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.cql.*; import com.datastax.oss.driver.api.querybuilder.QueryBuilder; import org.apache.commons.lang.NullArgumentException; import org.gcube.social_networking.socialnetworking.model.shared.*; import org.gcube.social_networking.socialnetworking.model.shared.exceptions.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.gcube.social_networking.utils.Schema.*; /** * @author Massimiliano Assante ISTI-CNR * @author Costantino Perciante ISTI-CNR * @author Ahmed Ibrahim ISTI-CNR * This class is used for querying and adding data to Cassandra via Datastax High Level API */ public final class SocialDBDatastaxDriver implements SocialDBDriver { /** * logger */ private static final Logger _log = LoggerFactory.getLogger(SocialDBDatastaxDriver.class); /** * connection instance */ private CassandraClusterConnection conn; protected CassandraClusterConnection getConnection() { return conn; } /** * use this constructor carefully from test classes * @param dropSchema set true if you want do drop the current and set up new one */ protected SocialDBDatastaxDriver(boolean dropSchema) { try { conn = new CassandraClusterConnection(dropSchema); } catch (Exception e) { throw new RuntimeException(e); } } /** * public constructor, no dropping schema is allowed */ public SocialDBDatastaxDriver() { try { conn = new CassandraClusterConnection(false); } catch (Exception e) { throw new RuntimeException(e); } } /** * public constructor, no dropping schema is allowed, infrastructureName is given. */ public SocialDBDatastaxDriver(String infrastructureName) { try { conn = new CassandraClusterConnection(false, infrastructureName); } catch (Exception e) { throw new RuntimeException(e); } } /* Utility Functions */ private static boolean existRecordbyId(CqlSession session, String id, String tableName, String colName) { PreparedStatement stmt = session.prepare(QueryBuilder .selectFrom(tableName).column(colName) .whereColumn(colName) .isEqualTo(QueryBuilder.bindMarker()) .build()); return session.execute(stmt.bind(id)).getAvailableWithoutFetching() > 0; } private static boolean existRecordbyCompId(CqlSession session, String col1, String col2, String id1, String id2, String tableName) { PreparedStatement stmt = session.prepare(QueryBuilder .selectFrom(tableName).all() .whereColumn(col1) .isEqualTo(QueryBuilder.bindMarker()) .whereColumn(col2) .isEqualTo(QueryBuilder.bindMarker()) .build()); return session.execute(stmt.bind(id1, id2)).getAvailableWithoutFetching() > 0; } private static PreparedStatement updatePostEntry(CqlSession session, String colName){ return session.prepare(QueryBuilder.update(POSTS) .setColumn(colName, QueryBuilder.bindMarker()) .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static Attachment readAttachmentFromRow(Row record) { Attachment a = new Attachment(); a.setId(Objects.requireNonNull(record.getUuid(ATTACH_ID)).toString()); a.setUri(record.getString(URI)); a.setName(record.getString(NAME)); a.setDescription(record.getString(DESCRIPTION)); a.setThumbnailURL(record.getString(URI_THUMBNAIL)); a.setMimeType(record.getString(MIME_TYPE)); return a; } private static Notification readNotificationFromRow(Row record) throws NotificationTypeNotFoundException { Notification a = new Notification(); a.setKey(Objects.requireNonNull(record.getUuid(NOT_ID)).toString()); a.setType(getNotificationType(Objects.requireNonNull(record.getString(TYPE)))); a.setUserid(record.getString(USER_ID)); a.setSubjectid(record.getString(SUBJECT_ID)); a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); a.setUri(record.getString(URI)); a.setDescription(record.getString(DESCRIPTION)); a.setRead(record.getBoolean(IS_READ)); a.setSenderid(record.getString(SENDER_ID)); a.setSenderFullName(record.getString(SENDER_FULL_NAME)); a.setSenderThumbnail(record.getString(SENDER_THUMBNAIL_URL)); return a; } private static Post readPostFromRow(Row record) throws PostTypeNotFoundException, PrivacyLevelTypeNotFoundException { Post a = new Post(); a.setKey(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); a.setType(getPostType(Objects.requireNonNull(record.getString(TYPE)))); a.setEntityId(record.getString(ENTITY_ID)); a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); a.setVreid(record.getString(VRE_ID)); a.setUri(record.getString(URI)); a.setUriThumbnail(record.getString(URI_THUMBNAIL)); a.setDescription(record.getString(DESCRIPTION)); a.setPrivacy(getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY)))); a.setFullName(record.getString(FULL_NAME)); a.setEmail(record.getString(EMAIL)); a.setThumbnailURL(record.getString(THUMBNAIL_URL)); a.setCommentsNo(String.valueOf(record.getLong(COMMENTS_NO))); a.setLikesNo(String.valueOf(record.getLong(LIKES_NO))); a.setLinkDescription(record.getString(LINK_DESCRIPTION)); a.setLinkTitle(record.getString(LINK_TITLE)); a.setLinkHost(record.getString(LINK_HOST)); a.setApplicationPost(record.getBoolean(IS_APPLICATION_POST)); a.setMultiFileUpload(record.getBoolean(MULTI_FILE_UPLOAD)); return a; } private static Like readLikeFromRow(Row record) { Like a = new Like(); a.setKey(Objects.requireNonNull(record.getUuid(LIKE_ID)).toString()); a.setUserid(record.getString(USER_ID)); a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); a.setPostid(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); a.setFullName(record.getString(FULL_NAME)); a.setThumbnailURL(record.getString(THUMBNAIL_URL)); return a; } private static Comment readCommentFromRow(Row record) { Comment a = new Comment(); a.setKey(Objects.requireNonNull(record.getUuid(COMMENT_ID)).toString()); a.setUserid(record.getString(USER_ID)); a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); a.setPostid(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); a.setFullName(record.getString(FULL_NAME)); a.setThumbnailURL(record.getString(THUMBNAIL_URL)); a.setText(record.getString(COMMENT)); a.setEdit(!record.isNull(IS_EDIT) && record.getBoolean(IS_EDIT)); a.setLastEditTime(record.isNull(LAST_EDIT_TIME)? null : Date.from(Objects.requireNonNull(record.getInstant(LAST_EDIT_TIME)))); return a; } private static Invite readAInviteFromRow(Row record) throws InviteStatusNotFoundException { Invite a = new Invite(); a.setKey(Objects.requireNonNull(record.getUuid(INVITE_ID)).toString()); a.setSenderUserId(record.getString(SENDER_USER_ID)); a.setVreid(record.getString(VRE_ID)); a.setInvitedEmail(record.getString(EMAIL)); a.setControlCode(record.getString(CONTROL_CODE)); a.setStatus(getInviteStatusType(Objects.requireNonNull(record.getString(STATUS)))); a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); a.setSenderFullName(record.getString(SENDER_FULL_NAME)); return a; } private static Optional < Post > findPostById(String postid, CqlSession session) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException { PreparedStatement stmtFindPost = session.prepare(QueryBuilder .selectFrom(POSTS).all() .whereColumn(POST_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); ResultSet rs = session.execute(stmtFindPost.bind(UUID.fromString(postid))); // We query by the primary key ensuring unicity Row record = rs.one(); return (null != record) ? Optional.of(readPostFromRow(record)) :Optional.empty(); } private static Optional < Notification > findNotById(String notid, CqlSession session) throws NotificationTypeNotFoundException { PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(NOTIFICATIONS).all() .whereColumn(NOT_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); ResultSet rs = session.execute(stmtFind.bind(UUID.fromString(notid))); // We query by the primary key ensuring unicity Row record = rs.one(); return (null != record) ? Optional.of(readNotificationFromRow(record)) :Optional.empty(); } private static PreparedStatement updateInviteEntry(CqlSession session, String colName){ return session.prepare(QueryBuilder.update(INVITES) .setColumn(colName, QueryBuilder.bindMarker()) .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement updateVreInviteEntry(CqlSession session, String colName){ return session.prepare(QueryBuilder.update(VRE_INVITES) .setColumn(colName, QueryBuilder.bindMarker()) .whereColumn(VRE_ID).isEqualTo(QueryBuilder.bindMarker()) .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteHashtagEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_POSTS) .whereColumn(HASHTAG) .isEqualTo(QueryBuilder.bindMarker()) .whereColumn(POST_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteHashtagCommentEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_COMMENTS) .whereColumn(HASHTAG) .isEqualTo(QueryBuilder.bindMarker()) .whereColumn(COMMENT_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteLikeEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(LIKES) .whereColumn(LIKE_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteUserLikeEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(USER_LIKED_POSTS) .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .whereColumn(LIKE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement updateCommentEntry(CqlSession session, String colName){ return session.prepare(QueryBuilder.update(COMMENTS) .setColumn(colName, QueryBuilder.bindMarker()) .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteCommentEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(COMMENTS) .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement updateNotificationEntry(CqlSession session, String colName){ return session.prepare(QueryBuilder.update(NOTIFICATIONS) .setColumn(colName, QueryBuilder.bindMarker()) .whereColumn(NOT_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); } private static PreparedStatement deleteUnreadNotEntry(CqlSession session){ return session.prepare(QueryBuilder.deleteFrom(USER_NOTIFICATIONS_UNREAD) .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .whereColumn(TIMESTAMP) .isEqualTo(QueryBuilder.bindMarker()) .build()); } private static BatchStatement getBatch(){ return BatchStatement.builder(BatchType.LOGGED).build(); } private static PreparedStatement createPostEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(POSTS) .value(POST_ID, QueryBuilder.bindMarker()) .value(LINK_HOST, QueryBuilder.bindMarker()) .value(DESCRIPTION, QueryBuilder.bindMarker()) .value(EMAIL, QueryBuilder.bindMarker()) .value(LIKES_NO, QueryBuilder.bindMarker()) .value(THUMBNAIL_URL, QueryBuilder.bindMarker()) .value(LINK_DESCRIPTION, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(URI, QueryBuilder.bindMarker()) .value(IS_APPLICATION_POST, QueryBuilder.bindMarker()) .value(ENTITY_ID, QueryBuilder.bindMarker()) .value(PRIVACY, QueryBuilder.bindMarker()) .value(TYPE, QueryBuilder.bindMarker()) .value(URI_THUMBNAIL, QueryBuilder.bindMarker()) .value(VRE_ID, QueryBuilder.bindMarker()) .value(MULTI_FILE_UPLOAD, QueryBuilder.bindMarker()) .value(FULL_NAME, QueryBuilder.bindMarker()) .value(COMMENTS_NO, QueryBuilder.bindMarker()) .value(LINK_TITLE, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createUserTimelineEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(USER_TIMELINE_POSTS) .value(USER_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createVreTimelineEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(VRE_TIMELINE_POSTS) .value(VRE_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createAppTimelineEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(APP_TIMELINE_POSTS) .value(APP_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNotificationEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(NOTIFICATIONS) .value(NOT_ID, QueryBuilder.bindMarker()) .value(TYPE, QueryBuilder.bindMarker()) .value(USER_ID, QueryBuilder.bindMarker()) .value(SUBJECT_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(DESCRIPTION, QueryBuilder.bindMarker()) .value(URI, QueryBuilder.bindMarker()) .value(SENDER_ID, QueryBuilder.bindMarker()) .value(SENDER_FULL_NAME, QueryBuilder.bindMarker()) .value(SENDER_THUMBNAIL_URL, QueryBuilder.bindMarker()) .value(IS_READ, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createUserNotificationsEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(USER_NOTIFICATIONS) .value(USER_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(NOT_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createUnreadNotificationEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(USER_NOTIFICATIONS_UNREAD) .value(USER_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(NOT_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNotificationPreferenceEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(USER_NOTIFICATIONS_PREFERENCES) .value(USER_ID, QueryBuilder.bindMarker()) .value(TYPE, QueryBuilder.bindMarker()) .value(PREFERENCE, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewCommentEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(COMMENTS) .value(COMMENT_ID, QueryBuilder.bindMarker()) .value(USER_ID, QueryBuilder.bindMarker()) .value(FULL_NAME, QueryBuilder.bindMarker()) .value(THUMBNAIL_URL, QueryBuilder.bindMarker()) .value(COMMENT, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(IS_EDIT, QueryBuilder.bindMarker()) .value(LAST_EDIT_TIME, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewLikeEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(LIKES) .value(LIKE_ID, QueryBuilder.bindMarker()) .value(USER_ID, QueryBuilder.bindMarker()) .value(FULL_NAME, QueryBuilder.bindMarker()) .value(THUMBNAIL_URL, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewUserLikesEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(USER_LIKED_POSTS) .value(USER_ID, QueryBuilder.bindMarker()) .value(LIKE_ID, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewHashtagTimelineEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(HASHTAGGED_POSTS) .value(HASHTAG, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .value(VRE_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewHashtagCommentEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(HASHTAGGED_COMMENTS) .value(HASHTAG, QueryBuilder.bindMarker()) .value(COMMENT_ID, QueryBuilder.bindMarker()) .value(VRE_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewEmailInviteEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(EMAIL_INVITES) .value(EMAIL, QueryBuilder.bindMarker()) .value(VRE_ID, QueryBuilder.bindMarker()) .value(INVITE_ID, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewInviteEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(INVITES) .value(INVITE_ID, QueryBuilder.bindMarker()) .value(SENDER_USER_ID, QueryBuilder.bindMarker()) .value(VRE_ID, QueryBuilder.bindMarker()) .value(EMAIL, QueryBuilder.bindMarker()) .value(CONTROL_CODE, QueryBuilder.bindMarker()) .value(STATUS, QueryBuilder.bindMarker()) .value(TIMESTAMP, QueryBuilder.bindMarker()) .value(SENDER_FULL_NAME, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewVreInviteEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(VRE_INVITES) .value(VRE_ID, QueryBuilder.bindMarker()) .value(INVITE_ID, QueryBuilder.bindMarker()) .value(STATUS, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewaAttachEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(ATTACHMENTS) .value(ATTACH_ID, QueryBuilder.bindMarker()) .value(POST_ID, QueryBuilder.bindMarker()) .value(URI, QueryBuilder.bindMarker()) .value(NAME, QueryBuilder.bindMarker()) .value(DESCRIPTION, QueryBuilder.bindMarker()) .value(URI_THUMBNAIL, QueryBuilder.bindMarker()) .value(MIME_TYPE, QueryBuilder.bindMarker()) .build()); } private static PreparedStatement createNewUHashtagCounterEntry(CqlSession session){ return session.prepare( QueryBuilder.insertInto(HASHTAGS_COUNTER) .value(VRE_ID, QueryBuilder.bindMarker()) .value(HASHTAG, QueryBuilder.bindMarker()) .value(COUNT, QueryBuilder.bindMarker()) .build()); } /* * ********************** POSTS *********************** * */ private List insertIntoPosts(CqlSession session, Post post){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_HOST, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(EMAIL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LIKES_NO, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_DESCRIPTION, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt9 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(IS_APPLICATION_POST, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt10 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(ENTITY_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt11 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(PRIVACY, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt12 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(TYPE, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt13 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(URI_THUMBNAIL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt14 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(VRE_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt15 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(MULTI_FILE_UPLOAD, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt16 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt17 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(COMMENTS_NO, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt18 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_TITLE, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); if(post.getLinkHost()!=null){ boundStatements.add(prepStmt1.bind(UUID.fromString(post.getKey()), post.getLinkHost())); }if(post.getDescription()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(post.getKey()), post.getDescription())); }if(post.getEmail()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(post.getKey()), post.getEmail())); }if(post.getLikesNo()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(post.getKey()), Long.parseLong(post.getLikesNo()))); }if(post.getThumbnailURL()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(post.getKey()), post.getThumbnailURL())); }if(post.getLinkDescription()!=null){ boundStatements.add(prepStmt6.bind(UUID.fromString(post.getKey()), post.getLinkDescription())); }if(post.getTime()!=null){ boundStatements.add(prepStmt7.bind(UUID.fromString(post.getKey()), post.getTime().toInstant())); }if(post.getUri()!=null){ boundStatements.add(prepStmt8.bind(UUID.fromString(post.getKey()), post.getUri())); } boundStatements.add(prepStmt9.bind(UUID.fromString(post.getKey()), post.isApplicationPost())); if(post.getEntityId()!=null){ boundStatements.add(prepStmt10.bind(UUID.fromString(post.getKey()), post.getEntityId())); }if(post.getPrivacy()!=null){ boundStatements.add(prepStmt11.bind(UUID.fromString(post.getKey()), post.getPrivacy().toString())); }if(post.getType()!=null){ boundStatements.add(prepStmt12.bind(UUID.fromString(post.getKey()), post.getType().toString())); }if(post.getUriThumbnail()!=null){ boundStatements.add(prepStmt13.bind(UUID.fromString(post.getKey()), post.getUriThumbnail())); }if(post.getVreid()!=null){ boundStatements.add(prepStmt14.bind(UUID.fromString(post.getKey()), post.getVreid())); } boundStatements.add(prepStmt15.bind(UUID.fromString(post.getKey()), post.isMultiFileUpload())); if(post.getFullName()!=null){ boundStatements.add(prepStmt16.bind(UUID.fromString(post.getKey()), post.getFullName())); }if(post.getCommentsNo()!=null){ boundStatements.add(prepStmt17.bind(UUID.fromString(post.getKey()), Long.parseLong(post.getCommentsNo()))); }if(post.getLinkTitle()!=null){ boundStatements.add(prepStmt18.bind(UUID.fromString(post.getKey()), post.getLinkTitle())); } return boundStatements; } /** * @inheritDoc */ @Override public boolean saveUserPost(Post post) { CqlSession session = conn.getKeyspaceSession(); List boundStatements = insertIntoPosts(session, post); //boundStatements.forEach(stmt -> writeBatch.add(stmt)); //an entry in posts //an entry in the user Timeline BoundStatement stmt2 = createUserTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey())); boundStatements.add(stmt2); //an entry in the VRES Timeline iff vreid field is not empty if (post.getVreid() != null && post.getVreid().compareTo("") != 0){ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey())); boundStatements.add(stmt3); } BatchStatement writeBatch = getBatch().addAll(boundStatements); Boolean result = session.execute(writeBatch).wasApplied(); if (result){ _log.info("Wrote user post with id " + post.getKey()); } return result; } /** * @inheritDoc */ @Override public boolean saveUserPost(Post post, List attachments) { if (attachments != null && !attachments.isEmpty()) post.setMultiFileUpload(true); boolean savePostResult = saveUserPost(post); if (savePostResult) { _log.info("Post has been saved"); String postkey = post.getKey(); for (Attachment attachment : attachments) { boolean attachSaveResult = saveAttachmentEntry(postkey, attachment); if (!attachSaveResult) _log.info("Some of the attachments failed to be saved: " + attachment.getName()); } return true; } else return false; } /** * @inheritDoc */ @Override public boolean saveAppPost(Post post) { CqlSession session = conn.getKeyspaceSession(); List boundStatements = insertIntoPosts(session, post); //an entry in the Applications Timeline BoundStatement stmt2 = createAppTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey())); boundStatements.add(stmt2); //an entry in the VRES Timeline iff vreid field is not empty if (post.getVreid() != null && post.getVreid().compareTo("") != 0){ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey())); boundStatements.add(stmt3); } BatchStatement writeBatch = getBatch().addAll(boundStatements); boolean result = session.execute(writeBatch).wasApplied(); if (result) _log.info("Wrote app post with id " + post.getKey()); return result; } /** * @inheritDoc */ @Override public boolean saveAppPost(Post post, List attachments) { if (attachments != null && !attachments.isEmpty()) post.setMultiFileUpload(true); boolean savePostResult = saveAppPost(post); if (savePostResult) { String PostKey = post.getKey(); for (Attachment attachment : attachments) { boolean attachSaveResult = saveAttachmentEntry(PostKey, attachment); if (!attachSaveResult) _log.warn("Some of the attachments failed to be saved: " + attachment.getName()); } return true; } else return false; } /** * @inheritDoc */ @Override public boolean savePostToVRETimeline(String postKey, String vreid) throws PostIDNotFoundException { Post toCheck; try { toCheck = readPost(postKey); if (toCheck == null) throw new PostIDNotFoundException("Could not find Post with id " + postKey, postKey); } catch (Exception e) { e.printStackTrace(); return false; } CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(createVreTimelineEntry(session).bind(vreid, toCheck.getTime().toInstant(), UUID.fromString(toCheck.getKey()))); try{ boolean res = session.execute(writeBatch).wasApplied(); return res; }catch (Exception e) { e.printStackTrace(); return false; } } /** * @inheritDoc */ @Override public Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException { CqlSession session = conn.getKeyspaceSession(); Post post; try{ post = findPostById(postid, session).get(); } catch (Exception e){ e.printStackTrace(); return null; } return post; } /** * @inheritDoc */ @Override public List getRecentPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { Date now = new Date(); if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); ResultSet result = null; try { CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_TIMELINE_POSTS).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); result = session.execute(stmtFind.bind(userid)); } catch (Exception e) { e.printStackTrace(); } Listrows = result.all(); List toReturn = new ArrayList<>(); for (Row row: rows){ Instant postTime = row.getInstant(TIMESTAMP); if (Date.from(postTime).getTime() > timeInMillis){ try{ Post toCheck = readPost(row.getUuid(POST_ID).toString()); if (toCheck.getType() != PostType.DISABLED) toReturn.add(toCheck); } catch (ColumnNameNotFoundException | PrivacyLevelTypeNotFoundException | PostIDNotFoundException | PostTypeNotFoundException e) { throw new RuntimeException(e); } } } return toReturn; } /** * @inheritDoc */ @Override public boolean deletePost(String postid) throws PostIDNotFoundException, PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException { Post toDelete = readPost(postid); CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(updatePostEntry(session, TYPE).bind(PostType.DISABLED.toString(), UUID.fromString(toDelete.getKey()))); try { session.execute(writeBatch); } catch (Exception e) { _log.error("Delete Post ERROR for postid " + postid); return false; } _log.info("Delete Post OK"); return true; } /** * @inheritDoc */ @Override public List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { return getPostsByIds(getUserPostIds(userid)); } /** * @inheritDoc */ @Override public List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { return getPostsByIds(getAppPostIds(appid)); } /** * @inheritDoc * @throws Exception */ @Override public List getRecentCommentedPostsByUserAndDate(String userid, long timeInMillis) throws Exception { List toReturn = new ArrayList(); Date now = new Date(); if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); if(userid == null || userid.isEmpty()) throw new IllegalArgumentException("the userId parameter cannot be null/empty"); // get the last comments by the user (it is not needed to get them sorted) List lastComments = getRecentCommentsByUserAndDateBody(userid, timeInMillis, false); // evaluate unique posts' ids HashSet postIds = new HashSet(); for (Comment comment : lastComments) { String postId = comment.getPostid(); try{ if(!postIds.contains(postId)){ postIds.add(postId); toReturn.add(readPost(postId)); } }catch(Exception e){ _log.error("Unable to retrieve post with id " + postId, e); } } Collections.sort(toReturn, Collections.reverseOrder()); return toReturn; } /** * helper method that retrieve all the posts belongin to a list of Ids * @param postIds * @return * @throws ColumnNameNotFoundException * @throws PostIDNotFoundException * @throws PostTypeNotFoundException * @throws PrivacyLevelTypeNotFoundException */ private List getPostsByIds(List postIds) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException { ArrayList toReturn = new ArrayList(); for (String postid : postIds) { Post toAdd = readPost(postid); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) toReturn.add(toAdd); } return toReturn; } /** * helper method that retrieve all the post Ids belonging to a user * @param userid user identifier * @return simply return a list of user post UUID in chronological order from the oldest to the more recent */ private ArrayList getUserPostIds(String userid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_TIMELINE_POSTS).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } ArrayList toReturn = new ArrayList<>(); Listrows = result.all(); for(Row row: rows){ try { String postid = row.getUuid(POST_ID).toString(); toReturn.add(postid); } catch (RuntimeException e) { throw new RuntimeException(e); } } return toReturn; } /** * helper method that return whether the user * @param userid user identifier * @param postid the post identifier * @return true if the post id liked already */ private boolean isPostLiked(String userid, String postid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_LIKED_POSTS).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } Listrows = result.all(); for (Row row: rows){ if (row.getUuid(POST_ID).toString().equals(postid)){ return true; } } return false; } /** * helper method that retrieve all the post Ids belonging to an application * @param appid application identifier * @return simply return a list of app post UUID in chronological order from the oldest to the more recent */ private ArrayList getAppPostIds(String appid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(APP_TIMELINE_POSTS).all() .whereColumn(APP_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(appid)); } catch (Exception e){ e.printStackTrace(); } Listrows=result.all(); ArrayList toReturn=new ArrayList<>(); for(Row row: rows){ try { String postid = row.getUuid(POST_ID).toString(); toReturn.add(postid); } catch (RuntimeException e) { throw new RuntimeException(e); } } return toReturn; } @Override public List getAllPortalPrivacyLevelPosts() throws PostTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { //possible error index ArrayList toReturn = new ArrayList(); ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(POSTS).all() .whereColumn(PRIVACY).isEqualTo(QueryBuilder.bindMarker()) .limit(20) .build()); try { result = session.execute(stmtFind.bind(PrivacyLevel.PORTAL.toString())); } catch (Exception e){ e.printStackTrace(); } Listrows=result.all(); for (Row row: rows) { Post toAdd = readPostFromRow(row); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) toReturn.add(toAdd); } return toReturn; } /** * @inheritDoc */ @Override public List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList postIDs = getUserPostIds(userid); //check if quantity is greater than user posts quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; //need them in reverse order for (int i = postIDs.size()-1; i >= (postIDs.size()-quantity); i--) { Post toAdd = readPost(postIDs.get(i)); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { toReturn.add(toAdd); _log.trace("Read recent post: " + postIDs.get(i)); } else { _log.trace("Read and skipped post: " + postIDs.get(i) + " (Removed Post)"); quantity += 1; //increase the quantity in case of removed post //check if quantity is greater than user posts quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; } } return toReturn; } /** * @inheritDoc */ @Override public List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { return getPostsByIds(getVREPostIds(vreid)); } @Override public List getRecentPostsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList postIDs = getVREPostIds(vreid); //check if quantity is greater than user posts quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; //need them in reverse order for (int i = postIDs.size()-1; i >= (postIDs.size()-quantity); i--) { Post toAdd = readPost(postIDs.get(i)); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { toReturn.add(toAdd); _log.trace("Read recent Post: " + postIDs.get(i)); } else { _log.trace("Read and skipped Post: " + postIDs.get(i) + " (Removed Post) ."); quantity += 1; //increase the quantity in case of removed Post //check if quantity is greater than user Posts quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; } } return toReturn; } /** * @inheritDoc */ @Override public RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { if (from < 1) { throw new IllegalArgumentException("From must be greather than 0"); } ArrayList postsToReturn = new ArrayList(); ArrayList postIDs = getVREPostIds(vreid); //if from is greater than posts size return empty if (from >= postIDs.size()) { _log.warn("The starting point of the range is greather than the total number of posts for this timeline: " + from + " >= " + postIDs.size()); return new RangePosts(); } int rangeStart = postIDs.size()-from; int rangeEnd = rangeStart-quantity; //check that you reached the end if (rangeEnd<1) rangeEnd = 0; _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); //need them in reverse order int howMany = from; for (int i = rangeStart; i > rangeEnd; i--) { Post toAdd = readPost(postIDs.get(i)); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { postsToReturn.add(toAdd); _log.trace("Read recent post, i=" + i + " id= " + postIDs.get(i)); } else { _log.trace("Read and skipped post, i=" + i + " id=: " + postIDs.get(i) + " (Removed post) ."); rangeEnd -= 1; //increase the upTo in case of removed post //check if quantity is greater than user posts rangeEnd = (rangeEnd > 0) ? rangeEnd : 0; } howMany++; } _log.debug("AFTER: starting Point==" + rangeStart + " rangeEnd= " + rangeEnd); return new RangePosts(howMany+1, postsToReturn); } /** * get a list of user vre post UUIDs in chronological order from the oldest to the more recent * @param vreid vreid identifier (scope) * @return simply return a list of user vre post UUIDs in chronological order from the oldest to the more recent */ private ArrayList getVREPostIds(String vreid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(VRE_TIMELINE_POSTS).all() .whereColumn(VRE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(vreid)); } catch (Exception e){ e.printStackTrace(); } Listrows=result.all(); ArrayList toReturn=new ArrayList<>(); for(Row row: rows){ try { String postid = row.getUuid(POST_ID).toString(); toReturn.add(postid); } catch (RuntimeException e) { throw new RuntimeException(e); } } return toReturn; } /* * ********************** NOTIFICATIONS *********************** * */ private List insertIntoNotifications(CqlSession session, Notification notification){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(TYPE, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SUBJECT_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_FULL_NAME, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt9 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_THUMBNAIL_URL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt10 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(IS_READ, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); if(notification.getType()!=null){ boundStatements.add(prepStmt1.bind(UUID.fromString(notification.getKey()),notification.getType().toString())); } if(notification.getUserid()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(notification.getKey()), notification.getUserid())); } if(notification.getSubjectid()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(notification.getKey()), notification.getSubjectid())); } if(notification.getTime()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(notification.getKey()),notification.getTime().toInstant())); } if(notification.getDescription()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(notification.getKey()),notification.getDescription())); }if(notification.getUri()!=null){ boundStatements.add(prepStmt6.bind(UUID.fromString(notification.getKey()),notification.getUri())); }if(notification.getSenderid()!=null){ boundStatements.add(prepStmt7.bind(UUID.fromString(notification.getKey()),notification.getSenderid())); }if(notification.getSenderFullName()!=null){ boundStatements.add(prepStmt8.bind(UUID.fromString(notification.getKey()),notification.getSenderFullName())); }if(notification.getSenderThumbnail()!=null){ boundStatements.add(prepStmt9.bind(UUID.fromString(notification.getKey()),notification.getSenderThumbnail())); } boundStatements.add(prepStmt10.bind(UUID.fromString(notification.getKey()),notification.isRead())); return boundStatements; } /** * @inheritDoc */ @Override public boolean saveNotification(Notification n) { CqlSession session = conn.getKeyspaceSession(); List boundStatements = insertIntoNotifications(session, n); //an entry in the user Notifications Timeline BoundStatement stmt2 = createUserNotificationsEntry(session).bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey())); boundStatements.add(stmt2); // save key in the unread notifications column family too BoundStatement stmt3 = createUnreadNotificationEntry(session).bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey())); boundStatements.add(stmt3); BatchStatement writeBatch = getBatch().addAll(boundStatements); try{ boolean res = session.execute(writeBatch).wasApplied(); return res; }catch (Exception e){ e.printStackTrace(); return false; } } /** * @inheritDoc */ @Override public Notification readNotification(String notificationid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException { Notification toReturn = new Notification(); CqlSession session = conn.getKeyspaceSession(); try { toReturn = findNotById(notificationid, session).get(); } catch (Exception e) { e.printStackTrace(); } return toReturn; } /** * @inheritDoc */ @Override public boolean setNotificationRead(String notificationidToSet) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException { Notification toSet = readNotification(notificationidToSet); if (toSet == null) throw new NotificationIDNotFoundException("The specified notification to set Read with id: " + notificationidToSet + " does not exist"); CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch() //update the entry in notifications .add(updateNotificationEntry(session,IS_READ).bind(true,UUID.fromString(notificationidToSet))) // delete the notification's key from the unread notifications column family .add(deleteUnreadNotEntry(session).bind(toSet.getUserid(), toSet.getTime().toInstant())); // execute the operations try { boolean res = session.execute(writeBatch).wasApplied(); return res; } catch (Exception e) { _log.error("ERROR while setting Notification " + notificationidToSet + " to read."); return false; } } /** * * @param userid user identifier * @return simply return a list of user notifications UUID in chronological order from the oldest to the more recent */ private ArrayList getUserNotificationsIds(String userid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_NOTIFICATIONS).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } ArrayList toReturn = new ArrayList(); // Iterate rows and their columns Listrows=result.all(); for (Row row : rows) { toReturn.add(row.getUuid(NOT_ID).toString()); } return toReturn; } /** * Return a list of not read notifications by user userid (messages as well as other notifications) * @param userid user identifier * @return simply return a list of not read user notifications UUID in chronological order from the oldest to the more recent */ private ArrayList getUnreadUserNotificationsIds(String userid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_NOTIFICATIONS_UNREAD).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } ArrayList toReturn = new ArrayList(); // Iterate rows and their columns Listrows=result.all(); for (Row row : rows) { toReturn.add(row.getUuid(NOT_ID).toString()); } return toReturn; } /** * @inheritDoc */ @Override public List getAllNotificationByUser(String userid, int limit) throws NotificationTypeNotFoundException, ColumnNameNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList notificationsIDs = getUserNotificationsIds(userid); //check if quantity is greater than user posts limit = (limit > notificationsIDs.size()) ? notificationsIDs.size() : limit; //need them in reverse order for (int i = notificationsIDs.size()-1; i >= (notificationsIDs.size()-limit); i--) { Notification toAdd = null; try { toAdd = readNotification(notificationsIDs.get(i)); toReturn.add(toAdd); } catch (NotificationIDNotFoundException e) { _log.error("Notification not found id=" + notificationsIDs.get(i)); } } return toReturn; } /** * @inheritDoc */ @Override public List getUnreadNotificationsByUser(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList notificationsIDs = getUnreadUserNotificationsIds(userid); //need them in reverse order for (int i = notificationsIDs.size()-1; i >= 0; i--) { try{ toReturn.add(readNotification(notificationsIDs.get(i))); }catch(Exception e){ _log.error("Unable to read notification with key " + notificationsIDs.get(i)); } } return toReturn; } /** * @inheritDoc */ @Override public List getRangeNotificationsByUser(String userid,int from, int quantity) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException { if (from < 1) { throw new IllegalArgumentException("From must be greather than 0"); } ArrayList toReturn = new ArrayList(); ArrayList notificationsIDs = getUserNotificationsIds(userid); //if from is greater than posts size return empty if (from >= notificationsIDs.size()) { _log.warn("The starting point of the range is greather than the total number of posts for this timeline: " + from + " >= " + notificationsIDs.size()); return new ArrayList(); } int rangeStart = notificationsIDs.size()-from; int rangeEnd = rangeStart-quantity; //check that you reached the end if (rangeEnd<1) rangeEnd = 0; _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); //need them in reverse order for (int i = rangeStart; i > rangeEnd; i--) { Notification toAdd = readNotification(notificationsIDs.get(i)); toReturn.add(toAdd); } return toReturn; } /** * @inheritDoc */ @Override public boolean setAllNotificationReadByUser(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException { // get the list of unread notifications ArrayList notificationsIDs = getUnreadUserNotificationsIds(userid); for (int i = notificationsIDs.size()-1; i >= 0; i--) { try{ // set to read (and automatically remove from the unread column family) setNotificationRead(notificationsIDs.get(i)); } catch (NotificationIDNotFoundException e) { _log.error("Could not set read notification with id =" + notificationsIDs.get(i)); } } return true; } /** * @inheritDoc */ @Override public boolean checkUnreadNotifications(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException { ArrayList unreadNotifications = getUnreadUserNotificationsIds(userid); for (int i = unreadNotifications.size() - 1; i >= 0; i--) { Notification toAdd; try { toAdd = readNotification(unreadNotifications.get(i)); if (toAdd.getType() != NotificationType.MESSAGE) return true; } catch (NotificationIDNotFoundException e) { _log.error("Notification not found with id = " + unreadNotifications.get(i)); } } return false; } /** * @inheritDoc */ @Override public boolean checkUnreadMessagesNotifications(String userid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException { ArrayList unreadNotifications = getUnreadUserNotificationsIds(userid); for (int i = unreadNotifications.size() - 1; i >= 0; i--) { Notification toAdd; try { toAdd = readNotification(unreadNotifications.get(i)); if (toAdd.getType() == NotificationType.MESSAGE) return true; } catch (NotificationIDNotFoundException e) { _log.error("Notification not found with id = " + unreadNotifications.get(i)); } } return false; } /* * ********************** NOTIFICATION SETTINGS *********************** * */ /** * @inheritDoc */ @Override public List getUserNotificationChannels(String userid, NotificationType notificationType) throws NotificationChannelTypeNotFoundException, NotificationTypeNotFoundException { _log.info("Asking for Single Notification preference of " + userid + " Type: " + notificationType); List toReturn = new ArrayList(); NotificationChannelType[] toProcess = getUserNotificationPreferences(userid).get(notificationType); _log.info("size of user notification preferences" + toProcess.length); if (toProcess == null) { _log.info("Single Notification preference of " + userid + " Type: " + notificationType + " not existing ... creating default"); return createNewNotificationType(userid, notificationType); } else if (toProcess.length == 0) return toReturn; else for (int i = 0; i < toProcess.length; i++) { toReturn.add(toProcess[i]); } return toReturn; } /** * called when you add new notification types where the setting does not exist yet * please note: by default we set all notifications */ private List createNewNotificationType(String userid, NotificationType notificationType) { List toReturn = new ArrayList(); _log.info("Create new notification type"); CqlSession session = conn.getKeyspaceSession(); String valueToInsert = ""; NotificationChannelType[] wpTypes = NotificationChannelType.values(); for (int i = 0; i < wpTypes.length; i++) { valueToInsert += wpTypes[i]; if (i < wpTypes.length-1) valueToInsert += ","; toReturn.add(wpTypes[i]); //add the new added notification type } BatchStatement writeBatch = getBatch().add( createNotificationPreferenceEntry(session).bind(userid, notificationType.toString(), valueToInsert) ); boolean res = false; try{ res = session.execute(writeBatch).wasApplied(); } catch (Exception e){ e.printStackTrace(); } if (res) { _log.info("Set New Notification Setting for " + userid + " OK"); _log.info("toreturn:" + toReturn.toString()); return toReturn; } _log.info("empty list"); return new ArrayList(); //no notification if sth fails } /** * @inheritDoc */ @Override public boolean setUserNotificationPreferences(String userid, Map enabledChannels) { CqlSession session = conn.getKeyspaceSession(); List boundStatements = new ArrayList<>(); for (NotificationType nType : enabledChannels.keySet()) { String valueToInsert = ""; _log.info("Type: " + nType.toString()); int channelsNo = (enabledChannels.get(nType) != null) ? enabledChannels.get(nType).length : 0; for (int i = 0; i < channelsNo; i++) { _log.info(enabledChannels.get(nType)[i].toString()); valueToInsert += NotificationChannelType.valueOf(enabledChannels.get(nType)[i].toString()); if (i < channelsNo-1) valueToInsert += ","; } if (channelsNo == 0) { //in case no channels were selected valueToInsert = ""; _log.trace("No Channels selected for " + nType + " by " + userid); } boundStatements.add(createNotificationPreferenceEntry(session).bind(userid, nType.toString(), valueToInsert)); } BatchStatement writeBatch = getBatch().addAll(boundStatements); boolean overAllresult = session.execute(writeBatch).wasApplied(); if (overAllresult) _log.info("Set Notification Map for " + userid + " OK"); else _log.info("Set Notification Map for " + userid + " FAILED"); return overAllresult; } /** * @inheritDoc * * by default Workspace and Calendar Notifications are set to Portal */ @Override public Map getUserNotificationPreferences(String userid) throws NotificationTypeNotFoundException, NotificationChannelTypeNotFoundException { _log.trace("Asking for Notification preferences of " + userid); Map toReturn = new HashMap(); ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_NOTIFICATIONS_PREFERENCES).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } //if there are no settings for this user create an entry and put all of them at true List results = result.all(); if (results.isEmpty()) { _log.info("Userid " + userid + " settings not found, initiating its preferences..."); HashMap toCreate = new HashMap(); for (int i = 0; i < NotificationType.values().length; i++) { //TODO: Potential bug in NotificationType for workspace are refactored //create a map with all notification enabled except for workspace notifications (They start with WP_) it was the only quick way if (NotificationType.values()[i].toString().startsWith("WP_")) { NotificationChannelType[] wpTypes = { NotificationChannelType.PORTAL }; toCreate.put(NotificationType.values()[i], wpTypes); } else toCreate.put(NotificationType.values()[i], NotificationChannelType.values()); } setUserNotificationPreferences(userid, toCreate); //commit the map return toCreate; } else { _log.trace("Notification preferences Found for " + userid); for (Row row: results){ String[] channels = row.getString(PREFERENCE).split(","); if (channels != null && channels.length == 1 && channels[0].toString().equals("") ) { //it is empty, preference is set to no notification at all toReturn.put(getNotificationType(row.getString(TYPE)), new NotificationChannelType[0]); } else { NotificationChannelType[] toAdd = new NotificationChannelType[channels.length]; for (int i = 0; i < channels.length; i++) { if (channels[i].compareTo("") != 0) { toAdd[i] = (getChannelType(channels[i])); } } toReturn.put(getNotificationType(row.getString(TYPE)), toAdd); } } } return toReturn; } /* * ********************** COMMENTS *********************** * */ private List insertIntoComments(CqlSession session, Comment comment){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(COMMENT, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(IS_EDIT, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(LAST_EDIT_TIME, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); if(comment.getUserid()!=null){ boundStatements.add(prepStmt1.bind(UUID.fromString(comment.getKey()),comment.getUserid())); } if(comment.getFullName()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(comment.getKey()), comment.getFullName())); } if(comment.getThumbnailURL()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(comment.getKey()), comment.getThumbnailURL())); } if(comment.getText()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(comment.getKey()),comment.getText())); } if(comment.getPostid()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(comment.getKey()),UUID.fromString(comment.getPostid()))); }if(comment.getTime()!=null){ boundStatements.add(prepStmt6.bind(UUID.fromString(comment.getKey()),comment.getTime().toInstant())); } boundStatements.add(prepStmt7.bind(UUID.fromString(comment.getKey()),comment.isEdit())); if(comment.getLastEditTime()!=null){ boundStatements.add(prepStmt8.bind(UUID.fromString(comment.getKey()),comment.getLastEditTime().toInstant())); } return boundStatements; } /** * @inheritDoc */ @Override public boolean addComment(Comment comment) throws PostIDNotFoundException { Post toComment = null; if (comment == null) throw new NullArgumentException("Comment must be not null"); if (comment.getPostid() == null) throw new NullArgumentException("Comment post id must be not null"); String postid = comment.getPostid(); try { toComment = readPost(postid); if (toComment == null) throw new PostIDNotFoundException("Could not find Post with id " + postid + " to associate this comment", postid); } catch (Exception e) { e.printStackTrace(); return false; } _log.info("Writing comment : {}", comment.toString()); CqlSession session = conn.getKeyspaceSession(); List boundStatements = insertIntoComments(session, comment); BatchStatement writeBatch = getBatch().addAll(boundStatements); try { ResultSet res = session.execute(writeBatch); for (ExecutionInfo ex: res.getExecutionInfos()){ _log.info("Writing comment result errors: {}", ex.getErrors()); _log.info("Writing comment result payload: {}", ex.getIncomingPayload()); } _log.info("Writing comment result executed?: {}", res.wasApplied()); } catch (Exception e) { e.printStackTrace(); return false; } //update the comment count boolean updateCommentNoResult = updatePostCommentsCount(toComment, true); return updateCommentNoResult; } /** * @inheritDoc */ public Comment readCommentById(String commentId) throws CommentIDNotFoundException { Comment toReturn = null; ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(COMMENTS).all() .whereColumn(COMMENT_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(UUID.fromString(commentId))); toReturn = readCommentFromRow(result.one()); if (toReturn==null) { throw new CommentIDNotFoundException("The requested commentId: " + commentId + " is not existing"); } } catch (Exception e){ e.printStackTrace(); } return toReturn; } /** * @inheritDoc */ @Override public List getAllCommentByPost(String postid) { //possible error index List toReturn = new ArrayList(); ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare("SELECT * FROM comments WHERE postid=?"); try { result = session.execute(stmtFind.bind(UUID.fromString(postid))); Listrows=result.all(); for (Row row : rows) { Comment toAdd = readCommentFromRow(row); toReturn.add(toAdd); } } catch (Exception e){ e.printStackTrace(); } return toReturn; } /** * @inheritDoc * @throws Exception */ @Override public List getRecentCommentsByUserAndDate(final String userid, final long timeInMillis) throws Exception { final List commentsByUser; Date now = new Date(); if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); if(userid == null || userid.isEmpty()) throw new IllegalArgumentException("the userId parameter cannot be null/empty"); commentsByUser = getRecentCommentsByUserAndDateBody(userid, timeInMillis, true); return commentsByUser; } /** * Private method that allows also to specify if the returned list must be sorted or not * @param userid the user id * @param timeInMillis the initial time to consider * @param sort a boolean value to specify if the returned list must be sorted (from the most recent to the oldest comment) * @return a list of comments recently made by the user */ private List getRecentCommentsByUserAndDateBody(final String userid, final long timeInMillis, boolean sort){ //possible error final List commentsByUser = new ArrayList(); CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(COMMENTS) .all() .build()); try { result = session.execute(stmtFind.bind()); List results = result.all(); if (!results.isEmpty()){ results.parallelStream().forEach( row->{ if(row.getString(USER_ID).equals(userid)){ try{ Comment c = readCommentById(row.getUuid(COMMENT_ID).toString()); Post p = readPost(c.getPostid()); if(c.getTime().getTime() >= timeInMillis && (p.getType() == PostType.TWEET || p.getType() == PostType.SHARE || p.getType() == PostType.PUBLISH)) commentsByUser.add(c); }catch(Exception e){ _log.error("Unable to read comment with id" + row.getString(COMMENT_ID), e); } } } ); } } catch (Exception e){ e.printStackTrace(); } if(sort) Collections.sort(commentsByUser, Collections.reverseOrder()); return commentsByUser; } /** * @inheritDoc */ @Override public boolean editComment(Comment comment2Edit) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, PostIDNotFoundException { CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(updateCommentEntry(session, COMMENT).bind(comment2Edit.getText(), UUID.fromString(comment2Edit.getKey()))) .add(updateCommentEntry(session, IS_EDIT).bind(true, UUID.fromString(comment2Edit.getKey()))) .add(updateCommentEntry(session, LAST_EDIT_TIME).bind(new Date().toInstant(), UUID.fromString(comment2Edit.getKey()))); try { boolean res = session.execute(writeBatch).wasApplied(); _log.info("Comments update OK to: " + comment2Edit.getText()); return res; } catch (Exception e) { _log.error("Comments update NOT OK "); return false; } } /** * @inheritDoc */ @Override public boolean deleteComment(String commentid, String Postid) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, PostIDNotFoundException { Post toUpdate = readPost(Postid); boolean updateCommentNoResult = false; updateCommentNoResult = updatePostCommentsCount(toUpdate, false); if (updateCommentNoResult) { CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(deleteCommentEntry(session).bind(UUID.fromString(commentid))); try { session.execute(writeBatch); } catch (Exception e) { _log.error("Comment Delete FAILED for " + commentid + " from Post " + Postid); e.printStackTrace(); } _log.trace("Comment Deleted " + commentid + " from Post " + Postid); } return updateCommentNoResult; } private List insertIntoLikes(CqlSession session, Like like){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); if(like.getUserid()!=null){ boundStatements.add(prepStmt1.bind(UUID.fromString(like.getKey()),like.getUserid())); } if(like.getFullName()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(like.getKey()), like.getFullName())); } if(like.getThumbnailURL()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(like.getKey()), like.getThumbnailURL())); } if(like.getPostid()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(like.getKey()),UUID.fromString(like.getPostid()))); }if(like.getTime()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(like.getKey()),like.getTime().toInstant())); } return boundStatements; } /** * @inheritDoc */ @Override public boolean like(Like like) throws PostIDNotFoundException { Post toLike = null; if (like == null) throw new NullArgumentException("Like must be not null"); if (like.getPostid() == null) throw new NullArgumentException("Like post id must be not null"); String postId = like.getPostid(); try { toLike = readPost(postId); if (toLike == null) throw new PostIDNotFoundException("Could not find post with id " + postId + " to associate this like", postId); } catch (Exception e) { e.printStackTrace(); return false; } if (isPostLiked(like.getUserid(), postId)) { _log.info("User " + like.getUserid() + " already liked post " + postId); return true; } else { CqlSession session = conn.getKeyspaceSession(); // Inserting data //an entry in the post CF //and an entry in the UserLikesCF List boundStatements = insertIntoLikes(session,like); BoundStatement stmt2 = createNewUserLikesEntry(session).bind(like.getUserid(), UUID.fromString(like.getKey()), UUID.fromString(like.getPostid())); boundStatements.add(stmt2); //boundStatements.forEach(stmt->writeBatch.add(stmt)); BatchStatement writeBatch = getBatch().addAll(boundStatements); try { session.execute(writeBatch); } catch (Exception e) { e.printStackTrace(); return false; } return updatePostLikesCount(toLike, true); } } /** * @inheritDoc */ @Override public boolean unlike(String userid, String likeid, String postId) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, PostIDNotFoundException { Post toUpdate = readPost(postId); boolean updateLikeNoResult = false; updateLikeNoResult = updatePostLikesCount(toUpdate, false); //this remove 1 from the post CF LikeNO if (updateLikeNoResult) { CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(deleteLikeEntry(session).bind(UUID.fromString(likeid))) .add(deleteUserLikeEntry(session).bind(userid, UUID.fromString(likeid))); try { session.execute(writeBatch); } catch (Exception e) { _log.error("Like Delete FAILED for " + likeid + " from post " + postId); e.printStackTrace(); } _log.trace("Unlike ok for " + likeid + " from post " + postId); } return updateLikeNoResult; } /** * @inheritDoc */ @Override public List getAllLikedPostIdsByUser(String userid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(USER_LIKED_POSTS).all() .whereColumn(USER_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(userid)); } catch (Exception e){ e.printStackTrace(); } ArrayList toReturn = new ArrayList(); for (Row row: result){ toReturn.add(row.getUuid(POST_ID).toString()); } return toReturn; } /** * @inheritDoc */ @Override public List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, ColumnNameNotFoundException, PostIDNotFoundException { ArrayList toReturn = new ArrayList(); List likedPostIDs = getAllLikedPostIdsByUser(userid); //check if quantity is greater than user posts limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; //need them in reverse order for (int i = likedPostIDs.size()-1; i >= (likedPostIDs.size()-limit); i--) { Post toAdd = readPost(likedPostIDs.get(i)); if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { toReturn.add(toAdd); _log.trace("Read recent post: " + likedPostIDs.get(i)); } else { _log.trace("Read and skipped post: " + likedPostIDs.get(i) + " (Removed post)"); limit += 1; //increase the quantity in case of removed post //check if quantity is greater than user posts limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; } } return toReturn; } /** * @inheritDoc */ @Override public List getRecentLikedPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { List toReturn = new ArrayList<>(); Date now = new Date(); if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); if(userid == null || userid.isEmpty()) throw new IllegalArgumentException("the userId parameter cannot be null/empty"); // get the list of liked posts List likedPostsIdsByUser = getAllLikedPostIdsByUser(userid); if(likedPostsIdsByUser != null && !likedPostsIdsByUser.isEmpty()){ for(int i = likedPostsIdsByUser.size() - 1; i >= 0; i--){ String postid = likedPostsIdsByUser.get(i); try{ // retrieve the Post Post toCheck = readPost(postid); boolean isPostOk = (toCheck.getType() == PostType.TWEET || toCheck.getType() == PostType.SHARE || toCheck.getType() == PostType.PUBLISH); // retrieve the like of the user for the post if(isPostOk){ List likes = getAllLikesByPost(postid); for (Like like : likes) { if(like.getTime().getTime() >= timeInMillis && like.getUserid().equals(userid)) toReturn.add(toCheck); } } }catch(Exception e){ _log.error("Skipped post with id " + postid, e); } } } // please check consider that if a user made like recently to an old post, well it could happen that this // post comes first than a newer post in the toReturn list. Thus we need to sort it. Collections.sort(toReturn, Collections.reverseOrder()); return toReturn; } /** * @inheritDoc */ @Override public List getAllLikesByPost(String postid) { //possible error index List toReturn = new ArrayList(); ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(LIKES).all() .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(UUID.fromString(postid))); for (Row row: result) { Like toAdd = readLikeFromRow(row); toReturn.add(toAdd); } } catch (Exception e){ e.printStackTrace(); } return toReturn; } /* * ********************** HASHTAGS *********************** * */ /** * @inheritDoc */ @Override public boolean saveHashTags(String postId, String vreid, List hashtags) throws PostIDNotFoundException { Set noduplicatesHashtags = null; if (hashtags != null && !hashtags.isEmpty()) { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); boolean firstInsert = session.execute((createNewHashtagTimelineEntry(session).bind(lowerCaseHashtag, UUID.fromString(postId), vreid))).wasApplied(); boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, true); if (! (firstInsert && secondInsert)) { _log.error("saveHashTags: Could not save the hashtag(s)"); return false; } } return true; } /** * @inheritDoc */ @Override public boolean deleteHashTags(String postId, String vreid, List hashtags) throws PostIDNotFoundException { Set noduplicatesHashtags = null; if (hashtags != null && !hashtags.isEmpty()) { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); boolean firstDelete = session.execute(deleteHashtagEntry(session).bind(lowerCaseHashtag, UUID.fromString(postId))).wasApplied(); boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, false); if (! (firstDelete && secondInsert)) { _log.error("deleteHashTags: Could not delete the hashtag(s)"); return false; } } return true; } /** * @inheritDoc */ @Override public boolean saveHashTagsComment(String commentId, String vreid, List hashtags) throws CommentIDNotFoundException { Set noduplicatesHashtags = null; if (hashtags != null && !hashtags.isEmpty()) { noduplicatesHashtags = new HashSet(hashtags); } // Inserting datacommentIdcommentId CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); boolean firstInsert = session.execute(createNewHashtagCommentEntry(session).bind(hashtag, UUID.fromString(commentId), vreid)).wasApplied(); boolean secondInsert = false; if(firstInsert) secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, true); if (! (firstInsert && secondInsert)) { _log.error("saveHashTags: Could not save the hashtag(s)"); return false; } } return true; } /** * @inheritDoc */ @Override public boolean deleteHashTagsComment(String commentId, String vreid, List hashtags) throws CommentIDNotFoundException { Set noduplicatesHashtags = null; if (hashtags != null && !hashtags.isEmpty()) { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); boolean firstDelete = session.execute(deleteHashtagCommentEntry(session).bind(lowerCaseHashtag, UUID.fromString(commentId))).wasApplied(); if(firstDelete){ boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, false); if (!(firstDelete && secondInsert)) { _log.error("deleteHashTags: Could not delete the hashtag(s)"); return false; } }else{ _log.error("deleteHashTags: Could not delete the hashtag(s)"); return false; } } return true; } /** * @inheritDoc */ @Override public Map getVREHashtagsWithOccurrence(String vreid) { ResultSet result = null; CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(HASHTAGS_COUNTER).all() .whereColumn(VRE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(vreid)); } catch (Exception e){ e.printStackTrace(); } HashMap toReturn = new HashMap (); List rows = result.all(); // Iterate rows and their columns for (Row row : rows) { Integer curValue = (int) row.getLong(COUNT); if (curValue > 0) toReturn.put(row.getString(HASHTAG), curValue); } return toReturn; } /** * @inheritDoc */ @Override public Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp){ CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(HASHTAGS_COUNTER).all() .whereColumn(VRE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(vreid)); } catch (Exception e){ e.printStackTrace(); } HashMap toReturn = new HashMap (); List rows = result.all(); // Iterate rows and their columns for (Row row : rows) { // retrieve the posts list for this hashtag List posts = null; try{ posts = getVREPostsByHashtag(vreid, row.getString(HASHTAG)); }catch(Exception e){ _log.error("Unable to retrieve the list of posts for hashtag" + row.getString(HASHTAG) + " in vre " + vreid); continue; } if(posts.isEmpty()){ _log.info("There are no posts containing hashtag " + row.getString(HASHTAG) + " in vre " + vreid); continue; } // retrieve the most recent one among these posts Collections.sort(posts, Collections.reverseOrder()); if(posts.get(0).getTime().getTime() < timestamp){ continue; } // else.. int curValue = (int) row.getLong(COUNT); if (curValue > 0) toReturn.put(row.getString(HASHTAG), curValue); } return toReturn; } /** * @inheritDoc */ @Override public List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException, PostIDNotFoundException, ColumnNameNotFoundException { List toReturn = new ArrayList<>(); CqlSession session = conn.getKeyspaceSession(); ResultSet resultPost = null; PreparedStatement stmtFind1 = session.prepare(QueryBuilder .selectFrom(HASHTAGGED_POSTS).all() .whereColumn(HASHTAG) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { resultPost = session.execute(stmtFind1.bind(hashtag)); } catch (Exception e){ e.printStackTrace(); } PreparedStatement stmtFind2 = session.prepare(QueryBuilder .selectFrom(HASHTAGGED_COMMENTS).all() .whereColumn(HASHTAG) .isEqualTo(QueryBuilder.bindMarker()) .build()); ResultSet resultComment = null; try { resultComment = session.execute(stmtFind2.bind(hashtag)); } catch (Exception e){ e.printStackTrace(); } Set postIds = new HashSet<>(); // Iterate rows and their columns (post) ListrowsPost=resultPost.all(); for (Row row : rowsPost) { if (row.getString(VRE_ID).compareTo(vreid)==0) postIds.add(row.getUuid(POST_ID).toString()); } // Iterate rows and their columns (comments) ListrowsComment=resultComment.all(); for (Row row : rowsComment) { if (row.getString(VRE_ID).compareTo(vreid)==0){ try { Comment c = readCommentById(row.getUuid(COMMENT_ID).toString()); postIds.add(c.getPostid()); } catch (CommentIDNotFoundException e) { _log.warn("Failed to fetch comment with id " + row.getString(COMMENT_ID)); } } } toReturn = getPostsByIds(new ArrayList<>(postIds)); return toReturn; } /* * ********************** Invites *********************** * */ private List insertIntoInvites(CqlSession session, Invite invite){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(SENDER_USER_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(VRE_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(EMAIL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(CONTROL_CODE, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(STATUS, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(SENDER_FULL_NAME, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); if(invite.getSenderUserId()!=null){ boundStatements.add(prepStmt1.bind(UUID.fromString(invite.getKey()),invite.getSenderUserId())); } if(invite.getVreid()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(invite.getKey()), invite.getVreid())); } if(invite.getInvitedEmail()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(invite.getKey()), invite.getInvitedEmail())); } if(invite.getControlCode()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(invite.getKey()),invite.getControlCode())); } if(invite.getStatus()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(invite.getKey()),invite.getStatus().toString())); } if(invite.getTime()!=null){ boundStatements.add(prepStmt6.bind(UUID.fromString(invite.getKey()),invite.getTime().toInstant())); } if(invite.getSenderFullName()!=null){ boundStatements.add(prepStmt7.bind(UUID.fromString(invite.getKey()),invite.getSenderFullName())); } return boundStatements; } /** * common part to save a invite * @param invite * @return the partial mutation batch instance */ private List initSaveInvite(Invite invite, CqlSession session) { List boundStatements = insertIntoInvites(session, invite); if (invite == null) throw new NullArgumentException("Invite instance is null"); return boundStatements; } /** * @inheritDoc */ @Override public String isExistingInvite(String vreid, String email) { CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind1 = session.prepare(QueryBuilder .selectFrom(EMAIL_INVITES).all() .whereColumn(EMAIL) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind1.bind(email)); } catch (Exception e){ e.printStackTrace(); } // Iterate rows and their columns Listrows=result.all(); for (Row row : rows) { if (row.getString(VRE_ID).compareTo(vreid)==0) return row.getUuid(INVITE_ID).toString(); } return null; } /** * @inheritDoc */ @Override public InviteOperationResult saveInvite(Invite invite) throws AddressException { if (invite == null) throw new NullArgumentException("Invite instance is null"); String email = invite.getInvitedEmail(); if (! verifyEmail(email)) throw new AddressException("Email is not valid ->" + email); if (invite.getVreid() == null || invite.getVreid().equals("")) throw new NullArgumentException("VREId is null or empty"); _log.debug("isExistingInvite? " + invite.getInvitedEmail() + " in " + invite.getVreid()); if (isExistingInvite(invite.getVreid(), invite.getInvitedEmail()) != null) return InviteOperationResult.ALREADY_INVITED; _log.debug("Invite not found, proceed to save it ..."); CqlSession session = conn.getKeyspaceSession(); List boundStatements = initSaveInvite(invite, session); //an entry in the VRE Invites boundStatements.add(createNewVreInviteEntry(session).bind(invite.getVreid(), UUID.fromString(invite.getKey()), InviteStatus.PENDING.toString())); //an entry in the EMAIL Invites boundStatements.add(createNewEmailInviteEntry(session).bind(email, invite.getVreid(), UUID.fromString(invite.getKey()))); BatchStatement writeBatch = getBatch().addAll(boundStatements); boolean result = session.execute(writeBatch).wasApplied(); return result ? InviteOperationResult.SUCCESS : InviteOperationResult.FAILED; } /** * @inheritDoc */ @Override public Invite readInvite(String inviteid) throws InviteIDNotFoundException, InviteStatusNotFoundException { Invite toReturn = null; CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(INVITES).all() .whereColumn(INVITE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(UUID.fromString(inviteid))); toReturn = readAInviteFromRow(result.one()); if (toReturn == null) { throw new InviteStatusNotFoundException("The requested inviteid: " + inviteid + " is not existing"); } //toReturn = readAInviteFromRow(result.all().get(0)); } catch (Exception e){ e.printStackTrace(); } return toReturn; } /** * helper method that retrieve all the Invites belonging to a list of Ids * @param inviteIds the lisf of invites UUID * @return all the invites belonging to a list of Ids * @throws InviteIDNotFoundException * @throws InviteStatusNotFoundException */ private List getInvitesById(List inviteIds) throws InviteIDNotFoundException, InviteStatusNotFoundException { ArrayList toReturn = new ArrayList(); for (String inviteid : inviteIds) toReturn.add(readInvite(inviteid)); return toReturn; } /** * @inheritDoc * @throws InviteStatusNotFoundException */ @Override public boolean setInviteStatus(String vreid, String email, InviteStatus status) throws InviteIDNotFoundException, InviteStatusNotFoundException { String inviteid = isExistingInvite(vreid, email); Invite toSet = readInvite(inviteid); if (toSet == null) throw new InviteIDNotFoundException("The specified invite to set with id: " + inviteid + " does not exist"); CqlSession session = conn.getKeyspaceSession(); BatchStatement writeBatch = getBatch().add(updateInviteEntry(session, STATUS).bind(status.toString(), UUID.fromString(inviteid))) .add(updateVreInviteEntry(session, STATUS).bind(status.toString(), vreid, UUID.fromString(inviteid))); try { session.execute(writeBatch); } catch (Exception e) { _log.error("ERROR while setting Invite " + inviteid + " to " + status.toString()); return false; } _log.trace("Invite Status Set to " + status.toString() + " OK"); return true; } /** * @inheritDoc */ @Override public List getInvitedEmailsByVRE(String vreid, InviteStatus... status) throws InviteIDNotFoundException, InviteStatusNotFoundException{ CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(VRE_INVITES).all() .whereColumn(VRE_ID) .isEqualTo(QueryBuilder.bindMarker()) .build()); try { result = session.execute(stmtFind.bind(vreid)); } catch (Exception e){ e.printStackTrace(); } ArrayList invitesIds = new ArrayList(); // Iterate rows and their columns Listrows=result.all(); for (Row row : rows) { if (status != null) { for (int i = 0; i < status.length; i++) { if (row.getString(STATUS).compareTo(status[i].toString())==0) invitesIds.add(row.getUuid(INVITE_ID).toString()); } } else { invitesIds.add(row.getUuid(INVITE_ID).toString()); } } return getInvitesById(invitesIds); } /** * @inheritDoc */ @Override public List getAttachmentsByPostId(String postId) throws PostIDNotFoundException { //index error Post toCheck = null; try { toCheck = readPost(postId); if (toCheck == null) throw new PostIDNotFoundException("Could not find post with id " + postId, postId); } catch (Exception e) { e.printStackTrace(); return null; } List toReturn = new ArrayList(); CqlSession session = conn.getKeyspaceSession(); PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(ATTACHMENTS).all() .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) .build()); ResultSet result = null; try { result = session.execute(stmtFind.bind(UUID.fromString(postId))); // Iterate rows and their columns Listrows=result.all(); for (Row row : rows) { _log.trace("Reading attachment if post=" + row.getUuid(POST_ID).toString()); Attachment toAdd = readAttachmentFromRow(row); toReturn.add(toAdd); } } catch (Exception e) { e.printStackTrace(); return null; } return toReturn; } /** * @inheritDoc */ @Override public void closeConnection() { conn.closeConnection(); } /* * ********************** Helper methods *********************** * */ private List insertIntoAttachments(CqlSession session, Attachment attachment, String postId){ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(NAME, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(URI_THUMBNAIL, QueryBuilder.bindMarker()).build()); PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(MIME_TYPE, QueryBuilder.bindMarker()).build()); List boundStatements = new ArrayList<>(); boundStatements.add(prepStmt1.bind(UUID.fromString(attachment.getId()),UUID.fromString(postId))); if(attachment.getUri()!=null){ boundStatements.add(prepStmt2.bind(UUID.fromString(attachment.getId()), attachment.getUri())); } if(attachment.getName()!=null){ boundStatements.add(prepStmt3.bind(UUID.fromString(attachment.getId()), attachment.getName())); } if(attachment.getDescription()!=null){ boundStatements.add(prepStmt4.bind(UUID.fromString(attachment.getId()),attachment.getDescription())); } if(attachment.getThumbnailURL()!=null){ boundStatements.add(prepStmt5.bind(UUID.fromString(attachment.getId()),attachment.getThumbnailURL())); } if(attachment.getMimeType()!=null){ boundStatements.add(prepStmt6.bind(UUID.fromString(attachment.getId()),attachment.getMimeType())); } return boundStatements; } /** * @inheritDoc */ @Override public boolean saveAttachmentEntry(String postId, Attachment toSave) { // Inserting data CqlSession session = conn.getKeyspaceSession(); //an entry in the Attachment CF try { List boundStatements = insertIntoAttachments(session, toSave, postId); BatchStatement writeBatch = getBatch().addAll(boundStatements); ResultSet res = session.execute(writeBatch); _log.info(res.getExecutionInfos().toString()); _log.info(""+res.wasApplied()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * simply return an enum representing the privacy level * @return correct enum representing the privacy level * @throws NotificationChannelTypeNotFoundException * @throws PostTypeNotFoundException */ private NotificationChannelType getChannelType(String channelName) throws NotificationChannelTypeNotFoundException { if (channelName.compareTo("PORTAL") == 0) return NotificationChannelType.PORTAL; else if (channelName.compareTo("EMAIL") == 0) return NotificationChannelType.EMAIL; else if (channelName.compareTo("TWITTER") == 0) return NotificationChannelType.TWITTER; else throw new NotificationChannelTypeNotFoundException("The Notification Channel Type was not recognized should be one of " + NotificationChannelType.values() + " asked for: " + channelName); } /** * simply return an enum representing the privacy level * @param privacyLevel . * @return correct enum representing the privacy level * @throws PostTypeNotFoundException */ private static PrivacyLevel getPrivacyLevel(String privacyLevel) throws PrivacyLevelTypeNotFoundException { if (privacyLevel.compareTo("CONNECTION") == 0) return PrivacyLevel.CONNECTION; else if (privacyLevel.compareTo("PRIVATE") == 0) return PrivacyLevel.PRIVATE; else if (privacyLevel.compareTo("PUBLIC") == 0) return PrivacyLevel.PUBLIC; else if (privacyLevel.compareTo("VRES") == 0) return PrivacyLevel.VRES; else if (privacyLevel.compareTo("SINGLE_VRE") == 0) return PrivacyLevel.SINGLE_VRE; else if (privacyLevel.compareTo("PORTAL") == 0) return PrivacyLevel.PORTAL; else throw new PrivacyLevelTypeNotFoundException("The Privacy Level was not recognized should be one of " + PrivacyLevel.values() + " asked for: " + privacyLevel); } /** * simply return an enum representing the post type * @param type . * @return correct enum representing the post type * @throws PostTypeNotFoundException . */ private static PostType getPostType(String type) throws PostTypeNotFoundException { if (type.compareTo("TWEET") == 0) { return PostType.TWEET; } else if (type.compareTo("JOIN") == 0) { return PostType.JOIN; } else if (type.compareTo("PUBLISH") == 0) { return PostType.PUBLISH; } else if (type.compareTo("SHARE") == 0) { return PostType.SHARE; } else if (type.compareTo("ACCOUNTING") == 0) { return PostType.ACCOUNTING; } else if (type.compareTo("DISABLED") == 0) { return PostType.DISABLED; } else throw new PostTypeNotFoundException("The post Type was not recognized should be one of " + PostType.values() + " asked for: " + type); } /** * simply return an enum representing the invite status type * @param type . * @return correct enum representing the post type * @throws InviteStatusNotFoundException . */ private static InviteStatus getInviteStatusType(String type) throws InviteStatusNotFoundException { switch (type) { case "PENDING": return InviteStatus.PENDING; case "ACCEPTED": return InviteStatus.ACCEPTED; case "REJECTED": return InviteStatus.REJECTED; case "RETRACTED": return InviteStatus.RETRACTED; default: throw new InviteStatusNotFoundException("The Invite Status was not recognized should be one of " + InviteStatus.values() + " asked for: " + type); } } /** * simply return an enum representing the post type * @param type . * @return correct enum representing the post type * @throws NotificationTypeNotFoundException . */ private static NotificationType getNotificationType(String type) throws NotificationTypeNotFoundException { if (type.compareTo("WP_FOLDER_SHARE") == 0) { return NotificationType.WP_FOLDER_SHARE; } else if (type.compareTo("WP_FOLDER_UNSHARE") == 0) { return NotificationType.WP_FOLDER_UNSHARE; } else if (type.compareTo("WP_ADMIN_UPGRADE") == 0) { return NotificationType.WP_ADMIN_UPGRADE; } else if (type.compareTo("WP_ADMIN_DOWNGRADE") == 0) { return NotificationType.WP_ADMIN_DOWNGRADE; } else if (type.compareTo("WP_FOLDER_RENAMED") == 0) { return NotificationType.WP_FOLDER_RENAMED; } else if (type.compareTo("WP_FOLDER_ADDEDUSER") == 0) { return NotificationType.WP_FOLDER_ADDEDUSER; } else if (type.compareTo("WP_FOLDER_REMOVEDUSER") == 0) { return NotificationType.WP_FOLDER_REMOVEDUSER; } else if (type.compareTo("WP_ITEM_DELETE") == 0) { return NotificationType.WP_ITEM_DELETE; } else if (type.compareTo("WP_ITEM_UPDATED") == 0) { return NotificationType.WP_ITEM_UPDATED; } else if (type.compareTo("WP_ITEM_NEW") == 0) { return NotificationType.WP_ITEM_NEW; } else if (type.compareTo("WP_ITEM_RENAMED") == 0) { return NotificationType.WP_ITEM_RENAMED; } else if (type.compareTo("OWN_COMMENT") == 0) { return NotificationType.OWN_COMMENT; } else if (type.compareTo("COMMENT") == 0) { return NotificationType.COMMENT; } else if (type.compareTo("MENTION") == 0) { return NotificationType.MENTION; } else if (type.compareTo("LIKE") == 0) { return NotificationType.LIKE; } else if (type.compareTo("CALENDAR_ADDED_EVENT") == 0) { return NotificationType.CALENDAR_ADDED_EVENT; } else if (type.compareTo("CALENDAR_UPDATED_EVENT") == 0) { return NotificationType.CALENDAR_UPDATED_EVENT; } else if (type.compareTo("CALENDAR_DELETED_EVENT") == 0) { return NotificationType.CALENDAR_DELETED_EVENT; } else if (type.compareTo("CALENDAR_ADDED_EVENT") == 0) { return NotificationType.CALENDAR_ADDED_EVENT; } else if (type.compareTo("CALENDAR_UPDATED_EVENT") == 0) { return NotificationType.CALENDAR_UPDATED_EVENT; } else if (type.compareTo("CALENDAR_DELETED_EVENT") == 0) { return NotificationType.CALENDAR_DELETED_EVENT; } else if (type.compareTo("MESSAGE") == 0) { return NotificationType.MESSAGE; } else if (type.compareTo("POST_ALERT") == 0) { return NotificationType.POST_ALERT; } else if (type.compareTo("REQUEST_CONNECTION") == 0) { return NotificationType.REQUEST_CONNECTION; } else if (type.compareTo("JOB_COMPLETED_NOK") == 0) { return NotificationType.JOB_COMPLETED_NOK; } else if (type.compareTo("JOB_COMPLETED_OK") == 0) { return NotificationType.JOB_COMPLETED_OK; } else if (type.compareTo("DOCUMENT_WORKFLOW_EDIT") == 0) { return NotificationType.DOCUMENT_WORKFLOW_EDIT; } else if (type.compareTo("DOCUMENT_WORKFLOW_VIEW") == 0) { return NotificationType.DOCUMENT_WORKFLOW_VIEW; } else if (type.compareTo("DOCUMENT_WORKFLOW_FORWARD_STEP_COMPLETED_OWNER") == 0) { return NotificationType.DOCUMENT_WORKFLOW_FORWARD_STEP_COMPLETED_OWNER; } else if (type.compareTo("DOCUMENT_WORKFLOW_STEP_FORWARD_PEER") == 0) { return NotificationType.DOCUMENT_WORKFLOW_STEP_FORWARD_PEER; } else if (type.compareTo("DOCUMENT_WORKFLOW_STEP_REQUEST_TASK") == 0) { return NotificationType.DOCUMENT_WORKFLOW_STEP_REQUEST_TASK; } else if (type.compareTo("DOCUMENT_WORKFLOW_USER_FORWARD_TO_OWNER") == 0) { return NotificationType.DOCUMENT_WORKFLOW_USER_FORWARD_TO_OWNER; } else if (type.compareTo("DOCUMENT_WORKFLOW_FIRST_STEP_REQUEST_INVOLVMENT") == 0) { return NotificationType.DOCUMENT_WORKFLOW_FIRST_STEP_REQUEST_INVOLVMENT; } else if (type.compareTo("TDM_TAB_RESOURCE_SHARE") == 0) { return NotificationType.TDM_TAB_RESOURCE_SHARE; } else if (type.compareTo("TDM_RULE_SHARE") == 0) { return NotificationType.TDM_RULE_SHARE; } else if (type.compareTo("TDM_TEMPLATE_SHARE") == 0) { return NotificationType.TDM_TEMPLATE_SHARE; } else if (type.compareTo("CAT_ITEM_SUBMITTED") == 0) { return NotificationType.CAT_ITEM_SUBMITTED; } else if (type.compareTo("CAT_ITEM_REJECTED") == 0) { return NotificationType.CAT_ITEM_REJECTED; } else if (type.compareTo("CAT_ITEM_PUBLISHED") == 0) { return NotificationType.CAT_ITEM_PUBLISHED; } else if (type.compareTo("CAT_ITEM_UPDATED") == 0) { return NotificationType.CAT_ITEM_UPDATED; } else if (type.compareTo("CAT_ITEM_DELETE") == 0) { return NotificationType.CAT_ITEM_DELETE; } else if (type.compareTo("GENERIC") == 0) { return NotificationType.GENERIC; } else throw new NotificationTypeNotFoundException("The Notification Type was not recognized should be one of " + NotificationType.values() + " asked for: " + type); } /** * * @param time in milliseconds * @return a Date object */ private Date getDateFromTimeInMillis(String time) { Long timeInMillis = Long.parseLong(time); Calendar toSet = Calendar.getInstance(); toSet.setTimeInMillis(timeInMillis); return toSet.getTime(); } /** * update the post by incrementing or decrementing by (1) the CommentsNo * used when adding or removing a comment to a post * @param toUpdate the postId * @param increment set true if you want to add 1, false to subtract 1. */ private boolean updatePostCommentsCount(Post toUpdate, boolean increment) { int newCount = 0; try { int current = Integer.parseInt(toUpdate.getCommentsNo()); newCount = increment ? current+1 : current-1; } catch (NumberFormatException e) { _log.error("Comments Number found is not a number: " + toUpdate.getCommentsNo()); } CqlSession session = conn.getKeyspaceSession(); //an entry in the Post CF try { session.execute(updatePostEntry(session, COMMENTS_NO).bind((long) newCount, UUID.fromString(toUpdate.getKey()))); } catch (Exception e) { _log.error("CommentsNo update NOT OK "); return false; } _log.info("CommentsNo update OK to: " + newCount); return true; } /** * update the post by incrementing or decrementing by (1) the LikesNo * used when adding or removing a comment to a post * @param toUpdate the postId * @param increment set true if you want to add 1, false to subtract 1. */ private boolean updatePostLikesCount(Post toUpdate, boolean increment) { int newCount = 0; try { int current = Integer.parseInt(toUpdate.getLikesNo()); newCount = increment ? current+1 : current-1; } catch (NumberFormatException e) { _log.error("Likes Number found is not a number: " + toUpdate.getLikesNo()); } CqlSession session = conn.getKeyspaceSession(); //an entry in the post CF try { session.execute(updatePostEntry(session, LIKES_NO).bind((long)newCount, UUID.fromString(toUpdate.getKey()))); } catch (Exception e) { _log.error("LikesNo update NOT OK "); return false; } _log.info("LikesNo update OK to: " + newCount); return true; } /** * update the hashtag count by incrementing or decrementing it by (1) * used when adding or removing a hashtag in a post * @param vreid the vreid * @param hashtag the hashtag * @param increment set true if you want to add 1, false to subtract 1. */ private boolean updateVREHashtagCount(String vreid, String hashtag, boolean increment) { Map vreHashtags = getVREHashtagsWithOccurrence(vreid); //if the hashtag not yet exist int newCount = 0; if (!vreHashtags.containsKey(hashtag)) { newCount = 1; } else { try { int current = vreHashtags.get(hashtag); newCount = increment ? current+1 : current-1; } catch (NumberFormatException e) { _log.error("Hashtag Number found is not a number: " + newCount); } } _log.debug("Updating counter for " + hashtag + " to " + newCount); CqlSession session = conn.getKeyspaceSession(); BoundStatement stmt; if (existRecordbyCompId(session, HASHTAG, VRE_ID, hashtag, vreid, HASHTAGS_COUNTER)){ stmt = session.prepare(QueryBuilder.update(HASHTAGS_COUNTER) .setColumn(COUNT, QueryBuilder.bindMarker()) .whereColumn(HASHTAG).isEqualTo(QueryBuilder.bindMarker()) .whereColumn(VRE_ID).isEqualTo(QueryBuilder.bindMarker()) .build()).bind((long)newCount, hashtag, vreid); } else{ stmt = createNewUHashtagCounterEntry(session).bind(vreid, hashtag, (long)newCount); } BatchStatement writeBatch = getBatch().add(stmt); try { session.execute(writeBatch); } catch (Exception e) { _log.error("Hashtag Count update NOT OK "); return false; } _log.debug("Hashtag Count update OK to: " + newCount); return true; } /** * verify an email address * @param email * @return true or false */ private boolean verifyEmail(String email) { boolean isValid = false; try { InternetAddress internetAddress = new InternetAddress(email); internetAddress.validate(); isValid = true; } catch (AddressException e) { _log.error("Validation Exception Occurred for email: " + email); } return isValid; } @Override public List getAllVREIds(){ Set ids = new HashSet<>(); CqlSession session = conn.getKeyspaceSession(); ResultSet result = null; PreparedStatement stmtFind = session.prepare(QueryBuilder .selectFrom(VRE_TIMELINE_POSTS).column(VRE_ID).all() .build()); try { result = session.execute(stmtFind.bind()); } catch (Exception e){ e.printStackTrace(); } Listrows=result.all(); for (Row row : rows) { ids.add(row.getString(VRE_ID)); } List toReturn = new ArrayList<>(); toReturn.addAll(ids); _log.debug("VRE ids are " + ids); return toReturn; } }