partiallly implemnted support for multi attachments

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portal/social-networking-library@122236 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Massimiliano Assante 2016-01-14 17:37:03 +00:00
parent 75a8352ba5
commit 630a26d821
7 changed files with 248 additions and 87 deletions

Binary file not shown.

View File

@ -192,6 +192,15 @@ public class CassandraClusterConnection {
* define Likes CF with FeedId as secondary index * define Likes CF with FeedId as secondary index
*/ */
ColumnFamilyDefinition cfDefLikes = getStaticCFDef(DBCassandraAstyanaxImpl.LIKES, "Feedid"); ColumnFamilyDefinition cfDefLikes = getStaticCFDef(DBCassandraAstyanaxImpl.LIKES, "Feedid");
/**
* define Invites CF with SenderUserId as secondary index
*/
ColumnFamilyDefinition cfDefInvites = getStaticCFDef(DBCassandraAstyanaxImpl.INVITES, "SenderUserId");
/**
* define Attachments CF with FeedId as secondary index
*/
ColumnFamilyDefinition cfDefAttachments = getStaticCFDef(DBCassandraAstyanaxImpl.ATTACHMENTS, "Feedid");
//get dynamic column families, act as auxiliary indexes //get dynamic column families, act as auxiliary indexes
ColumnFamilyDefinition cfDefConn = getDynamicCFDef(DBCassandraAstyanaxImpl.CONNECTIONS); ColumnFamilyDefinition cfDefConn = getDynamicCFDef(DBCassandraAstyanaxImpl.CONNECTIONS);
@ -214,6 +223,8 @@ public class CassandraClusterConnection {
.addColumnFamily(cfDefFeeds) .addColumnFamily(cfDefFeeds)
.addColumnFamily(cfDefComments) .addColumnFamily(cfDefComments)
.addColumnFamily(cfDefLikes) .addColumnFamily(cfDefLikes)
.addColumnFamily(cfDefInvites)
.addColumnFamily(cfDefAttachments)
.addColumnFamily(cfDefConn) .addColumnFamily(cfDefConn)
.addColumnFamily(cfDefPendingConn) .addColumnFamily(cfDefPendingConn)
.addColumnFamily(cfDefVRETimeline) .addColumnFamily(cfDefVRETimeline)

View File

@ -9,11 +9,13 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import org.apache.commons.lang.NullArgumentException; import org.apache.commons.lang.NullArgumentException;
import org.gcube.portal.databook.shared.Attachment;
import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.FeedType; import org.gcube.portal.databook.shared.FeedType;
@ -82,7 +84,9 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
public static final String HASHTAGS_COUNTER = "HashtagsCounter"; // count the hashtags per group and type public static final String HASHTAGS_COUNTER = "HashtagsCounter"; // count the hashtags per group and type
public static final String HASHTAGGED_FEEDS = "HashtaggedFeeds"; // contains hashtags per type associated with vre and feed public static final String HASHTAGGED_FEEDS = "HashtaggedFeeds"; // contains hashtags per type associated with vre and feed
public static final String VRE_INVITES = "VREInvites"; //contains the emails that were invited per VRE public static final String VRE_INVITES = "VREInvites"; //contains the emails that were invited per VRE
public static final String EMAIL_INVITES = "EMAILInvites"; //contains the list of invitation per email public static final String EMAIL_INVITES = "EMAILInvites"; //contains the list of invitation per email
public static final String ATTACHMENTS = "Attachments"; //contains the list of all the attachments in a feed
public static final String FEED_ATTACHMENTS = "FeedAttachments"; //contains the list of all the attachments for a given feed (dynamic CF)
private static ColumnFamily<String, String> cf_Connections = new ColumnFamily<String, String>( private static ColumnFamily<String, String> cf_Connections = new ColumnFamily<String, String>(
@ -162,7 +166,10 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
StringSerializer.get(), // Key Serializer StringSerializer.get(), // Key Serializer
StringSerializer.get()); // Column Serializer StringSerializer.get()); // Column Serializer
protected static ColumnFamily<String, String> cf_Attachments = new ColumnFamily<String, String>(
ATTACHMENTS, // Column Family Name
StringSerializer.get(), // Key Serializer
StringSerializer.get()); // Column Serializer
/** /**
* connection instance * connection instance
@ -331,7 +338,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
.putColumn("LinkTitle", feed.getLinkTitle(), null) .putColumn("LinkTitle", feed.getLinkTitle(), null)
.putColumn("LinkDescription", feed.getLinkDescription(), null) .putColumn("LinkDescription", feed.getLinkDescription(), null)
.putColumn("LinkHost", feed.getLinkHost(), null) .putColumn("LinkHost", feed.getLinkHost(), null)
.putColumn("IsApplicationFeed", feed.isApplicationFeed(), null); .putColumn("IsApplicationFeed", feed.isApplicationFeed(), null)
.putColumn("multiFileUpload", feed.isMultiFileUpload(), null);
return m; return m;
} }
/** /**
@ -353,6 +361,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
} }
return execute(m); return execute(m);
} }
/**
* {@inheritDoc}
*/
@Override
public boolean saveUserFeed(Feed feed, List<Attachment> attachments) {
if (attachments != null && !attachments.isEmpty())
feed.setMultiFileUpload(true);
boolean saveFeedResult = saveUserFeed(feed);
if (saveFeedResult) {
String feedKey = feed.getKey();
for (Attachment attachment : attachments) {
boolean attachSaveResult = saveAttachmentEntry(feedKey, attachment);
if (!attachSaveResult)
_log.warn("Some of the attachments failed to me saved: " + attachment.getName());
}
return true;
}
else return false;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -438,6 +466,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue()); toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue());
toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue()); toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue());
toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue()); toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue());
toReturn.setMultiFileUpload(columns.getColumnByName("multiFileUpload").getBooleanValue());
} catch (ConnectionException e) { } catch (ConnectionException e) {
e.printStackTrace(); e.printStackTrace();
@ -452,8 +481,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
public List<Feed> getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { public List<Feed> getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException {
Date now = new Date(); Date now = new Date();
if (timeInMillis > now.getTime()) if (timeInMillis > now.getTime())
throw new IllegalArgumentException("the timeInMillis must be before today"); throw new IllegalArgumentException("the timeInMillis must be before today");
OperationResult<Rows<String, String>> result = null; OperationResult<Rows<String, String>> result = null;
try { try {
result = conn.getKeyspace().prepareQuery(cf_UserTline) result = conn.getKeyspace().prepareQuery(cf_UserTline)
@ -1331,7 +1360,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
} }
return toReturn; return toReturn;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -1351,7 +1380,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
_log.info("Comments update OK to: " + comment2Edit.getText()); _log.info("Comments update OK to: " + comment2Edit.getText());
return true; return true;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -1651,8 +1680,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
* *
*/ */
/** /**
* common part to save a feed * common part to save a invite
* @param feed * @param invite
* @return the partial mutation batch instance * @return the partial mutation batch instance
*/ */
private MutationBatch initSaveInvite(Invite invite) { private MutationBatch initSaveInvite(Invite invite) {
@ -1660,7 +1689,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
throw new NullArgumentException("Invite instance is null"); throw new NullArgumentException("Invite instance is null");
// Inserting data // Inserting data
MutationBatch m = conn.getKeyspace().prepareMutationBatch(); MutationBatch m = conn.getKeyspace().prepareMutationBatch();
//an entry in the feed CF //an entry in the invite CF
m.withRow(cf_Invites, invite.getKey().toString()) m.withRow(cf_Invites, invite.getKey().toString())
.putColumn("SenderUserId", invite.getSenderUserId(), null) .putColumn("SenderUserId", invite.getSenderUserId(), null)
.putColumn("Vreid", invite.getVreid(), null) .putColumn("Vreid", invite.getVreid(), null)
@ -1837,6 +1866,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
********************** Helper methods *********************** ********************** Helper methods ***********************
* *
*/ */
/**
* @param feedId the feedId to which the attachment is attached
* @param toSave the instance to save
* @return true if the attachemnt entry is saved in the Attachments CF
*/
private boolean saveAttachmentEntry(String feedId, Attachment toSave) {
// Inserting data
MutationBatch m = conn.getKeyspace().prepareMutationBatch();
//an entry in the Attachment CF
String attachmentID = UUID.randomUUID().toString();
m.withRow(cf_Attachments, attachmentID)
.putColumn("feedId", feedId, null)
.putColumn("uri", toSave.getUri(), null)
.putColumn("name", toSave.getName(), null)
.putColumn("description",toSave.getDescription(), null)
.putColumn("thumbnailURL",toSave.getThumbnailURL(), null);
try {
m.execute();
} catch (ConnectionException e) {
e.printStackTrace();
return false;
}
return true;
}
/** /**
* simply return an enum representing the privacy level * simply return an enum representing the privacy level
@ -2170,7 +2224,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
} }
return isValid; return isValid;
} }

View File

@ -1,9 +1,17 @@
package org.gcube.portal.databook.server; package org.gcube.portal.databook.server;
import java.util.List; import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.gcube.portal.databook.shared.Attachment;
import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.FeedType;
import org.gcube.portal.databook.shared.PrivacyLevel;
import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException; import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException; import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException;
@ -12,6 +20,11 @@ import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.serializers.StringSerializer;
public class DatabookCassandraTest { public class DatabookCassandraTest {
private static DBCassandraAstyanaxImpl store; private static DBCassandraAstyanaxImpl store;
@ -26,60 +39,51 @@ public class DatabookCassandraTest {
System.out.println("End"); System.out.println("End");
} }
@Test // @Test
public void testFeedNumberPerUser() { // public void testFeedNumberPerUser() {
String userid = "massimiliano.assante"; // String userid = "massimiliano.assante";
//
List<Feed> feeds = null; // List<Feed> feeds = null;
int numComment = 0; // int numComment = 0;
long init = System.currentTimeMillis(); // long init = System.currentTimeMillis();
try { // try {
feeds = store.getAllFeedsByUser(userid); // feeds = store.getAllFeedsByUser(userid);
//
for (Feed feed : feeds) { // for (Feed feed : feeds) {
List<Comment> comments = store.getAllCommentByFeed(feed.getKey()); // List<Comment> comments = store.getAllCommentByFeed(feed.getKey());
//
//
for (Comment comment : comments) { // for (Comment comment : comments) {
numComment ++; // numComment ++;
} // }
} // }
//
} catch (PrivacyLevelTypeNotFoundException | FeedTypeNotFoundException // } catch (PrivacyLevelTypeNotFoundException | FeedTypeNotFoundException
| ColumnNameNotFoundException | FeedIDNotFoundException e) { // | ColumnNameNotFoundException | FeedIDNotFoundException e) {
// TODO Auto-generated catch block // // TODO Auto-generated catch block
System.err.println(e.toString()); // System.err.println(e.toString());
} // }
long end = System.currentTimeMillis(); // long end = System.currentTimeMillis();
System.err.println("retrieved " + feeds.size() + " and " + numComment + " in " + (end - init) + "ms"); // System.err.println("retrieved " + feeds.size() + " and " + numComment + " in " + (end - init) + "ms");
} // }
// @Test @Test
// public void testInvites() { public void testAttachments() {
// String controlCode = UUID.randomUUID().toString(); Attachment a1 = new Attachment("www1", "gattino1", "description1", "http://cdn.tuttozampe.com/wp-content/uploads/2010/09/ipoglicemia-gatto.jpg");
// String vreid = "/gcube/devsec/devVRE"; Attachment a2 = new Attachment("www2", "name2", "description2", "http://www.gcomegatto.it/wp-content/uploads/2015/01/09gatto.jpg");
// String email = "ciccio@gmail.com"; Attachment a3 = new Attachment("www3", "name3", "description3", "http://cdn.tuttozampe.com/wp-content/uploads/2010/09/ipoglicemia-gatto.jpg");
// List<Attachment> toPass = new ArrayList<Attachment>();
// InviteStatus statusToLookfor = InviteStatus.ACCEPTED; toPass.add(a1);
// toPass.add(a2);
// Invite invite = new Invite(UUID.randomUUID().toString(), "andrea.rossi", vreid, email, controlCode, InviteStatus.PENDING, new Date(), "Andrea Rossi");
// try {
// InviteOperationResult result = store.saveInvite(invite); Feed feed = new Feed(UUID.randomUUID().toString(), FeedType.TWEET, "massimiliano.assante", new Date(), "/gcube/devsec/devVRE",
// System.out.println(result); "http://www.gcomegatto.it/wp-content/uploads/2015/01/09gatto.jpg", "http://www.gcomegatto.it/wp-content/uploads/2015/01/09gatto.jpg", "This feed has attachments (gattini) ", PrivacyLevel.SINGLE_VRE,
// String inviteid = store.isExistingInvite(vreid, email); "Massimiliano Assante", "massimiliano.assante@isti.cnr.it", "http://cdn.tuttozampe.com/wp-content/uploads/2010/09/ipoglicemia-gatto.jpg", "Gattino", "linkDesc", "http://www.gcomegatto.it/wp-content/uploads/2015/01/09gatto.jpg", false);
//// System.out.println(store.readInvite(inviteid)); feed.setMultiFileUpload(true);
//// store.setInviteStatus(vreid, email, InviteStatus.ACCEPTED); assertTrue(store.saveUserFeed(feed, toPass));
//// System.out.println(store.readInvite(inviteid));
// System.out.println("Looking for all invites in " + vreid + " with status " + statusToLookfor); }
// List<Invite> invites = store.getInvitedEmailsByVRE(vreid, statusToLookfor, InviteStatus.PENDING);
// for (Invite invite2 : invites) {
// System.out.println(invite2);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// }
// @Test // @Test
// public void testHashTag() { // public void testHashTag() {
@ -116,26 +120,26 @@ public class DatabookCassandraTest {
// //
// } // }
// /**
// * use exclusively to add a new (Static) CF to a keyspace
// */
// @Test
// public void addInvitesStaticColumnFamilies() {
// ColumnFamily<String, String> CF_INVITES = ColumnFamily.newColumnFamily(DBCassandraAstyanaxImpl.INVITES, StringSerializer.get(), StringSerializer.get());
// //
// try { // /**
// new CassandraClusterConnection(false).getKeyspace().createColumnFamily(CF_INVITES, ImmutableMap.<String, Object>builder() // * use exclusively to add a new (Static) CF to a keyspace
// .put("default_validation_class", "UTF8Type") // */
// .put("key_validation_class", "UTF8Type") // @Test
// .put("comparator_type", "UTF8Type") // public void addAttachmentStaticColumnFamilies() {
// .build()); // ColumnFamily<String, String> CF_INVITES = ColumnFamily.newColumnFamily(DBCassandraAstyanaxImpl.ATTACHMENTS, StringSerializer.get(), StringSerializer.get());
// //
// } catch (ConnectionException e) { // try {
// e.printStackTrace(); // new CassandraClusterConnection(false).getKeyspace().createColumnFamily(CF_INVITES, ImmutableMap.<String, Object>builder()
// .put("default_validation_class", "UTF8Type")
// .put("key_validation_class", "UTF8Type")
// .put("comparator_type", "UTF8Type")
// .build());
//
// } catch (ConnectionException e) {
// e.printStackTrace();
// }
// System.out.println("addStaticColumnFamily END");
// } // }
// System.out.println("addInvitesStaticColumnFamily END");
// }
// /** // /**

View File

@ -1,12 +1,11 @@
package org.gcube.portal.databook.server; package org.gcube.portal.databook.server;
import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
import org.apache.commons.lang.NullArgumentException; import org.gcube.portal.databook.shared.Attachment;
import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.Feed;
import org.gcube.portal.databook.shared.Invite; import org.gcube.portal.databook.shared.Invite;
@ -65,6 +64,11 @@ public interface DatabookStore {
* @return true if everything went fine * @return true if everything went fine
*/ */
boolean saveUserFeed(Feed feed); boolean saveUserFeed(Feed feed);
/**
* save a Feed instance in the store having more than one attachment
* @return true if everything went fine
*/
boolean saveUserFeed(Feed feed, List<Attachment> attachments);
/** /**
* delete a Feed from the store * delete a Feed from the store
* @throws FeedIDNotFoundException * @throws FeedIDNotFoundException

View File

@ -0,0 +1,74 @@
package org.gcube.portal.databook.shared;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Attachment implements Serializable {
private String uri;
private String name;
private String description;
private String thumbnailURL;
/**
* @param uri where you can download the file from
* @param name the name of the attached file
* @param description the description of the attached file
* @param thumbnailURL the URL of the image representing the attached file
*/
public Attachment(String uri, String name,
String description, String thumbnailURL) {
super();
this.uri = uri;
this.name = name;
this.description = description;
this.thumbnailURL = thumbnailURL;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getThumbnailURL() {
return thumbnailURL;
}
public void setThumbnailURL(String thumbnailURL) {
this.thumbnailURL = thumbnailURL;
}
@Override
public String toString() {
return "Attachment [uri=" + uri + ", name=" + name + ", description="
+ description + ", thumbnailURL=" + thumbnailURL + "]";
}
}

View File

@ -29,6 +29,10 @@ public class Feed implements Serializable, Comparable<Feed> {
private String linkDescription; private String linkDescription;
private String linkHost; private String linkHost;
boolean applicationFeed; boolean applicationFeed;
/**
* this boolean indicates that the attachments to the post are > 1
*/
boolean multiFileUpload;
/** /**
* default constructor * default constructor
*/ */
@ -123,7 +127,7 @@ public class Feed implements Serializable, Comparable<Feed> {
public Feed(String key, FeedType type, String entityId, Date time, public Feed(String key, FeedType type, String entityId, Date time,
String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy, String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy,
String fullName, String email, String thumbnailURL, String commentsNo, String fullName, String email, String thumbnailURL, String commentsNo,
String likesNo, String linkTitle, String linkDescription, String linkHost, boolean applicationFeed) { String likesNo, String linkTitle, String linkDescription, String linkHost, boolean applicationFeed, boolean multiFileUpload) {
super(); super();
this.key = key; this.key = key;
this.type = type; this.type = type;
@ -143,6 +147,7 @@ public class Feed implements Serializable, Comparable<Feed> {
this.linkTitle = linkTitle; this.linkTitle = linkTitle;
this.linkHost = linkHost; this.linkHost = linkHost;
this.applicationFeed = applicationFeed; this.applicationFeed = applicationFeed;
this.multiFileUpload = multiFileUpload;
} }
/** /**
* *
@ -293,6 +298,12 @@ public class Feed implements Serializable, Comparable<Feed> {
public void setApplicationFeed(boolean applicationFeed) { public void setApplicationFeed(boolean applicationFeed) {
this.applicationFeed = applicationFeed; this.applicationFeed = applicationFeed;
} }
public boolean isMultiFileUpload() {
return multiFileUpload;
}
public void setMultiFileUpload(boolean multiFileUpload) {
this.multiFileUpload = multiFileUpload;
}
@Override @Override
public String toString() { public String toString() {
return "Feed [key=" + key + ", type=" + type + ", entityId=" + entityId return "Feed [key=" + key + ", type=" + type + ", entityId=" + entityId
@ -302,6 +313,9 @@ public class Feed implements Serializable, Comparable<Feed> {
+ fullName + ", email=" + email + ", thumbnailURL=" + fullName + ", email=" + email + ", thumbnailURL="
+ thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo=" + thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo="
+ likesNo + ", linkTitle=" + linkTitle + ", linkDescription=" + likesNo + ", linkTitle=" + linkTitle + ", linkDescription="
+ linkDescription + ", linkHost=" + linkHost + "]"; + linkDescription + ", linkHost=" + linkHost
+ ", applicationFeed=" + applicationFeed
+ ", multiFileUpload=" + multiFileUpload + "]";
} }
} }