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
*/
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
ColumnFamilyDefinition cfDefConn = getDynamicCFDef(DBCassandraAstyanaxImpl.CONNECTIONS);
@ -214,6 +223,8 @@ public class CassandraClusterConnection {
.addColumnFamily(cfDefFeeds)
.addColumnFamily(cfDefComments)
.addColumnFamily(cfDefLikes)
.addColumnFamily(cfDefInvites)
.addColumnFamily(cfDefAttachments)
.addColumnFamily(cfDefConn)
.addColumnFamily(cfDefPendingConn)
.addColumnFamily(cfDefVRETimeline)

View File

@ -9,11 +9,13 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
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.Feed;
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 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 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>(
@ -162,7 +166,10 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
StringSerializer.get(), // Key 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
@ -331,7 +338,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
.putColumn("LinkTitle", feed.getLinkTitle(), null)
.putColumn("LinkDescription", feed.getLinkDescription(), null)
.putColumn("LinkHost", feed.getLinkHost(), null)
.putColumn("IsApplicationFeed", feed.isApplicationFeed(), null);
.putColumn("IsApplicationFeed", feed.isApplicationFeed(), null)
.putColumn("multiFileUpload", feed.isMultiFileUpload(), null);
return m;
}
/**
@ -353,6 +361,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
}
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}
*/
@ -438,6 +466,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue());
toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue());
toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue());
toReturn.setMultiFileUpload(columns.getColumnByName("multiFileUpload").getBooleanValue());
} catch (ConnectionException e) {
e.printStackTrace();
@ -452,8 +481,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
public List<Feed> getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException {
Date now = new Date();
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;
try {
result = conn.getKeyspace().prepareQuery(cf_UserTline)
@ -1331,7 +1360,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
}
return toReturn;
}
/**
* {@inheritDoc}
*/
@ -1351,7 +1380,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
_log.info("Comments update OK to: " + comment2Edit.getText());
return true;
}
/**
* {@inheritDoc}
*/
@ -1651,8 +1680,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
*
*/
/**
* common part to save a feed
* @param feed
* common part to save a invite
* @param invite
* @return the partial mutation batch instance
*/
private MutationBatch initSaveInvite(Invite invite) {
@ -1660,7 +1689,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
throw new NullArgumentException("Invite instance is null");
// Inserting data
MutationBatch m = conn.getKeyspace().prepareMutationBatch();
//an entry in the feed CF
//an entry in the invite CF
m.withRow(cf_Invites, invite.getKey().toString())
.putColumn("SenderUserId", invite.getSenderUserId(), null)
.putColumn("Vreid", invite.getVreid(), null)
@ -1837,6 +1866,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
********************** 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
@ -2170,7 +2224,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore {
}
return isValid;
}

View File

@ -1,9 +1,17 @@
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.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.FeedIDNotFoundException;
import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException;
@ -12,6 +20,11 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
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 {
private static DBCassandraAstyanaxImpl store;
@ -26,60 +39,51 @@ public class DatabookCassandraTest {
System.out.println("End");
}
@Test
public void testFeedNumberPerUser() {
String userid = "massimiliano.assante";
List<Feed> feeds = null;
int numComment = 0;
long init = System.currentTimeMillis();
try {
feeds = store.getAllFeedsByUser(userid);
for (Feed feed : feeds) {
List<Comment> comments = store.getAllCommentByFeed(feed.getKey());
for (Comment comment : comments) {
numComment ++;
}
}
} catch (PrivacyLevelTypeNotFoundException | FeedTypeNotFoundException
| ColumnNameNotFoundException | FeedIDNotFoundException e) {
// TODO Auto-generated catch block
System.err.println(e.toString());
}
long end = System.currentTimeMillis();
System.err.println("retrieved " + feeds.size() + " and " + numComment + " in " + (end - init) + "ms");
}
// @Test
// public void testFeedNumberPerUser() {
// String userid = "massimiliano.assante";
//
// List<Feed> feeds = null;
// int numComment = 0;
// long init = System.currentTimeMillis();
// try {
// feeds = store.getAllFeedsByUser(userid);
//
// for (Feed feed : feeds) {
// List<Comment> comments = store.getAllCommentByFeed(feed.getKey());
//
//
// for (Comment comment : comments) {
// numComment ++;
// }
// }
//
// } catch (PrivacyLevelTypeNotFoundException | FeedTypeNotFoundException
// | ColumnNameNotFoundException | FeedIDNotFoundException e) {
// // TODO Auto-generated catch block
// System.err.println(e.toString());
// }
// long end = System.currentTimeMillis();
// System.err.println("retrieved " + feeds.size() + " and " + numComment + " in " + (end - init) + "ms");
// }
// @Test
// public void testInvites() {
// String controlCode = UUID.randomUUID().toString();
// String vreid = "/gcube/devsec/devVRE";
// String email = "ciccio@gmail.com";
//
// InviteStatus statusToLookfor = InviteStatus.ACCEPTED;
//
// Invite invite = new Invite(UUID.randomUUID().toString(), "andrea.rossi", vreid, email, controlCode, InviteStatus.PENDING, new Date(), "Andrea Rossi");
// try {
// InviteOperationResult result = store.saveInvite(invite);
// System.out.println(result);
// String inviteid = store.isExistingInvite(vreid, email);
//// System.out.println(store.readInvite(inviteid));
//// store.setInviteStatus(vreid, email, InviteStatus.ACCEPTED);
//// 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
public void testAttachments() {
Attachment a1 = new Attachment("www1", "gattino1", "description1", "http://cdn.tuttozampe.com/wp-content/uploads/2010/09/ipoglicemia-gatto.jpg");
Attachment a2 = new Attachment("www2", "name2", "description2", "http://www.gcomegatto.it/wp-content/uploads/2015/01/09gatto.jpg");
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>();
toPass.add(a1);
toPass.add(a2);
Feed feed = new Feed(UUID.randomUUID().toString(), FeedType.TWEET, "massimiliano.assante", new Date(), "/gcube/devsec/devVRE",
"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,
"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);
feed.setMultiFileUpload(true);
assertTrue(store.saveUserFeed(feed, toPass));
}
// @Test
// 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()
// .put("default_validation_class", "UTF8Type")
// .put("key_validation_class", "UTF8Type")
// .put("comparator_type", "UTF8Type")
// .build());
//
// } catch (ConnectionException e) {
// e.printStackTrace();
// /**
// * use exclusively to add a new (Static) CF to a keyspace
// */
// @Test
// public void addAttachmentStaticColumnFamilies() {
// ColumnFamily<String, String> CF_INVITES = ColumnFamily.newColumnFamily(DBCassandraAstyanaxImpl.ATTACHMENTS, StringSerializer.get(), StringSerializer.get());
//
// try {
// 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;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
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.Feed;
import org.gcube.portal.databook.shared.Invite;
@ -65,6 +64,11 @@ public interface DatabookStore {
* @return true if everything went fine
*/
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
* @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 linkHost;
boolean applicationFeed;
/**
* this boolean indicates that the attachments to the post are > 1
*/
boolean multiFileUpload;
/**
* default constructor
*/
@ -123,7 +127,7 @@ public class Feed implements Serializable, Comparable<Feed> {
public Feed(String key, FeedType type, String entityId, Date time,
String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy,
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();
this.key = key;
this.type = type;
@ -143,6 +147,7 @@ public class Feed implements Serializable, Comparable<Feed> {
this.linkTitle = linkTitle;
this.linkHost = linkHost;
this.applicationFeed = applicationFeed;
this.multiFileUpload = multiFileUpload;
}
/**
*
@ -293,6 +298,12 @@ public class Feed implements Serializable, Comparable<Feed> {
public void setApplicationFeed(boolean applicationFeed) {
this.applicationFeed = applicationFeed;
}
public boolean isMultiFileUpload() {
return multiFileUpload;
}
public void setMultiFileUpload(boolean multiFileUpload) {
this.multiFileUpload = multiFileUpload;
}
@Override
public String toString() {
return "Feed [key=" + key + ", type=" + type + ", entityId=" + entityId
@ -302,6 +313,9 @@ public class Feed implements Serializable, Comparable<Feed> {
+ fullName + ", email=" + email + ", thumbnailURL="
+ thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo="
+ likesNo + ", linkTitle=" + linkTitle + ", linkDescription="
+ linkDescription + ", linkHost=" + linkHost + "]";
+ linkDescription + ", linkHost=" + linkHost
+ ", applicationFeed=" + applicationFeed
+ ", multiFileUpload=" + multiFileUpload + "]";
}
}