From 79aba2e2fdf5541ed18beecc76763c56a98dba93 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Sat, 28 Oct 2023 01:38:25 +0200 Subject: [PATCH] Datastax Driver Fully Implemented - Partially Tested --- CHANGELOG.md | 3 + META-INF/MANIFEST.MF | 2 +- pom.xml | 85 +- .../server/CassandraClusterConnection.java | 703 ++-- .../server/DBCassandraAstyanaxImpl.java | 3433 ----------------- .../server/DBCassandraDatastaxImpl.java | 2539 ++++++++++++ .../server/DatabookCassandraTest.java | 9 +- .../portal/databook/server/DatabookStore.java | 325 +- .../databook/server/RunningCluster.java | 55 +- .../gcube/portal/databook/server/Schema.java | 68 + .../gcube/portal/databook/server/Tester.java | 45 + .../portal/databook/shared/Attachment.java | 18 +- .../gcube/portal/databook/shared/Comment.java | 44 +- .../portal/databook/shared/EnhancedFeed.java | 24 +- .../gcube/portal/databook/shared/Feed.java | 322 -- .../portal/databook/shared/FeedType.java | 19 - .../gcube/portal/databook/shared/Invite.java | 37 +- .../gcube/portal/databook/shared/Like.java | 33 +- .../portal/databook/shared/Notification.java | 219 +- .../gcube/portal/databook/shared/Post.java | 103 +- .../portal/databook/shared/RangeFeeds.java | 40 - .../shared/ex/FeedTypeNotFoundException.java | 8 - ...tion.java => PostIDNotFoundException.java} | 4 +- .../shared/ex/PostTypeNotFoundException.java | 8 + 24 files changed, 3608 insertions(+), 4538 deletions(-) delete mode 100644 src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java create mode 100644 src/main/java/org/gcube/portal/databook/server/DBCassandraDatastaxImpl.java create mode 100644 src/main/java/org/gcube/portal/databook/server/Schema.java create mode 100644 src/main/java/org/gcube/portal/databook/server/Tester.java delete mode 100644 src/main/java/org/gcube/portal/databook/shared/Feed.java delete mode 100644 src/main/java/org/gcube/portal/databook/shared/FeedType.java delete mode 100644 src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java delete mode 100644 src/main/java/org/gcube/portal/databook/shared/ex/FeedTypeNotFoundException.java rename src/main/java/org/gcube/portal/databook/shared/ex/{FeedIDNotFoundException.java => PostIDNotFoundException.java} (58%) create mode 100644 src/main/java/org/gcube/portal/databook/shared/ex/PostTypeNotFoundException.java diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb5b9a..4b50a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.0.0] - 2023-10-24 + - Feature #25901, add Cassandra 4.1.3 java client + ## [v1.18.0] - 2022-09-20 - Feature #23891, The (wrongly named) Feed class has been changed to Post, all the methods have been changed accordingly and the old one set as deprecated diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index 5e94951..ed49fc3 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Class-Path: +Main-Class: org.gcube.portal.databook.server.Tester diff --git a/pom.xml b/pom.xml index d7074d7..4347bf6 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.gcube.portal social-networking-library - 1.18.0 + 2.0.0-SNAPSHOT gCube Social Networking Library The gCube Social Networking Library is the 'bridge' between your gCube Applications and the social networking facilities. @@ -28,57 +28,39 @@ 2.8.1 UTF-8 UTF-8 + 4.13.0 + 1.2.3 - - - - org.gcube.distribution - maven-portal-bom - 3.6.4 - pom - import - - - + + com.datastax.oss + java-driver-query-builder + ${cassandra.driver.oss.version} + + + com.datastax.oss + java-driver-mapper-runtime + ${cassandra.driver.oss.version} + com.google gwt-jsonmaker - - - com.netflix.astyanax - astyanax-core - provided - - - org.slf4j - log4j-over-slf4j - - - - - com.netflix.astyanax - astyanax-thrift - provided - - - com.netflix.astyanax - astyanax-cassandra - provided + 1.2.1 org.gcube.resources.discovery ic-client + [1.0.5-SNAPSHOT,2.0.0-SNAPSHOT) org.gcube.common.portal portal-manager - provided + [2.4.2-SNAPSHOT,3.0.0-SNAPSHOT) com.sun.mail javax.mail - provided + 1.5.2 junit @@ -89,15 +71,21 @@ com.google.gwt gwt-user ${gwtVersion} - provided org.slf4j slf4j-log4j12 + 1.6.4 org.slf4j slf4j-api + 1.6.4 + + + commons-lang + commons-lang + 2.6 @@ -135,6 +123,31 @@ true + + org.apache.maven.plugins + maven-assembly-plugin + 3.4.2 + + + + true + org.gcube.portal.databook.server.Tester + + + + jar-with-dependencies + + + + + assemble-all + package + + single + + + + diff --git a/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java b/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java index 7627070..25927bd 100644 --- a/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java +++ b/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java @@ -1,33 +1,25 @@ package org.gcube.portal.databook.server; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.net.InetSocketAddress; +import java.time.Duration; +import java.util.List; + +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.CqlSessionBuilder; +import com.datastax.oss.driver.api.core.config.DefaultDriverOption; +import com.datastax.oss.driver.api.core.config.DriverConfigLoader; +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.metadata.Metadata; +import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; +import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.api.querybuilder.SchemaBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.netflix.astyanax.AstyanaxContext; -import com.netflix.astyanax.Cluster; -import com.netflix.astyanax.Keyspace; -import com.netflix.astyanax.connectionpool.NodeDiscoveryType; -import com.netflix.astyanax.connectionpool.OperationResult; -import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; -import com.netflix.astyanax.connectionpool.impl.ConnectionPoolConfigurationImpl; -import com.netflix.astyanax.connectionpool.impl.ConnectionPoolType; -import com.netflix.astyanax.connectionpool.impl.CountingConnectionPoolMonitor; -import com.netflix.astyanax.ddl.ColumnDefinition; -import com.netflix.astyanax.ddl.ColumnFamilyDefinition; -import com.netflix.astyanax.ddl.KeyspaceDefinition; -import com.netflix.astyanax.ddl.SchemaChangeResult; -import com.netflix.astyanax.impl.AstyanaxConfigurationImpl; -import com.netflix.astyanax.thrift.ThriftFamilyFactory; -import com.netflix.astyanax.thrift.ddl.ThriftColumnDefinitionImpl; -import com.netflix.astyanax.thrift.ddl.ThriftColumnFamilyDefinitionImpl; - /** * @author Massimiliano Assante ISTI-CNR - * @author Costantino Perciante ISTI-CNR + * @author Ahmed Salah Tawfik Ibrahim ISTI-CNR * */ public class CassandraClusterConnection { @@ -39,304 +31,473 @@ public class CassandraClusterConnection { /** * keyspace location */ - private static String clusterName; - private static String host; - private static String keyspaceName; + private static List hosts; + private static String datacenterName; + private static String keyspaceName; + private CqlSession myKeyspaceSession; - private Keyspace myKeyspace; /** - * + * * @param dropSchema set true if you want do drop the current and set up new one * the connection to cassandra cluster */ protected CassandraClusterConnection(boolean dropSchema) { - if (clusterName == null || host == null || keyspaceName == null) { + if (hosts == null || datacenterName == null || keyspaceName == null) { RunningCluster cluster = RunningCluster.getInstance(null); - clusterName = cluster.getClusterName(); - host = cluster.getHost(); - keyspaceName = cluster.getKeyspaceName(); - } - AstyanaxContext clusterContext = new AstyanaxContext.Builder() - .forCluster(clusterName) - .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()) - .withConnectionPoolConfiguration( - new ConnectionPoolConfigurationImpl( - clusterName).setMaxConnsPerHost(100) - .setSeeds(host)) - .withConnectionPoolMonitor( - new CountingConnectionPoolMonitor()) - .buildCluster(ThriftFamilyFactory.getInstance()); + //host = cluster.getHost(); + hosts = cluster.getHosts(); + datacenterName = cluster.getDatacenterName(); + keyspaceName = cluster.getKeyspaceName(); + } _log.info(keyspaceName + " KeySpace SetUp ..."); - SetUpKeySpaces(clusterContext, dropSchema); + SetUpKeySpaces(dropSchema); + myKeyspaceSession = connect(keyspaceName); _log.info("CONNECTED! using KeySpace: " + keyspaceName); - - // then close connection pool for cluster - _log.info("Closing cluster connection pool no longer needed (keyspace one will be used)"); - clusterContext.shutdown(); - _log.info("Closed cluster connection pool no longer needed (keyspace one will be used)"); } /** - * Close the connection pool - */ - public void closeConnection(){ - - if(myKeyspace != null){ - try{ - _log.info("Closing pool connection"); - myKeyspace.getConnectionPool().shutdown(); - _log.info("Pool closed!"); - }catch(Exception e){ - _log.error("Unable to close connection pool", e); - } - } - } - - /** - * - * @param dropSchema set true if you want do drop the current and set up new one + * + * @param dropSchema set true if you want to drop the current and set up new one * the connection to cassandra cluster */ protected CassandraClusterConnection(boolean dropSchema, String infrastructureName) { - if (clusterName == null || host == null || keyspaceName == null) { + if (hosts == null || datacenterName == null || keyspaceName == null) { RunningCluster cluster = RunningCluster.getInstance(infrastructureName); - clusterName = cluster.getClusterName(); - host = cluster.getHost(); + //host = cluster.getHost(); + hosts = cluster.getHosts(); + datacenterName = cluster.getDatacenterName(); keyspaceName = cluster.getKeyspaceName(); - } - - AstyanaxContext clusterContext = new AstyanaxContext.Builder() - .forCluster(clusterName) - .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()) - .withConnectionPoolConfiguration( - new ConnectionPoolConfigurationImpl( - clusterName).setMaxConnsPerHost(100) - .setSeeds(host)) - .withConnectionPoolMonitor( - new CountingConnectionPoolMonitor()) - .buildCluster(ThriftFamilyFactory.getInstance()); - + } _log.info(keyspaceName + " KeySpace SetUp ..."); - SetUpKeySpaces(clusterContext, dropSchema); + SetUpKeySpaces(dropSchema); + myKeyspaceSession = connect(keyspaceName); _log.info("CONNECTED! using KeySpace: " + keyspaceName); - - // then close connection pool for cluster - _log.info("Closing cluster connection pool no longer needed (keyspace one will be used)"); - clusterContext.shutdown(); - _log.info("Closed cluster connection pool no longer needed (keyspace one will be used)"); + } + + public CqlSession getKeyspaceSession(){ + if (myKeyspaceSession.isClosed()){ + myKeyspaceSession = connect(keyspaceName); + } + return myKeyspaceSession; } /** - * Get the reference to the current keyspace - * @return keyspace reference + * @param dropSchema set true if you want to drop the current and set up new one + * the connection to cassandra cluster */ - public Keyspace getKeyspace() { - - // The Keyspace instance can be shared among different requests - if(myKeyspace == null){ - synchronized(this){ - if(myKeyspace == null){ // double checked lock - AstyanaxContext context = new AstyanaxContext.Builder() - .forCluster(clusterName) - .forKeyspace(keyspaceName) - .withAstyanaxConfiguration( - new AstyanaxConfigurationImpl() - .setDiscoveryType(NodeDiscoveryType.NONE) // use only the host given as seeds (do not discover) - .setConnectionPoolType(ConnectionPoolType.ROUND_ROBIN) // how to handle connections of the the connection pool - ) - .withConnectionPoolConfiguration( - new ConnectionPoolConfigurationImpl("MyConnectionPool") - .setMaxConnsPerHost(3) // for each seed(host) - .setSocketTimeout(2000) //-> default: 11 seconds - //.setConnectTimeout(1000) -> default: 2 seconds - .setSeeds(host) - ) - .withConnectionPoolMonitor(new CountingConnectionPoolMonitor()) - .buildKeyspace(ThriftFamilyFactory.getInstance()); - - - context.start(); - - // save keyspace reference - myKeyspace = context.getEntity(); - - } + public void SetUpKeySpaces(boolean dropSchema) { + boolean createNew = false; + boolean found = false; + CqlSession session = connect(); + Metadata metaData = session.getMetadata(); + for (KeyspaceMetadata meta : metaData.getKeyspaces().values()) { + if (meta.getName().toString().equals(keyspaceName)){ + found = true; + break; } } - - return myKeyspace; - } - - /** - * - * @param clusterContext - * @param dropSchema - * @throws ConnectionException - */ - public void SetUpKeySpaces(AstyanaxContext clusterContext, boolean dropSchema) { - boolean createNew = false; - clusterContext.start(); try { - Cluster cluster = clusterContext.getEntity(); - KeyspaceDefinition keyspaceDef = cluster.describeKeyspace(keyspaceName); - - if (dropSchema && keyspaceDef != null) { + if (dropSchema && found) { _log.info("Dropping Keyspace: " + keyspaceName + " ..."); try { - OperationResult returned = cluster.dropKeyspace(keyspaceName); + ResultSet returned = dropKeyspace(); Thread.sleep(2000); - _log.info("Dropped " + returned.getResult().toString()); - } catch (ConnectionException e) { + if (returned.wasApplied()) + _log.info("Dropped " + keyspaceName); + else + _log.info("Couldn't drop " + keyspaceName); + } catch (Exception e) { _log.error("Dropping Keyspace operation Failed ... " + keyspaceName + " does NOT exists"); return; - } catch (InterruptedException e) { - e.printStackTrace(); - } + } createNew = true; + } - } - - keyspaceDef = cluster.makeKeyspaceDefinition(); - keyspaceDef = cluster.describeKeyspace(keyspaceName); - - if (keyspaceDef == null || keyspaceDef.getName() == null || createNew) { + if (!found || createNew) { _log.info("Keyspace does not exist, triggering schema creation ... "); - createSchema(cluster); - _log.info("Cluster " + clusterName + " on " + host + " Initialized OK!"); + int replicationFactor = 2; + createKeyspace(keyspaceName, replicationFactor); + closeSession(session); + createTables(); _log.info("Using Keyspace " + keyspaceName); } - } catch (ConnectionException e) { + } catch (Exception e) { e.printStackTrace(); } } - /* - * + * ********************** CASSANDRA KEYSPACE CREATION *********************** * */ - /** - * create the databook schema - * @return - * @throws ConnectionException - */ - private void createSchema(Cluster cluster) throws ConnectionException { - - Map stratOptions = new HashMap(); - stratOptions.put("replication_factor", "1"); - - KeyspaceDefinition ksDef = cluster.makeKeyspaceDefinition(); - - //get static column families with secondary indexes - /** - * define Notifications CF with Type as secondary index - */ - ColumnFamilyDefinition cfDefNotifications = getStaticCFDef(DBCassandraAstyanaxImpl.NOTIFICATIONS, "Type"); - /** - * define Feeds CF with Privacy as secondary index - */ - ColumnFamilyDefinition cfDefFeeds = getStaticCFDef(DBCassandraAstyanaxImpl.FEEDS, "Privacy"); - /** - * define Comments CF with FeedId as secondary index - */ - ColumnFamilyDefinition cfDefComments = getStaticCFDef(DBCassandraAstyanaxImpl.COMMENTS, "Feedid"); - /** - * 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); - ColumnFamilyDefinition cfDefPendingConn = getDynamicCFDef(DBCassandraAstyanaxImpl.PENDING_CONNECTIONS_CF_NAME); - ColumnFamilyDefinition cfDefVRETimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.VRE_TIMELINE_FEEDS); - ColumnFamilyDefinition cfDefAPPTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.APP_TIMELINE_FEEDS); - ColumnFamilyDefinition cfDefUserTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.USER_TIMELINE_FEEDS); - ColumnFamilyDefinition cfDefUserLikedFeeds = getDynamicCFDef(DBCassandraAstyanaxImpl.USER_LIKED_FEEDS); - ColumnFamilyDefinition cfDefUserNotifications = getDynamicCFDef(DBCassandraAstyanaxImpl.USER_NOTIFICATIONS); - ColumnFamilyDefinition cfDefUserNotificationsUnread = getDynamicCFDef(DBCassandraAstyanaxImpl.USER_NOTIFICATIONS_UNREAD); - ColumnFamilyDefinition cfDefUserNotificationsPreferences = getDynamicCFDef(DBCassandraAstyanaxImpl.USER_NOTIFICATIONS_PREFERENCES); - ColumnFamilyDefinition cfDefEmailInvitesTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.EMAIL_INVITES); - ColumnFamilyDefinition cfDefVREInvitesTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.VRE_INVITES); - ColumnFamilyDefinition cfDefHashtagsCounter = getDynamicCFDef(DBCassandraAstyanaxImpl.HASHTAGS_COUNTER); - ColumnFamilyDefinition cfDefHashtagTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.HASHTAGGED_FEEDS); - ColumnFamilyDefinition cfDefHashtagCommentsTimeline = getDynamicCFDef(DBCassandraAstyanaxImpl.HASHTAGGED_COMMENTS); - - - ksDef.setName(keyspaceName) - .setStrategyOptions(stratOptions) - .setStrategyClass("SimpleStrategy") - .addColumnFamily(cfDefNotifications) - .addColumnFamily(cfDefFeeds) - .addColumnFamily(cfDefComments) - .addColumnFamily(cfDefLikes) - .addColumnFamily(cfDefInvites) - .addColumnFamily(cfDefAttachments) - .addColumnFamily(cfDefConn) - .addColumnFamily(cfDefPendingConn) - .addColumnFamily(cfDefVRETimeline) - .addColumnFamily(cfDefAPPTimeline) - .addColumnFamily(cfDefUserTimeline) - .addColumnFamily(cfDefUserNotifications) - .addColumnFamily(cfDefUserNotificationsUnread) - .addColumnFamily(cfDefUserNotificationsPreferences) - .addColumnFamily(cfDefUserLikedFeeds) - .addColumnFamily(cfDefEmailInvitesTimeline) - .addColumnFamily(cfDefVREInvitesTimeline) - .addColumnFamily(cfDefHashtagsCounter) - .addColumnFamily(cfDefHashtagTimeline) - .addColumnFamily(cfDefHashtagCommentsTimeline); - - cluster.addKeyspace(ksDef); + private static CqlSession connect() { + CqlSession cqlSession = configBuilder(CqlSession.builder()) + .addContactPoints(hosts) + .withLocalDatacenter(datacenterName) + .build(); + _log.info("[OK] Connected to Cassandra Cluster"); + return cqlSession; + } + private static CqlSession connect(String KEYSPACE_NAME) { + CqlSession cqlSession = configBuilder(CqlSession.builder()) + .addContactPoints(hosts) + .withKeyspace(KEYSPACE_NAME) + .withLocalDatacenter("1") + .build(); + _log.info("[OK] Connected to Keyspace {} ", KEYSPACE_NAME); + return cqlSession; } - /** - * create a dynamic column family to be added in a keyspace - * - * @param cfName the CF name - * @return the instance to be added to the keyspace - */ - private ColumnFamilyDefinition getDynamicCFDef(String cfName) { - ColumnFamilyDefinition columnFamilyDefinition = new ThriftColumnFamilyDefinitionImpl(); - columnFamilyDefinition.setName(cfName); - columnFamilyDefinition.setKeyValidationClass("UTF8Type"); - columnFamilyDefinition.setComparatorType("UTF8Type"); - return columnFamilyDefinition; + public static void closeSession(CqlSession session) { + if (session != null) session.close(); + _log.info("[OK]Session is now closed"); } - /** - * create a static column family to be added in a keyspace with possibility to add a secondary index for a given column - * - * @param cfName the CF name - * @param secondaryIndexedField the column name of the column to index - * @return the instance to be added to the keyspace - */ - private ColumnFamilyDefinition getStaticCFDef(String cfName, String secondaryIndexedField) { - ColumnFamilyDefinition columnFamilyDefinition = new ThriftColumnFamilyDefinitionImpl(); - columnFamilyDefinition.setName(cfName); - - columnFamilyDefinition.setKeyValidationClass("UTF8Type"); - columnFamilyDefinition.setComparatorType("UTF8Type"); - - - //Add secondary index for userid - ColumnDefinition typeCDef = new ThriftColumnDefinitionImpl(); - typeCDef.setName(secondaryIndexedField) - .setValidationClass("UTF8Type"); - typeCDef.setIndex(secondaryIndexedField+"_"+UUID.randomUUID().toString().substring(0,5), "KEYS"); - - columnFamilyDefinition.addColumnDefinition(typeCDef); - return columnFamilyDefinition; + public void closeConnection(){ + if(!myKeyspaceSession.isClosed()){ + try{ + _log.info("Closing connection"); + closeSession(myKeyspaceSession); + _log.info("Connection closed!"); + }catch(Exception e){ + _log.error("Unable to close connection", e); + } + } } + + private static CqlSessionBuilder configBuilder(CqlSessionBuilder cqlSessionBuilder){ + return cqlSessionBuilder + .withConfigLoader(DriverConfigLoader.programmaticBuilder() + // Resolves the timeout query 'SELECT * FROM system_schema.tables' timed out after PT2S + .withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofMillis(240000)) + .withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofMillis(240000)) + .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(240000)) + .build()); + } + private static void createKeyspace(String keyspaceName, int replicationFactor) { + try (CqlSession cqlSession = configBuilder(CqlSession.builder()) + .addContactPoints(hosts) + .withLocalDatacenter("1") + .build()) { + cqlSession.execute(SchemaBuilder.createKeyspace(keyspaceName) + .ifNotExists() + .withSimpleStrategy(replicationFactor) + .withDurableWrites(true) + .build()); + _log.info("+ Keyspace '{}' created.", keyspaceName); + closeSession(cqlSession); + } + } + + private static ResultSet dropKeyspace(){ + ResultSet toreturn; + try (CqlSession cqlSession = configBuilder(CqlSession.builder()) + .addContactPoints(hosts) + .withLocalDatacenter("1") + .build()) { + toreturn = cqlSession.execute(SchemaBuilder.dropKeyspace(keyspaceName).ifExists().build()); + _log.info("Keyspace {} dropped.", keyspaceName); + closeSession(cqlSession); + } + return toreturn; + } + private void createTables(){ + try (CqlSession cqlSession = configBuilder(CqlSession.builder()) + .addContactPoints(hosts) + .withLocalDatacenter("1") + .withKeyspace(keyspaceName) + .build()) { + + createTableUSERNotificationsPreferences(cqlSession); + createTableUSERNotifications(cqlSession); + createTableVRETimeline(cqlSession); + createTableAppTimeline(cqlSession); + createTableUSERTimeline(cqlSession); + createTableHashtaggedPosts(cqlSession); + createTableHashtaggedComments(cqlSession); + createTableHashtagsCounter(cqlSession); + createTableUSERNotificationsUnread(cqlSession); + createTableUSERLikes(cqlSession); + createTableVREInvites(cqlSession); + createTableEMAILInvites(cqlSession); + createTableAttachments(cqlSession); + createTableInvites(cqlSession); + createTableLikes(cqlSession); + createTableComments(cqlSession); + createTableNotifications(cqlSession); + createTablePosts(cqlSession); + + closeSession(cqlSession); + } + } + private void createTableUSERNotificationsPreferences(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("UserNotificationsPreferences") + .ifNotExists() + .withPartitionKey("userid", DataTypes.TEXT) + .withPartitionKey("type", DataTypes.TEXT) + .withColumn("preference", DataTypes.TEXT) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "USERNotificationsPreferences"); + } + private void createTableUSERNotifications(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("UserNotifications") + .ifNotExists() + .withPartitionKey("userid", DataTypes.TEXT) + .withPartitionKey("timestamp", DataTypes.TIMESTAMP) + .withColumn("notid", DataTypes.UUID) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "USERNotifications"); + } + private void createTableVRETimeline(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("VRETimeline") + .ifNotExists() + .withPartitionKey("vreid", DataTypes.TEXT) + .withPartitionKey("timestamp", DataTypes.TIMESTAMP) + .withColumn("postid", DataTypes.UUID) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "VRETimeline"); + } + private void createTableAppTimeline(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("AppTimeline") + .ifNotExists() + .withPartitionKey("appid", DataTypes.TEXT) + .withPartitionKey("timestamp", DataTypes.TIMESTAMP) + .withColumn("postid", DataTypes.UUID) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "AppTimeline"); + } + private void createTableUSERTimeline(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("UserTimeline") + .ifNotExists() + .withPartitionKey("userid", DataTypes.TEXT) + .withPartitionKey("timestamp", DataTypes.TIMESTAMP) + .withColumn("postid", DataTypes.UUID) + .withCompactStorage() + .build()); + _log.info("+ Table '{}' has been created (if needed).", "USERTimeline"); + } + private void createTableHashtaggedPosts(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("HashtaggedPosts") + .ifNotExists() + .withPartitionKey("hashtag", DataTypes.TEXT) + .withPartitionKey("postid", DataTypes.UUID) + .withColumn("vreid", DataTypes.TEXT) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "HashtaggedPosts"); + } + private void createTableHashtaggedComments(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("HashtaggedComments") + .ifNotExists() + .withPartitionKey("hashtag", DataTypes.TEXT) + .withPartitionKey("commentid", DataTypes.UUID) + .withColumn("vreid", DataTypes.TEXT) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "HashtaggedComments"); + } + private void createTableHashtagsCounter(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("HashtagsCounter") + .ifNotExists() + .withPartitionKey("vreid", DataTypes.TEXT) + .withPartitionKey("hashtag", DataTypes.TEXT) + .withColumn("count", DataTypes.BIGINT) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "HashtagsCounter"); + } + private void createTableUSERNotificationsUnread(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("UserUnreadNotifications") + .ifNotExists() + .withPartitionKey("userid", DataTypes.TEXT) + .withPartitionKey("timestamp", DataTypes.TIMESTAMP) + .withColumn("notid", DataTypes.UUID) + .withCompactStorage() + .build()); + _log.info("+ Table '{}' has been created (if needed).", "USERNotificationsUnread"); + } + private void createTableUSERLikes(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("UserLikes") + .ifNotExists() + .withPartitionKey("userid", DataTypes.TEXT) + .withPartitionKey("likeid", DataTypes.UUID) + .withColumn("postid", DataTypes.UUID) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "USERLikes"); + } + private void createTableVREInvites(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("VREInvites") + .ifNotExists() + .withPartitionKey("vreid", DataTypes.TEXT) + .withPartitionKey("inviteid", DataTypes.UUID) + .withColumn("status", DataTypes.TEXT) + .withCompactStorage() + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "VREInvites"); + } + private void createTableEMAILInvites(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("EmailInvites") + .ifNotExists() + .withPartitionKey("email", DataTypes.TEXT) + .withPartitionKey("vreid", DataTypes.TEXT) + .withColumn("inviteid", DataTypes.UUID) + .withCompactStorage() + .build()); + _log.info("+ Table '{}' has been created (if needed).", "EMAILInvites"); + } + private void createTableAttachments(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Attachments") + .ifNotExists() + .withPartitionKey("attachid", DataTypes.UUID) + .withColumn("postid", DataTypes.UUID) + .withColumn("uri", DataTypes.TEXT) + .withColumn("name", DataTypes.TEXT) + .withColumn("description", DataTypes.TEXT) + .withColumn("urithumbnail", DataTypes.TEXT) + .withColumn("mimetype", DataTypes.TEXT) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("post_attach") + .ifNotExists() + .onTable("Attachments") + .andColumn("postid") + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "Attachments"); + } + private void createTableInvites(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Invites") + .ifNotExists() + .withPartitionKey("inviteid", DataTypes.UUID) + .withColumn("senderuserid", DataTypes.TEXT) + .withColumn("vreid", DataTypes.TEXT) + .withColumn("email", DataTypes.TEXT) + .withColumn("controlcode", DataTypes.TEXT) + .withColumn("status", DataTypes.TEXT) + .withColumn("timestamp", DataTypes.TIMESTAMP) + .withColumn("senderfullname", DataTypes.TEXT) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("sender") + .ifNotExists() + .onTable("Invites") + .andColumn("senderuserid") + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "Invites"); + } + private void createTableLikes(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Likes") + .ifNotExists() + .withPartitionKey("likeid", DataTypes.UUID) + .withColumn("userid", DataTypes.TEXT) + .withColumn("fullname", DataTypes.TEXT) + .withColumn("thumbnailurl", DataTypes.TEXT) + .withColumn("postid", DataTypes.UUID) + .withColumn("timestamp", DataTypes.TIMESTAMP) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("post_likes") + .ifNotExists() + .onTable("Likes") + .andColumn("postid") + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "Likes"); + } + private void createTableComments(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Comments") + .ifNotExists() + .withPartitionKey("commentid", DataTypes.UUID) + .withColumn("userid", DataTypes.TEXT) + .withColumn("fullname", DataTypes.TEXT) + .withColumn("thumbnailurl", DataTypes.TEXT) + .withColumn("comment", DataTypes.TEXT) + .withColumn("postid", DataTypes.UUID) + .withColumn("timestamp", DataTypes.TIMESTAMP) + .withColumn("isedit", DataTypes.BOOLEAN) + .withColumn("lastedittime", DataTypes.TIMESTAMP) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("post_comments") + .ifNotExists() + .onTable("Comments") + .andColumn("postid") + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "Comments"); + } + private void createTableNotifications(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Notifications") + .ifNotExists() + .withPartitionKey("notid", DataTypes.UUID) + .withColumn("type", DataTypes.TEXT) + .withColumn("userid", DataTypes.TEXT) + .withColumn("subjectid", DataTypes.TEXT) + .withColumn("timestamp", DataTypes.TIMESTAMP) + .withColumn("description", DataTypes.TEXT) + .withColumn("uri", DataTypes.TEXT) + .withColumn("senderid", DataTypes.TEXT) + .withColumn("senderfullname", DataTypes.TEXT) + .withColumn("senderthumbnailurl", DataTypes.TEXT) + .withColumn("isread", DataTypes.BOOLEAN) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("not_type") + .ifNotExists() + .onTable("Notifications") + .andColumn("type") + .build()); + _log.info("+ Table '{}' has been created (if needed).", "Notifications"); + } + private void createTablePosts(CqlSession cqlSession) { + cqlSession.execute(SchemaBuilder.createTable("Posts") + .ifNotExists() + .withPartitionKey("postid", DataTypes.UUID) + .withColumn("linkhost", DataTypes.TEXT) + .withColumn("description", DataTypes.TEXT) + .withColumn("email", DataTypes.TEXT) + .withColumn("likesno", DataTypes.BIGINT) + .withColumn("thumbnailurl", DataTypes.TEXT) + .withColumn("linkdescription", DataTypes.TEXT) + .withColumn("timestamp", DataTypes.TIMESTAMP) + .withColumn("uri", DataTypes.TEXT) + .withColumn("isapplicationpost", DataTypes.BOOLEAN) + .withColumn("entityid", DataTypes.TEXT) + .withColumn("privacy", DataTypes.TEXT) + .withColumn("type", DataTypes.TEXT) + .withColumn("urithumbnail", DataTypes.TEXT) + .withColumn("vreid", DataTypes.TEXT) + .withColumn("multifileupload", DataTypes.BOOLEAN) + .withColumn("fullname", DataTypes.TEXT) + .withColumn("commentsno", DataTypes.BIGINT) + .withColumn("linktitle", DataTypes.TEXT) + .withCompactStorage() + .build()); + cqlSession.execute(SchemaBuilder.createIndex("posts_privacy") + .ifNotExists() + .onTable("Posts") + .andColumn("privacy") + .build()); + + _log.info("+ Table '{}' has been created (if needed).", "Posts"); + } + } diff --git a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java b/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java deleted file mode 100644 index c426315..0000000 --- a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java +++ /dev/null @@ -1,3433 +0,0 @@ -package org.gcube.portal.databook.server; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -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; -import org.gcube.portal.databook.shared.Invite; -import org.gcube.portal.databook.shared.InviteOperationResult; -import org.gcube.portal.databook.shared.InviteStatus; -import org.gcube.portal.databook.shared.Like; -import org.gcube.portal.databook.shared.Notification; -import org.gcube.portal.databook.shared.NotificationChannelType; -import org.gcube.portal.databook.shared.NotificationType; -import org.gcube.portal.databook.shared.Post; -import org.gcube.portal.databook.shared.PostType; -import org.gcube.portal.databook.shared.PrivacyLevel; -import org.gcube.portal.databook.shared.RangeFeeds; -import org.gcube.portal.databook.shared.RangePosts; -import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException; -import org.gcube.portal.databook.shared.ex.CommentIDNotFoundException; -import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; -import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.InviteIDNotFoundException; -import org.gcube.portal.databook.shared.ex.InviteStatusNotFoundException; -import org.gcube.portal.databook.shared.ex.LikeIDNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationChannelTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationIDNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.PrivacyLevelTypeNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.astyanax.MutationBatch; -import com.netflix.astyanax.RowCallback; -import com.netflix.astyanax.connectionpool.OperationResult; -import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; -import com.netflix.astyanax.model.Column; -import com.netflix.astyanax.model.ColumnFamily; -import com.netflix.astyanax.model.ColumnList; -import com.netflix.astyanax.model.Row; -import com.netflix.astyanax.model.Rows; -import com.netflix.astyanax.query.PreparedIndexExpression; -import com.netflix.astyanax.serializers.StringSerializer; -import com.netflix.astyanax.util.RangeBuilder; -/** - * @author Massimiliano Assante ISTI-CNR - * @author Costantino Perciante ISTI-CNR - * This class is used for querying and adding data to Cassandra via Astyanax High Level API - */ -public final class DBCassandraAstyanaxImpl implements DatabookStore { - - /** - * logger - */ - private static final Logger _log = LoggerFactory.getLogger(DBCassandraAstyanaxImpl.class); - /** - * Column Family names - */ - public static final String CONNECTIONS = "Connections"; - public static final String PENDING_CONNECTIONS_CF_NAME = "PendingConnections"; - public static final String NOTIFICATIONS = "Notifications"; - public static final String FEEDS = "Feeds"; - public static final String COMMENTS = "Comments"; - public static final String LIKES = "Likes"; - public static final String INVITES = "Invites"; - public static final String VRE_TIMELINE_FEEDS = "VRETimeline"; - public static final String USER_TIMELINE_FEEDS = "USERTimeline"; - public static final String APP_TIMELINE_FEEDS = "AppTimeline"; - public static final String USER_LIKED_FEEDS = "USERLikes"; - public static final String USER_NOTIFICATIONS = "USERNotifications"; // regular user notifications timeline (both read and unread, messages are included) - public static final String USER_NOTIFICATIONS_UNREAD = "USERNotificationsUnread"; // only unread user notifications/ notifications messages - public static final String USER_NOTIFICATIONS_PREFERENCES = "USERNotificationsPreferences"; // preferences for notifications - 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_COMMENTS = "HashtaggedComments"; // contains hashtags per type associated with vre and comment - 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 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 cf_Connections = new ColumnFamily( - CONNECTIONS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_PendingConnections = new ColumnFamily( - PENDING_CONNECTIONS_CF_NAME, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_Feeds = new ColumnFamily( - FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_UserTline = new ColumnFamily( - USER_TIMELINE_FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - - private static ColumnFamily cf_VRETline = new ColumnFamily( - VRE_TIMELINE_FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - - private static ColumnFamily cf_AppTline = new ColumnFamily( - APP_TIMELINE_FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - - private static ColumnFamily cf_Comments = new ColumnFamily( - COMMENTS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_Likes = new ColumnFamily( - LIKES, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_Invites = new ColumnFamily( - INVITES, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_UserLikedFeeds = new ColumnFamily( - USER_LIKED_FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_Notifications = new ColumnFamily( - NOTIFICATIONS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_UserNotifications = new ColumnFamily( - USER_NOTIFICATIONS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_UserNotificationsUnread = new ColumnFamily( - USER_NOTIFICATIONS_UNREAD, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - protected static ColumnFamily cf_UserNotificationsPreferences = new ColumnFamily( - USER_NOTIFICATIONS_PREFERENCES, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_HashtagsCounter = new ColumnFamily( - HASHTAGS_COUNTER, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - protected static ColumnFamily cf_HashtagTimelineFeed = new ColumnFamily( - HASHTAGGED_FEEDS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - protected static ColumnFamily cf_HashtagTimelineComment = new ColumnFamily( - HASHTAGGED_COMMENTS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - private static ColumnFamily cf_VREInvites = new ColumnFamily( - VRE_INVITES, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - protected static ColumnFamily cf_EmailInvites = new ColumnFamily( - EMAIL_INVITES, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - - protected static ColumnFamily cf_Attachments = new ColumnFamily( - ATTACHMENTS, // Column Family Name - StringSerializer.get(), // Key Serializer - StringSerializer.get()); // Column Serializer - - /** - * 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 DBCassandraAstyanaxImpl(boolean dropSchema) { - conn = new CassandraClusterConnection(dropSchema); - } - /** - * public constructor, no dropping schema is allowed - */ - public DBCassandraAstyanaxImpl() { - conn = new CassandraClusterConnection(false); - } - - /** - * public constructor, no dropping schema is allowed, infrastructureName is given. - */ - public DBCassandraAstyanaxImpl(String infrastructureName) { - conn = new CassandraClusterConnection(false, infrastructureName); - } - - /** - * execute the mutation batch - * @param m - * @return true if everything went fine - */ - private boolean execute(MutationBatch m) { - try { - m.execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return false; - } - return true; - } - /* - * - ********************** FRIENDSHIPS (CONNECTIONS) *********************** - * - */ - /** - * {@inheritDoc} - */ - @Override - public boolean requestFriendship(String from, String to) { - - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_PendingConnections, to).putColumn(from, "", null); - try { - m.execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return false; - } - _log.info(from + " has requested a connection to " + to); - return true; - } - /** - * {@inheritDoc} - */ - @Override - public boolean approveFriendship(String from, String to) { - - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_Connections, to).putColumn(from, "", null); - m.withRow(cf_Connections, from).putColumn(to, "", null); - // Deleting a standard column - m.withRow(cf_PendingConnections, from).deleteColumn(to); - boolean result = execute(m); - if (result) - _log.info(from + " and " + to + " are now connected"); - return result; - } - /** - * {@inheritDoc} - */ - @Override - public boolean denyFriendship(String from, String to) { - // Deleting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_PendingConnections, from).deleteColumn(to); - boolean result = execute(m); - if (result) - _log.info(from + " has denied connection to " + to); - return result; - } - /** - * {@inheritDoc} - */ - @Override - public List getFriends(String userid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_Connections) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getName()); - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public List getPendingFriendRequests(String userid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_PendingConnections) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getName()); - } - } - return toReturn; - } - /* - * - ********************** FEEDS *********************** - * - */ - /** - * common part to save a feed - * @deprecated - * @param feed - * @return the partial mutation batch instance - */ - private MutationBatch initSaveFeed(Feed feed) { - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Feeds, feed.getKey().toString()) - .putColumn("Entityid", feed.getEntityId(), null) - .putColumn("Time", feed.getTime().getTime()+"", null) - .putColumn("Vreid", feed.getVreid(), null) - .putColumn("Uri", feed.getUri(), null) - .putColumn("UriThumbnail", feed.getUriThumbnail(), null) - .putColumn("Description", feed.getDescription(), null) - .putColumn("Privacy", feed.getPrivacy().toString(), null) - .putColumn("FullName", feed.getFullName(), null) - .putColumn("Type", feed.getType().toString(), null) - .putColumn("Email", feed.getEmail(), null) - .putColumn("ThumbnailURL", feed.getThumbnailURL(), null) - .putColumn("CommentsNo", feed.getCommentsNo(), null) - .putColumn("LikesNo", feed.getLikesNo(), null) - .putColumn("LinkTitle", feed.getLinkTitle(), null) - .putColumn("LinkDescription", feed.getLinkDescription(), null) - .putColumn("LinkHost", feed.getLinkHost(), null) - .putColumn("IsApplicationFeed", feed.isApplicationFeed(), null) - .putColumn("multiFileUpload", feed.isMultiFileUpload(), null); - return m; - } - /** - * common part to save a feed - * @param post - * @return the partial mutation batch instance - */ - private MutationBatch initSavePost(Post post) { - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Feeds, post.getKey().toString()) - .putColumn("Entityid", post.getEntityId(), null) - .putColumn("Time", post.getTime().getTime()+"", null) - .putColumn("Vreid", post.getVreid(), null) - .putColumn("Uri", post.getUri(), null) - .putColumn("UriThumbnail", post.getUriThumbnail(), null) - .putColumn("Description", post.getDescription(), null) - .putColumn("Privacy", post.getPrivacy().toString(), null) - .putColumn("FullName", post.getFullName(), null) - .putColumn("Type", post.getType().toString(), null) - .putColumn("Email", post.getEmail(), null) - .putColumn("ThumbnailURL", post.getThumbnailURL(), null) - .putColumn("CommentsNo", post.getCommentsNo(), null) - .putColumn("LikesNo", post.getLikesNo(), null) - .putColumn("LinkTitle", post.getLinkTitle(), null) - .putColumn("LinkDescription", post.getLinkDescription(), null) - .putColumn("LinkHost", post.getLinkHost(), null) - .putColumn("IsApplicationFeed", post.isApplicationFeed(), null) - .putColumn("multiFileUpload", post.isMultiFileUpload(), null); - return m; - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public boolean saveUserFeed(Feed feed) { - MutationBatch m = initSaveFeed(feed); - - //an entry in the user Timeline - m.withRow(cf_UserTline, feed.getEntityId()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); - - //an entry in the VRES Timeline iff vreid field is not empty - if (feed.getVreid() != null && feed.getVreid().compareTo("") != 0) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, feed.getVreid()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); - } - return execute(m); - } - /** - * {@inheritDoc} - */ - @Override - public boolean saveUserPost(Post post) { - MutationBatch m = initSavePost(post); - - //an entry in the user Timeline - m.withRow(cf_UserTline, post.getEntityId()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); - - //an entry in the VRES Timeline iff vreid field is not empty - if (post.getVreid() != null && post.getVreid().compareTo("") != 0) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, post.getVreid()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); - } - return execute(m); - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public boolean saveUserFeed(Feed feed, List 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} - */ - @Override - public boolean saveUserPost(Post post, List attachments) { - if (attachments != null && !attachments.isEmpty()) - post.setMultiFileUpload(true); - boolean saveFeedResult = saveUserPost(post); - if (saveFeedResult) { - 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 - @Deprecated - public boolean saveAppFeed(Feed feed) { - MutationBatch m = initSaveFeed(feed); - - //an entry in the Applications Timeline - m.withRow(cf_AppTline, feed.getEntityId()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); - - //an entry in the VRES Timeline iff vreid field is not empty - if (feed.getVreid() != null && feed.getVreid().compareTo("") != 0) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, feed.getVreid()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); - } - boolean result = execute(m); - if (result) - _log.trace("saveAppFeed OK!"); - return result; - } - /** - * {@inheritDoc} - */ - @Override - public boolean saveAppPost(Post post) { - MutationBatch m = initSavePost(post); - - //an entry in the Applications Timeline - m.withRow(cf_AppTline, post.getEntityId()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); - - //an entry in the VRES Timeline iff vreid field is not empty - if (post.getVreid() != null && post.getVreid().compareTo("") != 0) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, post.getVreid()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); - } - boolean result = execute(m); - if (result) - _log.trace("saveAppFeed OK!"); - return result; - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public boolean saveAppFeed(Feed feed, List attachments) { - if (attachments != null && !attachments.isEmpty()) - feed.setMultiFileUpload(true); - boolean saveFeedResult = saveAppFeed(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} - */ - @Override - public boolean saveAppPost(Post post, List attachments) { - if (attachments != null && !attachments.isEmpty()) - post.setMultiFileUpload(true); - boolean saveFeedResult = saveAppPost(post); - if (saveFeedResult) { - String feedKey = post.getKey(); - for (Attachment attachment : attachments) { - boolean attachSaveResult = saveAttachmentEntry(feedKey, attachment); - if (!attachSaveResult) - _log.warn("Some of the attachments failed to be saved: " + attachment.getName()); - } - return true; - } - else return false; - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public boolean saveFeedToVRETimeline(String feedKey, String vreid) throws FeedIDNotFoundException { - String feedId = feedKey; - Feed toCheck = null; - try { - toCheck = readFeed(feedId); - if (toCheck == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId, feedId); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - - //an entry in the user Timeline - m.withRow(cf_VRETline, vreid) - .putColumn(toCheck.getTime().getTime()+"", feedKey, null); - return execute(m); - } - /** - * {@inheritDoc} - */ - @Override - public boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException { - String postId = postKey; - Post toCheck = null; - try { - toCheck = readPost(postId); - if (toCheck == null) - throw new FeedIDNotFoundException("Could not find Post with id " + postId, postId); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - - //an entry in the user Timeline - m.withRow(cf_VRETline, vreid) - .putColumn(toCheck.getTime().getTime()+"", postKey, null); - return execute(m); - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public Feed readFeed(String feedid) - throws PrivacyLevelTypeNotFoundException, - FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - Feed toReturn = new Feed(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Feeds) - .getKey(feedid) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { - throw new FeedIDNotFoundException("The requested feedid: " + feedid + " is not existing", feedid); - } - - toReturn.setKey(feedid); - toReturn.setDescription(columns.getColumnByName("Description").getStringValue()); - toReturn.setEmail(columns.getColumnByName("Email").getStringValue()); - toReturn.setFullName(columns.getColumnByName("FullName").getStringValue()); - toReturn.setPrivacy(getPrivacyLevel(columns.getColumnByName("Privacy").getStringValue())); - toReturn.setThumbnailURL(columns.getColumnByName("ThumbnailURL").getStringValue()); - toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Time").getStringValue())); - - FeedType ft = getFeedType(columns.getColumnByName("Type").getStringValue()); - - toReturn.setType(ft); - toReturn.setUri(columns.getColumnByName("Uri").getStringValue()); - toReturn.setUriThumbnail(columns.getColumnByName("UriThumbnail").getStringValue()); - toReturn.setVreid(columns.getColumnByName("Vreid").getStringValue()); - toReturn.setEntityId(columns.getColumnByName("Entityid").getStringValue()); - toReturn.setCommentsNo(columns.getColumnByName("CommentsNo").getStringValue()); - toReturn.setLikesNo(columns.getColumnByName("LikesNo").getStringValue()); - - toReturn.setLinkTitle(columns.getColumnByName("LinkTitle").getStringValue()); - toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue()); - toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue()); - toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue()); - boolean isMultiFileUpload = false; - try { - isMultiFileUpload = columns.getColumnByName("multiFileUpload").getBooleanValue(); - } - catch (NullPointerException e) { } - toReturn.setMultiFileUpload(isMultiFileUpload); - - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public Post readPost(String postid) - throws PrivacyLevelTypeNotFoundException, - FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - Post toReturn = new Post(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Feeds) - .getKey(postid) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { - throw new FeedIDNotFoundException("The requested feedid: " + postid + " is not existing", postid); - } - - toReturn.setKey(postid); - toReturn.setDescription(columns.getColumnByName("Description").getStringValue()); - toReturn.setEmail(columns.getColumnByName("Email").getStringValue()); - toReturn.setFullName(columns.getColumnByName("FullName").getStringValue()); - toReturn.setPrivacy(getPrivacyLevel(columns.getColumnByName("Privacy").getStringValue())); - toReturn.setThumbnailURL(columns.getColumnByName("ThumbnailURL").getStringValue()); - toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Time").getStringValue())); - - PostType ptype = getPostType(columns.getColumnByName("Type").getStringValue()); - - toReturn.setType(ptype); - toReturn.setUri(columns.getColumnByName("Uri").getStringValue()); - toReturn.setUriThumbnail(columns.getColumnByName("UriThumbnail").getStringValue()); - toReturn.setVreid(columns.getColumnByName("Vreid").getStringValue()); - toReturn.setEntityId(columns.getColumnByName("Entityid").getStringValue()); - toReturn.setCommentsNo(columns.getColumnByName("CommentsNo").getStringValue()); - toReturn.setLikesNo(columns.getColumnByName("LikesNo").getStringValue()); - - toReturn.setLinkTitle(columns.getColumnByName("LinkTitle").getStringValue()); - toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue()); - toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue()); - toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue()); - boolean isMultiFileUpload = false; - try { - isMultiFileUpload = columns.getColumnByName("multiFileUpload").getBooleanValue(); - } - catch (NullPointerException e) { } - toReturn.setMultiFileUpload(isMultiFileUpload); - - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - @Deprecated - public List getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { - Date now = new Date(); - if (timeInMillis > now.getTime()) - throw new IllegalArgumentException("the timeInMillis must be before today"); - - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - List toReturn = new ArrayList(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - long feedTime = Long.parseLong(column.getName()); - if (feedTime > timeInMillis) { - try { - Feed toCheck = readFeed(column.getStringValue()); - if (toCheck.getType() != FeedType.DISABLED) - toReturn.add(toCheck); - } catch (PrivacyLevelTypeNotFoundException - | FeedTypeNotFoundException - | FeedIDNotFoundException - | ColumnNameNotFoundException e) { - e.printStackTrace(); - } - } - } - } - return toReturn; - } - /** - * {@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"); - - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - List toReturn = new ArrayList<>(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - long feedTime = Long.parseLong(column.getName()); - if (feedTime > timeInMillis) { - try { - Post toCheck = readPost(column.getStringValue()); - if (toCheck.getType() != PostType.DISABLED) - toReturn.add(toCheck); - } catch (PrivacyLevelTypeNotFoundException - | FeedTypeNotFoundException - | FeedIDNotFoundException - | ColumnNameNotFoundException e) { - e.printStackTrace(); - } - } - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public boolean deleteFeed(String feedId) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException { - Feed toDelete = readFeed(feedId); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //edit the entry in the feed CF - m.withRow(cf_Feeds, toDelete.getKey().toString()).putColumn("Type", ""+FeedType.DISABLED, null); - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Delete Feed ERROR for feedid " + feedId); - return false; - } - _log.info("Delete Feed OK"); - return true; - } - /** - * {@inheritDoc} - */ - @Override - public boolean deletePost(String postid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException { - Post toDelete = readPost(postid); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //edit the entry in the feed CF - m.withRow(cf_Feeds, toDelete.getKey().toString()).putColumn("Type", ""+PostType.DISABLED, null); - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Delete Post ERROR for postid " + postid); - return false; - } - _log.info("Delete Post OK"); - return true; - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public List getAllFeedsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getFeedsByIds(getUserFeedIds(userid)); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getPostsByIds(getUserPostIds(userid)); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllFeedsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getFeedsByIds(getAppFeedIds(appid)); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getPostsByIds(getAppPostIds(appid)); - } - /** - * {@inheritDoc} - * @throws Exception - */ - @Deprecated - @Override - public List getRecentCommentedFeedsByUserAndDate(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 feeds' ids - HashSet feedsIds = new HashSet(); - - for (Comment comment : lastComments) { - String feedId = comment.getFeedid(); - try{ - if(!feedsIds.contains(feedId)){ - feedsIds.add(feedId); - toReturn.add(readFeed(feedId)); - } - }catch(Exception e){ - _log.error("Unable to retrieve feed with id " + feedId, e); - } - } - - Collections.sort(toReturn, Collections.reverseOrder()); - return toReturn; - } - /** - * {@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 feeds' ids - HashSet postIds = new HashSet(); - - for (Comment comment : lastComments) { - String postId = comment.getFeedid(); - try{ - if(!postIds.contains(postId)){ - postIds.add(postId); - toReturn.add(readPost(postId)); - } - }catch(Exception e){ - _log.error("Unable to retrieve feed with id " + postId, e); - } - } - - Collections.sort(toReturn, Collections.reverseOrder()); - return toReturn; - } - /** - * @deprecated - * helper method that retrieve all the feeds belongin to a list of Ids - * @param feedIds - * @return - * @throws ColumnNameNotFoundException - * @throws FeedIDNotFoundException - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - */ - private List getFeedsByIds(List feedIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - ArrayList toReturn = new ArrayList(); - for (String feedid : feedIds) { - Feed toAdd = readFeed(feedid); - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) - toReturn.add(toAdd); - } - return toReturn; - } - /** - * helper method that retrieve all the feeds belongin to a list of Ids - * @param postIds - * @return - * @throws ColumnNameNotFoundException - * @throws FeedIDNotFoundException - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - */ - private List getPostsByIds(List postIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - ArrayList toReturn = new ArrayList(); - for (String feedid : postIds) { - Post toAdd = readPost(feedid); - if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) - toReturn.add(toAdd); - } - return toReturn; - } - /** - * helper method that retrieve all the feed Ids belonging to a user - * @param userid user identifier - * @return simply return a list of user feed UUID in chronological order from the oldest to the more recent - */ - @Deprecated - private ArrayList getUserFeedIds(String userid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - 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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - - /** - * helper method that return whether the user - * @param userid user identifier - * @param feedid the feed identifier - * @return true if the feed id liked already - */ - private boolean isFeedLiked(String userid, String feedid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserLikedFeeds) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - // Iterate rows and their columns looking for the feeid id - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(feedid)==0) - return true; - } - } - return false; - } - - - /** - * helper method that retrieve all the feed Ids belonging to an application - * @param appid application identifier - * @return simply return a list of app feed UUID in chronological order from the oldest to the more recent - */ - @Deprecated - private ArrayList getAppFeedIds(String appid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_AppTline) - .getKeySlice(appid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - /** - * 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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_AppTline) - .getKeySlice(appid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { - ArrayList toReturn = new ArrayList(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Feeds) - .searchWithIndex() - .setLimit(20) // Number of rows returned - .addExpression() - .whereColumn("Privacy").equals().value(PrivacyLevel.PORTAL.toString()) - .execute(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - Feed toAdd = new Feed(); - toAdd.setKey(row.getKey()); - for (Column col : row.getColumns()) { - if (col.getName().compareTo("Description") == 0) - toAdd.setDescription(col.getStringValue()); - else if (col.getName().compareTo("FullName") == 0) - toAdd.setFullName(col.getStringValue()); - else if (col.getName().compareTo("Email") == 0) - toAdd.setEmail(col.getStringValue()); - else if (col.getName().compareTo("Privacy") == 0) - toAdd.setPrivacy(getPrivacyLevel(col.getStringValue())); - else if (col.getName().compareTo("ThumbnailURL") == 0) - toAdd.setThumbnailURL(col.getStringValue()); - else if (col.getName().compareTo("Time") == 0) - toAdd.setTime(getDateFromTimeInMillis(col.getStringValue())); - else if (col.getName().compareTo("Type") == 0) { - FeedType ft = getFeedType(col.getStringValue()); - toAdd.setType(ft); - } - else if (col.getName().compareTo("Uri") == 0) - toAdd.setUri(col.getStringValue()); - else if (col.getName().compareTo("UriThumbnail") == 0) - toAdd.setUriThumbnail(col.getStringValue()); - else if (col.getName().compareTo("Vreid") == 0) - toAdd.setVreid(col.getStringValue()); - else if (col.getName().compareTo("Entityid") == 0) - toAdd.setEntityId(col.getStringValue()); - else if (col.getName().compareTo("CommentsNo") == 0) - toAdd.setCommentsNo(col.getStringValue()); - else if (col.getName().compareTo("LikesNo") == 0) - toAdd.setLikesNo(col.getStringValue()); - else if (col.getName().compareTo("LinkDescription") == 0) - toAdd.setLinkDescription(col.getStringValue()); - else if (col.getName().compareTo("LinkHost") == 0) - toAdd.setLinkHost(col.getStringValue()); - else if (col.getName().compareTo("LinkTitle") == 0) - toAdd.setLinkTitle(col.getStringValue()); - else if (col.getName().compareTo("IsApplicationFeed") == 0) - toAdd.setApplicationFeed(col.getBooleanValue()); - else { - _log.warn("getAllPortalPrivacyLevelFeeds(): Could not assign variable to this Feed for column name: " + col.getName()); - } - } - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) - toReturn.add(toAdd); - } - } catch (ConnectionException e) { - e.printStackTrace(); - return toReturn; - } - return toReturn; - } - @Override - public List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { - ArrayList toReturn = new ArrayList(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Feeds) - .searchWithIndex() - .setLimit(20) // Number of rows returned - .addExpression() - .whereColumn("Privacy").equals().value(PrivacyLevel.PORTAL.toString()) - .execute(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - Post toAdd = new Post(); - toAdd.setKey(row.getKey()); - for (Column col : row.getColumns()) { - if (col.getName().compareTo("Description") == 0) - toAdd.setDescription(col.getStringValue()); - else if (col.getName().compareTo("FullName") == 0) - toAdd.setFullName(col.getStringValue()); - else if (col.getName().compareTo("Email") == 0) - toAdd.setEmail(col.getStringValue()); - else if (col.getName().compareTo("Privacy") == 0) - toAdd.setPrivacy(getPrivacyLevel(col.getStringValue())); - else if (col.getName().compareTo("ThumbnailURL") == 0) - toAdd.setThumbnailURL(col.getStringValue()); - else if (col.getName().compareTo("Time") == 0) - toAdd.setTime(getDateFromTimeInMillis(col.getStringValue())); - else if (col.getName().compareTo("Type") == 0) { - PostType ft = getPostType(col.getStringValue()); - toAdd.setType(ft); - } - else if (col.getName().compareTo("Uri") == 0) - toAdd.setUri(col.getStringValue()); - else if (col.getName().compareTo("UriThumbnail") == 0) - toAdd.setUriThumbnail(col.getStringValue()); - else if (col.getName().compareTo("Vreid") == 0) - toAdd.setVreid(col.getStringValue()); - else if (col.getName().compareTo("Entityid") == 0) - toAdd.setEntityId(col.getStringValue()); - else if (col.getName().compareTo("CommentsNo") == 0) - toAdd.setCommentsNo(col.getStringValue()); - else if (col.getName().compareTo("LikesNo") == 0) - toAdd.setLikesNo(col.getStringValue()); - else if (col.getName().compareTo("LinkDescription") == 0) - toAdd.setLinkDescription(col.getStringValue()); - else if (col.getName().compareTo("LinkHost") == 0) - toAdd.setLinkHost(col.getStringValue()); - else if (col.getName().compareTo("LinkTitle") == 0) - toAdd.setLinkTitle(col.getStringValue()); - else if (col.getName().compareTo("IsApplicationFeed") == 0) - toAdd.setApplicationFeed(col.getBooleanValue()); - else { - _log.warn("getAllPortalPrivacyLevelFeeds(): Could not assign variable to this Feed for column name: " + col.getName()); - } - } - if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) - toReturn.add(toAdd); - } - } catch (ConnectionException e) { - e.printStackTrace(); - return toReturn; - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - @Deprecated - public List getRecentFeedsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - ArrayList feedIDs = getUserFeedIds(userid); - //check if quantity is greater than user feeds - quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity; - - //need them in reverse order - for (int i = feedIDs.size()-1; i >= (feedIDs.size()-quantity); i--) { - Feed toAdd = readFeed(feedIDs.get(i)); - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) { - toReturn.add(toAdd); - _log.trace("Read recent feed: " + feedIDs.get(i)); - } else { - _log.trace("Read and skipped feed: " + feedIDs.get(i) + " (Removed Feed)"); - quantity += 1; //increase the quantity in case of removed feed - //check if quantity is greater than user feeds - quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity; - } - } - return toReturn; - } - @Override - public List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - ArrayList postIDs = getUserPostIds(userid); - //check if quantity is greater than user feeds - 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 feeds - quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - @Deprecated - public List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getFeedsByIds(getVREFeedIds(vreid)); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - return getPostsByIds(getVREPostIds(vreid)); - } - /** - * {@inheritDoc} - */ - @Deprecated - @Override - public List getRecentFeedsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - ArrayList feedIDs = getVREFeedIds(vreid); - //check if quantity is greater than user feeds - quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity; - - //need them in reverse order - for (int i = feedIDs.size()-1; i >= (feedIDs.size()-quantity); i--) { - Feed toAdd = readFeed(feedIDs.get(i)); - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) { - toReturn.add(toAdd); - _log.trace("Read recent feed: " + feedIDs.get(i)); - } else { - _log.trace("Read and skipped feed: " + feedIDs.get(i) + " (Removed Feed) ."); - quantity += 1; //increase the quantity in case of removed feed - //check if quantity is greater than user feeds - quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity; - } - } - return toReturn; - } - @Override - public List getRecentPostsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - 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 RangeFeeds getRecentFeedsByVREAndRange(String vreid, int from, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - if (from < 1) { - throw new IllegalArgumentException("From must be greather than 0"); - } - ArrayList feedsToReturn = new ArrayList(); - ArrayList feedIDs = getVREFeedIds(vreid); - - //if from is greater than feeds size return empty - if (from >= feedIDs.size()) { - _log.warn("The starting point of the range is greather than the total number of feeds for this timeline: " + from + " >= " + feedIDs.size()); - return new RangeFeeds(); - } - - int rangeStart = feedIDs.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--) { - Feed toAdd = readFeed(feedIDs.get(i)); - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) { - feedsToReturn.add(toAdd); - _log.trace("Read recent feed, i=" + i + " id= " + feedIDs.get(i)); - } else { - _log.trace("Read and skipped feed, i=" + i + " id=: " + feedIDs.get(i) + " (Removed Feed) ."); - rangeEnd -= 1; //increase the upTo in case of removed feed - //check if quantity is greater than user feeds - rangeEnd = (rangeEnd > 0) ? rangeEnd : 0; - } - howMany++; - } - _log.debug("AFTER: starting Point==" + rangeStart + " rangeEnd= " + rangeEnd); - return new RangeFeeds(howMany+1, feedsToReturn); - } - /** - * {@inheritDoc} - */ - @Override - public RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - if (from < 1) { - throw new IllegalArgumentException("From must be greather than 0"); - } - ArrayList feedsToReturn = new ArrayList(); - ArrayList feedIDs = getVREPostIds(vreid); - - //if from is greater than feeds size return empty - if (from >= feedIDs.size()) { - _log.warn("The starting point of the range is greather than the total number of feeds for this timeline: " + from + " >= " + feedIDs.size()); - return new RangePosts(); - } - - int rangeStart = feedIDs.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(feedIDs.get(i)); - if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { - feedsToReturn.add(toAdd); - _log.trace("Read recent post, i=" + i + " id= " + feedIDs.get(i)); - } else { - _log.trace("Read and skipped post, i=" + i + " id=: " + feedIDs.get(i) + " (Removed post) ."); - rangeEnd -= 1; //increase the upTo in case of removed feed - //check if quantity is greater than user feeds - rangeEnd = (rangeEnd > 0) ? rangeEnd : 0; - } - howMany++; - } - _log.debug("AFTER: starting Point==" + rangeStart + " rangeEnd= " + rangeEnd); - return new RangePosts(howMany+1, feedsToReturn); - } - /** - * @deprecated - * get a list of user vre feed UUIDs in chronological order from the oldest to the more recent - * @param vreid vreid identifier (scope) - * @return simply return a list of user vre feed UUIDs in chronological order from the oldest to the more recent - */ - private ArrayList getVREFeedIds(String vreid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_VRETline) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - /** - * 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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_VRETline) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - /* - * - ********************** NOTIFICATIONS *********************** - * - */ - /** - * {@inheritDoc} - */ - @Override - public boolean saveNotification(Notification n) { - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Notifications, n.getKey().toString()) - .putColumn("Type", n.getType().toString(), null) - .putColumn("Userid", n.getUserid(), null) - .putColumn("Subjectid", n.getSubjectid(), null) - .putColumn("Time", n.getTime().getTime()+"", null) - .putColumn("Uri", n.getUri(), null) - .putColumn("Description", n.getDescription(), null) - .putColumn("Read", n.isRead(), null) - .putColumn("Senderid", n.getSenderid(), null) - .putColumn("SenderFullName", n.getSenderFullName(), null) - .putColumn("SenderThumbnail", n.getSenderThumbnail(), null); - - //an entry in the user Notifications Timeline - m.withRow(cf_UserNotifications, n.getUserid()).putColumn(n.getTime().getTime()+"", n.getKey().toString(), null); - - // save key in the unread notifications column family too - m.withRow(cf_UserNotificationsUnread, n.getUserid()).putColumn(n.getTime().getTime()+"", n.getKey().toString(), null); - - return execute(m); - } - - /** - * {@inheritDoc} - */ - @Override - public Notification readNotification(String notificationid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException { - Notification toReturn = new Notification(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Notifications) - .getKey(notificationid) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { - throw new NotificationIDNotFoundException("The requested notificationid: " + notificationid + " is not existing"); - } - - toReturn.setKey(notificationid); - NotificationType nt = getNotificationType(columns.getColumnByName("Type").getStringValue()); - toReturn.setType(nt); - toReturn.setUserid(columns.getColumnByName("Userid").getStringValue()); - toReturn.setSubjectid(columns.getColumnByName("Subjectid").getStringValue()); - toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Time").getStringValue())); - toReturn.setUri(columns.getColumnByName("Uri").getStringValue()); - toReturn.setDescription(columns.getColumnByName("Description").getStringValue()); - toReturn.setRead(columns.getColumnByName("Read").getBooleanValue()); - toReturn.setSenderid(columns.getColumnByName("Senderid").getStringValue()); - toReturn.setSenderFullName(columns.getColumnByName("SenderFullName").getStringValue()); - toReturn.setSenderThumbnail(columns.getColumnByName("SenderThumbnail").getStringValue()); - - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - 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"); - - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - - //set as read - m.withRow(cf_Notifications, notificationidToSet).putColumn("Read", true, null); - - // delete the notification's key from the unread notifications column family - m.withRow(cf_UserNotificationsUnread, toSet.getUserid()).deleteColumn(toSet.getTime().getTime()+""); - - // execute the operations - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("ERROR while setting Notification " + notificationidToSet + " to read."); - return false; - } - _log.trace("Notification Set read OK to"); - return true; - } - /** - * - * @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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserNotifications) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - 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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserNotificationsUnread) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - 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 feeds - 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 feeds size return empty - if (from >= notificationsIDs.size()) { - _log.warn("The starting point of the range is greather than the total number of feeds 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.trace("Asking for Single Notification preference of " + userid + " Type: " + notificationType); - List toReturn = new ArrayList(); - NotificationChannelType[] toProcess = getUserNotificationPreferences(userid).get(notificationType); - if (toProcess == null) { - _log.warn("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(); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - 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 - } - m.withRow(cf_UserNotificationsPreferences, userid).putColumn(notificationType.toString(), valueToInsert, null); - boolean overAllresult = execute(m); - if (overAllresult) { - _log.trace("Set New Notification Setting for " + userid + " OK"); - return toReturn; - } - return new ArrayList(); //no notification if sth fails - } - /** - * {@inheritDoc} - */ - @Override - public boolean setUserNotificationPreferences(String userid, Map enabledChannels) { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - - for (NotificationType nType : enabledChannels.keySet()) { - String valueToInsert = ""; - int channelsNo = (enabledChannels.get(nType) != null) ? enabledChannels.get(nType).length : 0; - for (int i = 0; i < channelsNo; i++) { - valueToInsert += enabledChannels.get(nType)[i]; - if (i < channelsNo-1) - valueToInsert += ","; - } - if (channelsNo == 0) { //in case no channels were selected - valueToInsert = ""; - _log.trace("No Channels selected for " + nType + " by " + userid); - } - m.withRow(cf_UserNotificationsPreferences, userid).putColumn(nType.toString(), valueToInsert, null); - } - - boolean overAllresult = execute(m); - if (overAllresult) - _log.trace("Set Notification Map for " + userid + " OK"); - else - _log.trace("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(); - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserNotificationsPreferences) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - //if there are no settings for this user create an entry and put all of them at true - if (result.getResult().getRowByIndex(0).getColumns().size() == 0) { - _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 : result.getResult()) - for (Column column : row.getColumns()) { - String[] channels = column.getStringValue().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(column.getName()), 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(column.getName()), toAdd); - } - } - } - return toReturn; - } - /* - * - ********************** COMMENTS *********************** - * - */ - /** - * {@inheritDoc} - */ - @Override - public boolean addComment(Comment comment) throws FeedIDNotFoundException { - Feed toComment = null; - if (comment == null) - throw new NullArgumentException("Comment must be not null"); - if (comment.getFeedid() == null) - throw new NullArgumentException("Comment feed id must be not null"); - - String feedId = comment.getFeedid(); - try { - toComment = readFeed(feedId); - if (toComment == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId + " to associate this comment", feedId); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the Comment CF - m.withRow(cf_Comments, comment.getKey().toString()) - .putColumn("Text", comment.getText(), null) - .putColumn("Timestamp", comment.getTime().getTime()+"", null) - .putColumn("Userid", comment.getUserid(), null) - .putColumn("Feedid",comment.getFeedid(), null) - .putColumn("FullName",comment.getFullName(), null) - .putColumn("ThumbnailURL", comment.getThumbnailURL(), null) - .putColumn("IsEdited", comment.isEdit(), null); - - try { - m.execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return false; - } - //update the comment count - boolean updateCommentNoResult = updateFeedCommentsCount(toComment, true); - return updateCommentNoResult; - } - /** - * {@inheritDoc} - */ - public Comment readCommentById(String commentId) throws CommentIDNotFoundException { - Comment toReturn = new Comment(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Comments) - .getKey(commentId) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { - throw new CommentIDNotFoundException("The requested commentId: " + commentId + " is not existing"); - } - - toReturn.setKey(commentId); - toReturn.setText(columns.getColumnByName("Text").getStringValue()); - toReturn.setFullName(columns.getColumnByName("FullName").getStringValue()); - if(columns.getColumnByName("IsEdited") != null) - toReturn.setEdit(columns.getColumnByName("IsEdited").getBooleanValue()); - toReturn.setFeedid(columns.getColumnByName("Feedid").getStringValue()); - toReturn.setUserid(columns.getColumnByName("Userid").getStringValue()); - toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Timestamp").getStringValue())); - toReturn.setThumbnailURL(columns.getColumnByName("ThumbnailURL").getStringValue()); - if (columns.getColumnByName("LastEditTime") != null) - toReturn.setLastEditTime(getDateFromTimeInMillis(columns.getColumnByName("LastEditTime").getStringValue())); - - } catch (ConnectionException e) { - _log.debug(e.toString()); - return null; - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - @Deprecated - public List getAllCommentByFeed(String feedid) { - return getAllCommentByPost(feedid); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllCommentByPost(String postid) { - List toReturn = new ArrayList(); - - PreparedIndexExpression clause = cf_Comments.newIndexClause().whereColumn("Feedid").equals().value(postid); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Comments) - .searchWithIndex() - .setStartKey("") - .addPreparedExpressions(Arrays.asList(clause)) - .execute(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - Comment toAdd = new Comment(); - toAdd.setKey(row.getKey()); - for (Column col : row.getColumns()) { - if (col.getName().compareTo("Text") == 0) - toAdd.setText(col.getStringValue()); - else if (col.getName().compareTo("FullName") == 0) - toAdd.setFullName(col.getStringValue()); - else if (col.getName().compareTo("Timestamp") == 0) - toAdd.setTime(getDateFromTimeInMillis(col.getStringValue())); - else if (col.getName().compareTo("Userid") == 0) - toAdd.setUserid(col.getStringValue()); - else if (col.getName().compareTo("ThumbnailURL") == 0) - toAdd.setThumbnailURL(col.getStringValue()); - else if (col.getName().compareTo("Feedid") == 0) - toAdd.setFeedid(col.getStringValue()); - else if(col.getName().compareTo("IsEdited") == 0) - toAdd.setEdit(col.getBooleanValue()); - else if(col.getName().compareTo("LastEditTime") == 0) - toAdd.setLastEditTime(getDateFromTimeInMillis(col.getStringValue())); - else { - _log.error("getAllCommentByPost(): Could not assign variable to this Comment for column name: " + col.getName()); - } - } - toReturn.add(toAdd); - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - 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 - * @throws ConnectionException - */ - private List getRecentCommentsByUserAndDateBody(final String userid, - final long timeInMillis, boolean sort) throws ConnectionException{ - - final List commentsByUser = new ArrayList(); - final AtomicInteger maxRetryExecutions = new AtomicInteger(10); - - /** - * See https://github.com/Netflix/astyanax/wiki/Reading-Data for more information (Query all with callback) - */ - conn.getKeyspace().prepareQuery(cf_Comments) - .getAllRows() - .setRowLimit(100) // Read in blocks of 100 - .withColumnRange(new RangeBuilder().setLimit(10).build()) - .executeWithCallback(new RowCallback() { - @Override - public void success(Rows rows) { - - // use a temporary list for each thread - List partialCommentsList = new ArrayList(); - - nextRow: for (Row row : rows) { - for(Column column: row.getColumns()){ - if(column.getName().equals("Userid")){ - if(column.getStringValue().equals(userid)){ - try{ - Comment c = readCommentById(row.getKey()); - Feed f = readFeed(c.getFeedid()); - if(c.getTime().getTime() >= timeInMillis && - (f.getType() == FeedType.TWEET || f.getType() == FeedType.SHARE || f.getType() == FeedType.PUBLISH)) - partialCommentsList.add(c); - }catch(Exception e){ - _log.error("Unable to read comment with id" + row.getKey(), e); - } - } - continue nextRow; - } - } - } - - // if there is something to save... - if(partialCommentsList.size() > 0){ - synchronized (commentsByUser){ - commentsByUser.addAll(partialCommentsList); - } - } - } - - @Override - public boolean failure(ConnectionException e) { - // decrement value - int currentValue = maxRetryExecutions.decrementAndGet(); - if(currentValue <= 0){ - _log.error("Too many errors while fetching user's comments, exiting"); - return false; - }else{ - _log.error("Error while fetching user's recent comments ... repeating operation"); - return true; - } - } - }); - - if(sort) - Collections.sort(commentsByUser, Collections.reverseOrder()); - - return commentsByUser; - - } - - /** - * {@inheritDoc} - */ - @Override - public boolean editComment(Comment comment2Edit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Comments, comment2Edit.getKey().toString()).putColumn("Text", comment2Edit.getText(), null); - m.withRow(cf_Comments, comment2Edit.getKey().toString()).putColumn("IsEdited", comment2Edit.isEdit(), null); - m.withRow(cf_Comments, comment2Edit.getKey().toString()).putColumn("LastEditTime", comment2Edit.getLastEditTime().getTime() + "", null); - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Comments update NOT OK "); - return false; - } - _log.info("Comments update OK to: " + comment2Edit.getText()); - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean deleteComment(String commentid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException { - Feed toUpdate = readFeed(feedid); - boolean updateCommentNoResult = false; - - updateCommentNoResult = updateFeedCommentsCount(toUpdate, false); - if (updateCommentNoResult) { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_Comments, commentid) - .delete(); - - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Comment Delete FAILED for " + commentid + " from Feed " + feedid); - e.printStackTrace(); - } - _log.trace("Comment Deleted " + commentid + " from Feed " + feedid); - } - - - return updateCommentNoResult; - } - /** - * {@inheritDoc} - */ - @Override - public boolean like(Like like) throws FeedIDNotFoundException { - Feed toLike = null; - if (like == null) - throw new NullArgumentException("Like must be not null"); - if (like.getFeedid() == null) - throw new NullArgumentException("Like feed id must be not null"); - - String feedId = like.getFeedid(); - try { - toLike = readFeed(feedId); - if (toLike == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId + " to associate this like", feedId); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - if (isFeedLiked(like.getUserid(), feedId)) { - _log.info("User " + like.getUserid() + " already liked Feed " + feedId); - return true; - } - else { - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Likes, like.getKey().toString()) - .putColumn("Timestamp", like.getTime().getTime()+"", null) - .putColumn("Userid", like.getUserid(), null) - .putColumn("Feedid",like.getFeedid(), null) - .putColumn("FullName",like.getFullName(), null) - .putColumn("ThumbnailURL", like.getThumbnailURL(), null); - //and an entry in the UserLikesCF - m.withRow(cf_UserLikedFeeds, like.getUserid()).putColumn(like.getKey(), like.getFeedid(), null); - - try { - m.execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return false; - } - return updateFeedLikesCount(toLike, true); - } - } - /** - * {@inheritDoc} - */ - @Override - public boolean unlike(String userid, String likeid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, FeedIDNotFoundException { - Feed toUpdate = readFeed(feedid); - boolean updateLikeNoResult = false; - - updateLikeNoResult = updateFeedLikesCount(toUpdate, false); //this remove 1 from the Feed CF LikeNO - if (updateLikeNoResult) { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //delete the row from LikesCF - m.withRow(cf_Likes, likeid).delete(); - //delete the column from UserLikes - m.withRow(cf_UserLikedFeeds, userid).deleteColumn(likeid); - - - - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Like Delete FAILED for " + likeid + " from Feed " + feedid); - e.printStackTrace(); - } - _log.trace("Unlike ok for " + likeid + " from Feed " + feedid); - } - return updateLikeNoResult; - } - /** - * {@inheritDoc} - */ - @Override - @Deprecated - public List getAllLikedFeedIdsByUser(String userid) { - return getAllLikedPostIdsByUser(userid); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllLikedPostIdsByUser(String userid) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_UserLikedFeeds) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public List getAllLikedFeedsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - List likedFeedIDs = getAllLikedFeedIdsByUser(userid); - - //check if quantity is greater than user feeds - limit = (limit > likedFeedIDs.size()) ? likedFeedIDs.size() : limit; - - //need them in reverse order - for (int i = likedFeedIDs.size()-1; i >= (likedFeedIDs.size()-limit); i--) { - Feed toAdd = readFeed(likedFeedIDs.get(i)); - if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) { - toReturn.add(toAdd); - _log.trace("Read recent feed: " + likedFeedIDs.get(i)); - } else { - _log.trace("Read and skipped feed: " + likedFeedIDs.get(i) + " (Removed Feed)"); - limit += 1; //increase the quantity in case of removed feed - //check if quantity is greater than user feeds - limit = (limit > likedFeedIDs.size()) ? likedFeedIDs.size() : limit; - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - List likedPostIDs = getAllLikedPostIdsByUser(userid); - - //check if quantity is greater than user feeds - 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 feed - //check if quantity is greater than user feeds - limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; - } - } - return toReturn; - } - - /** - * {@inheritDoc} - */ - @Override - public List getRecentLikedFeedsByUserAndDate(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 feeds - List likedFeedsIdsByUser = getAllLikedFeedIdsByUser(userid); - - if(likedFeedsIdsByUser != null && !likedFeedsIdsByUser.isEmpty()){ - for(int i = likedFeedsIdsByUser.size() - 1; i >= 0; i--){ - String feedId = likedFeedsIdsByUser.get(i); - try{ - - // retrieve the feed - Feed toCheck = readFeed(feedId); - boolean isFeedOk = (toCheck.getType() == FeedType.TWEET || toCheck.getType() == FeedType.SHARE || toCheck.getType() == FeedType.PUBLISH); - - // retrieve the like of the user for the feed - if(isFeedOk){ - List likes = getAllLikesByPost(feedId); - for (Like like : likes) { - if(like.getTime().getTime() >= timeInMillis && like.getUserid().equals(userid)) - toReturn.add(toCheck); - } - } - - }catch(Exception e){ - _log.error("Skipped feed with id " + feedId, 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 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 feeds - 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} - */ - @Deprecated - @Override - public List getAllLikesByFeed(String feedid) { - return getAllLikesByPost(feedid); - } - /** - * {@inheritDoc} - */ - @Override - public List getAllLikesByPost(String postid) { - List toReturn = new ArrayList(); - OperationResult> result; - PreparedIndexExpression clause = cf_Likes.newIndexClause().whereColumn("Feedid").equals().value(postid); - try { - result = conn.getKeyspace().prepareQuery(cf_Likes) - .searchWithIndex() - .setStartKey("") - .addPreparedExpressions(Arrays.asList(clause)) - .execute(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - Like toAdd = new Like(); - toAdd.setKey(row.getKey()); - for (Column col : row.getColumns()) { - if (col.getName().compareTo("FullName") == 0) - toAdd.setFullName(col.getStringValue()); - else if (col.getName().compareTo("Timestamp") == 0) - toAdd.setTime(getDateFromTimeInMillis(col.getStringValue())); - else if (col.getName().compareTo("Userid") == 0) - toAdd.setUserid(col.getStringValue()); - else if (col.getName().compareTo("ThumbnailURL") == 0) - toAdd.setThumbnailURL(col.getStringValue()); - else if (col.getName().compareTo("Feedid") == 0) - toAdd.setFeedid(col.getStringValue()); - else { - _log.error("getAllLikesByPost(): Could not assign variable to this Like for column name: " + col.getName()); - } - } - toReturn.add(toAdd); - } - } catch (ConnectionException e) { - e.printStackTrace(); - } - return toReturn; - } - /* - * - ********************** HASHTAGS *********************** - * - */ - /** - * {@inheritDoc} - */ - @Override - public boolean saveHashTags(String feedid, String vreid, List hashtags) throws FeedIDNotFoundException { - Set noduplicatesHashtags = null; - if (hashtags != null && !hashtags.isEmpty()) { - noduplicatesHashtags = new HashSet(hashtags); - } - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - for (String hashtag : noduplicatesHashtags) { - String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineFeed, lowerCaseHashtag).putColumn(feedid, vreid, null); - boolean firstInsert = execute(m); - 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 feedid, String vreid, List hashtags) throws FeedIDNotFoundException { - Set noduplicatesHashtags = null; - if (hashtags != null && !hashtags.isEmpty()) { - noduplicatesHashtags = new HashSet(hashtags); - } - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - for (String hashtag : noduplicatesHashtags) { - String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineFeed, lowerCaseHashtag).deleteColumn(feedid); - boolean firstDelete = execute(m); - 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 - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - for (String hashtag : noduplicatesHashtags) { - String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineComment, lowerCaseHashtag).putColumn(commentId, vreid, null); - boolean firstInsert = execute(m); - 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 - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - for (String hashtag : noduplicatesHashtags) { - String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineComment, lowerCaseHashtag).deleteColumn(commentId); - boolean firstDelete = execute(m); - 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) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_HashtagsCounter) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - HashMap toReturn = new HashMap (); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - int curValue = Integer.parseInt(column.getStringValue()); - if (curValue > 0) - toReturn.put(column.getName(), curValue); - } - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp){ - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_HashtagsCounter) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - - HashMap toReturn = new HashMap (); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - - // retrieve the feeds list for this hashtag - List feeds = null; - try{ - feeds = getVREFeedsByHashtag(vreid, column.getName()); - }catch(Exception e){ - _log.error("Unable to retrieve the list of feeds for hashtag" + column.getName() + " in vre " + vreid); - continue; - } - - if(feeds.isEmpty()){ - - _log.info("There are no feeds containing hashtag " + column.getName() + " in vre " + vreid); - continue; - - } - - // retrieve the most recent one among these feeds - Collections.sort(feeds, Collections.reverseOrder()); - - if(feeds.get(0).getTime().getTime() < timestamp){ - continue; - } - - // else.. - int curValue = Integer.parseInt(column.getStringValue()); - - if (curValue > 0) - toReturn.put(column.getName(), curValue); - } - } - return toReturn; - } - - /** - * {@inheritDoc} - */ - @Override - public List getVREFeedsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - List toReturn = new ArrayList(); - OperationResult> resultFeed = null; - OperationResult> resultComment = null; - try { - resultFeed = conn.getKeyspace().prepareQuery(cf_HashtagTimelineFeed) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - try { - resultComment = conn.getKeyspace().prepareQuery(cf_HashtagTimelineComment) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - Set feedIds = new HashSet(); - // Iterate rows and their columns (feed) - for (Row row : resultFeed.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(vreid)==0) - feedIds.add(column.getName()); - } - } - // Iterate rows and their columns (comments) - for (Row row : resultComment.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(vreid)==0){ - try { - Comment c = readCommentById(column.getName()); - feedIds.add(c.getFeedid()); - } catch (CommentIDNotFoundException e) { - _log.warn("Failed to fetch comment with id " + column.getName()); - } - } - } - } - toReturn = getFeedsByIds(new ArrayList(feedIds)); - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - List toReturn = new ArrayList<>(); - OperationResult> resultPost = null; - OperationResult> resultComment = null; - try { - resultPost = conn.getKeyspace().prepareQuery(cf_HashtagTimelineFeed) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - try { - resultComment = conn.getKeyspace().prepareQuery(cf_HashtagTimelineComment) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - Set postIds = new HashSet<>(); - // Iterate rows and their columns (feed) - for (Row row : resultPost.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(vreid)==0) - postIds.add(column.getName()); - } - } - // Iterate rows and their columns (comments) - for (Row row : resultComment.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(vreid)==0){ - try { - Comment c = readCommentById(column.getName()); - postIds.add(c.getFeedid()); - } catch (CommentIDNotFoundException e) { - _log.warn("Failed to fetch comment with id " + column.getName()); - } - } - } - } - toReturn = getPostsByIds(new ArrayList(postIds)); - return toReturn; - } - /* - * - ********************** Invites *********************** - * - */ - /** - * common part to save a invite - * @param invite - * @return the partial mutation batch instance - */ - private MutationBatch initSaveInvite(Invite invite) { - if (invite == null) - throw new NullArgumentException("Invite instance is null"); - // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the invite CF - m.withRow(cf_Invites, invite.getKey().toString()) - .putColumn("SenderUserId", invite.getSenderUserId(), null) - .putColumn("Vreid", invite.getVreid(), null) - .putColumn("InvitedEmail", invite.getInvitedEmail(), null) - .putColumn("ControlCode", invite.getControlCode(), null) - .putColumn("Status", invite.getStatus().toString(), null) - .putColumn("Time", invite.getTime().getTime()+"", null) - .putColumn("SenderFullName", invite.getSenderFullName(), null); - return m; - } - - /** - * {@inheritDoc} - */ - @Override - public String isExistingInvite(String vreid, String email) { - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_EmailInvites) - .getKeySlice(email) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - if (column.getName().compareTo(vreid)==0) - return column.getStringValue(); - } - } - 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 ..."); - - MutationBatch m = initSaveInvite(invite); - //an entry in the VRE Invites - m.withRow(cf_VREInvites, invite.getVreid()) - .putColumn(invite.getKey().toString(), InviteStatus.PENDING.toString(), null); - - //an entry in the EMAIL Invites - m.withRow(cf_EmailInvites, email) - .putColumn(invite.getVreid(), invite.getKey().toString(), null); - boolean result = execute(m); - return result ? InviteOperationResult.SUCCESS : InviteOperationResult.FAILED; - } - /** - * {@inheritDoc} - */ - @Override - public Invite readInvite(String inviteid) throws InviteIDNotFoundException, InviteStatusNotFoundException { - Invite toReturn = new Invite(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Invites) - .getKey(inviteid) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { - throw new InviteStatusNotFoundException("The requested inviteid: " + inviteid + " is not existing"); - } - - toReturn.setKey(inviteid); - toReturn.setSenderUserId(columns.getColumnByName("SenderUserId").getStringValue()); - toReturn.setVreid(columns.getColumnByName("Vreid").getStringValue()); - toReturn.setInvitedEmail(columns.getColumnByName("InvitedEmail").getStringValue()); - toReturn.setControlCode(columns.getColumnByName("ControlCode").getStringValue()); - InviteStatus status = getInviteStatusType(columns.getColumnByName("Status").getStringValue()); - toReturn.setStatus(status); - toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Time").getStringValue())); - toReturn.setSenderFullName(columns.getColumnByName("SenderFullName").getStringValue()); - - } catch (ConnectionException e) { - e.printStackTrace(); - return null; - } - 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"); - - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //update in the Invites Static CF - m.withRow(cf_Invites, inviteid).putColumn("Status", status.toString(), null); - //updated in the VREInvites Dynamic CF - m.withRow(cf_VREInvites, toSet.getVreid()).putColumn(inviteid, status.toString(), null); - try { - m.execute(); - } catch (ConnectionException 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{ - OperationResult> result = null; - try { - result = conn.getKeyspace().prepareQuery(cf_VREInvites) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - } - ArrayList invitesIds = new ArrayList(); - // Iterate rows and their columns - for (Row row : result.getResult()) { - if (status != null) { - for (Column column : row.getColumns()) { - for (int i = 0; i < status.length; i++) { - if (column.getStringValue().compareTo(status[i].toString())==0) - invitesIds.add(column.getName()); - } - - } - } - else { - for (Column column : row.getColumns()) - invitesIds.add(column.getName()); - } - } - return getInvitesById(invitesIds); - } - /** - * {@inheritDoc} - */ - @Override - public List getAttachmentsByFeedId(String feedId) throws FeedIDNotFoundException { - Feed toCheck = null; - try { - toCheck = readFeed(feedId); - if (toCheck == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId, feedId); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - List toReturn = new ArrayList(); - - PreparedIndexExpression clause = cf_Attachments.newIndexClause().whereColumn("feedId").equals().value(feedId); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Attachments) - .searchWithIndex() - .setStartKey("") - .addPreparedExpressions(Arrays.asList(clause)) - .execute(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - Attachment toAdd = new Attachment(); - toAdd.setId(row.getKey()); - for (Column col : row.getColumns()) { - if (col.getName().compareTo("feedId") == 0) - _log.trace("Reading attachment if feed=" + col.getStringValue()); - else if (col.getName().compareTo("uri") == 0) - toAdd.setUri(col.getStringValue()); - else if (col.getName().compareTo("name") == 0) - toAdd.setName(col.getStringValue()); - else if (col.getName().compareTo("description") == 0) - toAdd.setDescription(col.getStringValue()); - else if (col.getName().compareTo("thumbnailURL") == 0) - toAdd.setThumbnailURL(col.getStringValue()); - else if (col.getName().compareTo("mimeType") == 0) - toAdd.setMimeType(col.getStringValue()); - else { - _log.error("getAttachmentsByFeedId(): Could not assign variable to this Attachment for column name: " + col.getName()); - } - } - toReturn.add(toAdd); - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - return toReturn; - } - /** - * {@inheritDoc} - */ - @Override - public void closeConnection() { - conn.closeConnection(); - } - /* - * - ********************** 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 - m.withRow(cf_Attachments, toSave.getId()) - .putColumn("feedId", feedId, null) - .putColumn("uri", toSave.getUri(), null) - .putColumn("name", toSave.getName(), null) - .putColumn("description",toSave.getDescription(), null) - .putColumn("thumbnailURL",toSave.getThumbnailURL(), null) - .putColumn("mimeType",toSave.getMimeType(), null); - try { - m.execute(); - } catch (ConnectionException e) { - e.printStackTrace(); - return false; - } - return true; - } - - - /** - * simply return an enum representing the privacy level - * @param privacyLevel . - * @return correct enum representing the privacy level - * @throws NotificationChannelTypeNotFoundException - * @throws FeedTypeNotFoundException - */ - 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 FeedTypeNotFoundException - */ - private 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 feed type - * @param type . - * @return correct enum representing the feed type - * @throws TypeNotFoundException . - */ - private FeedType getFeedType(String type) throws FeedTypeNotFoundException { - if (type.compareTo("TWEET") == 0) { - return FeedType.TWEET; - } - else if (type.compareTo("JOIN") == 0) { - return FeedType.JOIN; - } - else if (type.compareTo("PUBLISH") == 0) { - return FeedType.PUBLISH; - } - else if (type.compareTo("SHARE") == 0) { - return FeedType.SHARE; - } - else if (type.compareTo("ACCOUNTING") == 0) { - return FeedType.ACCOUNTING; - } - else if (type.compareTo("DISABLED") == 0) { - return FeedType.DISABLED; - } - else - throw new FeedTypeNotFoundException("The Feed Type was not recognized should be one of " + FeedType.values() + " asked for: " + type); - } - /** - * simply return an enum representing the feed type - * @param type . - * @return correct enum representing the feed type - * @throws TypeNotFoundException . - */ - private PostType getPostType(String type) throws FeedTypeNotFoundException { - 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 FeedTypeNotFoundException("The Feed 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 feed type - * @throws TypeNotFoundException . - */ - private 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 feed type - * @param type . - * @return correct enum representing the feed type - * @throws TypeNotFoundException . - */ - private 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 feed by incrementing or decrementing by (1) the CommentsNo - * used when adding or removing a comment to a feed - * @param toUpdate the feedid - * @param increment set true if you want to add 1, false to subtract 1. - */ - private boolean updateFeedCommentsCount(Feed 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()); - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Feeds, toUpdate.getKey().toString()).putColumn("CommentsNo", ""+newCount, null); - try { - m.execute(); - } catch (ConnectionException e) { - _log.error("CommentsNo update NOT OK "); - return false; - } - _log.info("CommentsNo update OK to: " + newCount); - return true; - } - - /** - * update the feed by incrementing or decrementing by (1) the LikesNo - * used when adding or removing a comment to a feed - * @param toUpdate the feedid - * @param increment set true if you want to add 1, false to subtract 1. - */ - private boolean updateFeedLikesCount(Feed 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()); - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - //an entry in the feed CF - m.withRow(cf_Feeds, toUpdate.getKey().toString()).putColumn("LikesNo", ""+newCount, null); - try { - m.execute(); - } catch (ConnectionException 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 feed - * @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); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_HashtagsCounter, vreid).putColumn(hashtag, ""+newCount, null); - try { - m.execute(); - } catch (ConnectionException 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() throws ConnectionException{ - - List ids = new ArrayList<>(); - - OperationResult> rows = conn.getKeyspace().prepareQuery(cf_VRETline).getAllRows() - .withColumnRange(new RangeBuilder().setLimit(0).build()) - .execute(); - - Rows res = rows.getResult(); - - for (Row row : res) { - ids.add(row.getKey()); - } - - _log.debug("VRE ids are " + ids); - - return ids; - - } -} diff --git a/src/main/java/org/gcube/portal/databook/server/DBCassandraDatastaxImpl.java b/src/main/java/org/gcube/portal/databook/server/DBCassandraDatastaxImpl.java new file mode 100644 index 0000000..bf8d97d --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/server/DBCassandraDatastaxImpl.java @@ -0,0 +1,2539 @@ +package org.gcube.portal.databook.server; + +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; + +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.portal.databook.shared.Attachment; +import org.gcube.portal.databook.shared.Comment; +import org.gcube.portal.databook.shared.Invite; +import org.gcube.portal.databook.shared.InviteOperationResult; +import org.gcube.portal.databook.shared.InviteStatus; +import org.gcube.portal.databook.shared.Like; +import org.gcube.portal.databook.shared.Notification; +import org.gcube.portal.databook.shared.NotificationChannelType; +import org.gcube.portal.databook.shared.NotificationType; +import org.gcube.portal.databook.shared.Post; +import org.gcube.portal.databook.shared.PostType; +import org.gcube.portal.databook.shared.PrivacyLevel; +import org.gcube.portal.databook.shared.RangePosts; +import org.gcube.portal.databook.shared.ex.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.gcube.portal.databook.server.CassandraClusterConnection.closeSession; +import static org.gcube.portal.databook.server.Schema.*; +import static org.gcube.portal.databook.shared.Notification.getChannelType; +import static org.gcube.portal.databook.shared.Notification.getNotificationType; + +/** + * @author Massimiliano Assante ISTI-CNR + * @author Costantino Perciante ISTI-CNR + * This class is used for querying and adding data to Cassandra via Astyanax High Level API + */ +public final class DBCassandraDatastaxImpl implements DatabookStore { + + /** + * logger + */ + private static final Logger _log = LoggerFactory.getLogger(DBCassandraDatastaxImpl.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 DBCassandraDatastaxImpl(boolean dropSchema) { + conn = new CassandraClusterConnection(dropSchema); + } + /** + * public constructor, no dropping schema is allowed + */ + public DBCassandraDatastaxImpl() { + conn = new CassandraClusterConnection(false); + } + + /** + * public constructor, no dropping schema is allowed, infrastructureName is given. + */ + public DBCassandraDatastaxImpl(String infrastructureName) { + conn = new CassandraClusterConnection(false, infrastructureName); + } + + /* + 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 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()) + .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()); + } + + + /* + * + ********************** FEEDS *********************** + * + */ + /** + * {@inheritDoc} + */ + @Override + public boolean saveUserPost(Post post) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + //an entry in posts + PreparedStatement stmt1 = createPostEntry(session); + writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()), + post.getLinkHost(), + post.getDescription(), + post.getEmail(), + post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null, + post.getThumbnailURL(), + post.getLinkDescription(), + post.getTime()!=null?post.getTime().toInstant():null, + post.getUri(), + post.isApplicationPost(), + post.getEntityId(), + post.getPrivacy()!=null?post.getPrivacy().toString():null, + post.getType()!=null?post.getType().toString():null, + post.getUriThumbnail(), + post.getVreid(), + post.isMultiFileUpload(), + post.getFullName(), + post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null, + post.getLinkTitle())); + + //an entry in the user Timeline + PreparedStatement stmt2 = createUserTimelineEntry(session); + writeBatch.add(stmt2.bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()))); + + //an entry in the VRES Timeline iff vreid field is not empty + if (post.getVreid() != null && post.getVreid().compareTo("") != 0){ + PreparedStatement stmt3 = createVreTimelineEntry(session); + writeBatch.add(stmt3.bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()))); + + } + Boolean result = session.execute(writeBatch).wasApplied(); + if (result){ + _log.info("Wrote user post with id " + post.getKey()); + } + closeSession(session); + + 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) { + 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 saveAppPost(Post post) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + //an entry to posts + PreparedStatement stmt1 = createPostEntry(session); + writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()), + post.getLinkHost(), + post.getDescription(), + post.getEmail(), + post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null, + post.getThumbnailURL(), + post.getLinkDescription(), + post.getTime()!=null?post.getTime().toInstant():null, + post.getUri(), + post.isApplicationPost(), + post.getEntityId(), + post.getPrivacy()!=null?post.getPrivacy().toString():null, + post.getType()!=null?post.getType().toString():null, + post.getUriThumbnail(), + post.getVreid(), + post.isMultiFileUpload(), + post.getFullName(), + post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null, + post.getLinkTitle())); + + + //an entry in the Applications Timeline + PreparedStatement stmt2 = createAppTimelineEntry(session); + writeBatch.add(stmt2.bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()))); + + //an entry in the VRES Timeline iff vreid field is not empty + if (post.getVreid() != null && post.getVreid().compareTo("") != 0){ + PreparedStatement stmt3 = createVreTimelineEntry(session); + writeBatch.add(stmt3.bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()))); + + } + + boolean result = session.execute(writeBatch).wasApplied(); + if (result) + _log.info("Wrote app post with id " + post.getKey()); + closeSession(session); + return result; + } + /** + * {@inheritDoc} + */ + @Override + public boolean saveAppPost(Post post, List attachments) { + if (attachments != null && !attachments.isEmpty()) + post.setMultiFileUpload(true); + boolean saveFeedResult = saveAppPost(post); + if (saveFeedResult) { + String feedKey = post.getKey(); + for (Attachment attachment : attachments) { + boolean attachSaveResult = saveAttachmentEntry(feedKey, 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) { + 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(); + + PreparedStatement stmt3 = createVreTimelineEntry(session); + writeBatch.add(stmt3.bind(vreid, toCheck.getTime().toInstant(), UUID.fromString(toCheck.getKey()))); + closeSession(session); + try{ + boolean res = session.execute(writeBatch).wasApplied(); + closeSession(session); + return res; + }catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + 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(new Post(record)) :Optional.empty(); + } + + /** + * {@inheritDoc} + */ + @Override + public Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + CqlSession session = conn.getKeyspaceSession(); + Post post; + try{ + post = findPostById(postid, session).get(); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + 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)); + closeSession(session); + } catch (Exception e) { + e.printStackTrace(); + } + List toReturn = result.all().stream().map(row-> { + try { + 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) + return toCheck; + } catch (ColumnNameNotFoundException | + PrivacyLevelTypeNotFoundException e) { + throw new RuntimeException(e); + } + } + } catch (RuntimeException e) { + throw new RuntimeException(e); + } + return null; + }).collect(Collectors.toList()); + + return toReturn; + } + + 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()); + } + /** + * {@inheritDoc} + */ + @Override + public boolean deletePost(String postid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + Post toDelete = readPost(postid); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + PreparedStatement stmt1 = updatePostEntry(session, TYPE); + writeBatch.add(stmt1.bind(PostType.DISABLED.toString(), UUID.fromString(toDelete.getKey()))); + + try { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + _log.error("Delete Post ERROR for postid " + postid); + closeSession(session); + return false; + } + _log.info("Delete Post OK"); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + return getPostsByIds(getUserPostIds(userid)); + } + + /** + * {@inheritDoc} + */ + @Override + public List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + 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 feeds' 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 feed with id " + postId, e); + } + } + + Collections.sort(toReturn, Collections.reverseOrder()); + return toReturn; + } + + /** + * helper method that retrieve all the feeds belongin to a list of Ids + * @param postIds + * @return + * @throws ColumnNameNotFoundException + * @throws PrivacyLevelTypeNotFoundException + */ + private List getPostsByIds(List postIds) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + ArrayList toReturn = new ArrayList(); + for (String feedid : postIds) { + Post toAdd = readPost(feedid); + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; + } + + /** + * helper method that return whether the user + * @param userid user identifier + * @param postid the feed identifier + * @return true if the feed 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + boolean flag = false; + + for (Row row: result.all()){ + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; + } + + + @Override + public List getAllPortalPrivacyLevelPosts() throws PrivacyLevelTypeNotFoundException, PostTypeNotFoundException { + //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())); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + for (Row row: result.all()) { + Post toAdd = new Post(row); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) + toReturn.add(toAdd); + } + return toReturn; + } + + @Override + public List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + ArrayList toReturn = new ArrayList(); + ArrayList postIDs = getUserPostIds(userid); + //check if quantity is greater than user feeds + 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 feeds + quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; + } + } + return toReturn; + } + + /** + * {@inheritDoc} + */ + @Override + public List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + return getPostsByIds(getVREPostIds(vreid)); + } + + @Override + public List getRecentPostsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException { + 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, ColumnNameNotFoundException { + if (from < 1) { + throw new IllegalArgumentException("From must be greather than 0"); + } + ArrayList feedsToReturn = new ArrayList(); + ArrayList feedIDs = getVREPostIds(vreid); + + //if from is greater than feeds size return empty + if (from >= feedIDs.size()) { + _log.warn("The starting point of the range is greather than the total number of feeds for this timeline: " + from + " >= " + feedIDs.size()); + return new RangePosts(); + } + + int rangeStart = feedIDs.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(feedIDs.get(i)); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { + feedsToReturn.add(toAdd); + _log.trace("Read recent post, i=" + i + " id= " + feedIDs.get(i)); + } else { + _log.trace("Read and skipped post, i=" + i + " id=: " + feedIDs.get(i) + " (Removed post) ."); + rangeEnd -= 1; //increase the upTo in case of removed feed + //check if quantity is greater than user feeds + rangeEnd = (rangeEnd > 0) ? rangeEnd : 0; + } + howMany++; + } + _log.debug("AFTER: starting Point==" + rangeStart + " rangeEnd= " + rangeEnd); + return new RangePosts(howMany+1, feedsToReturn); + } + + /** + * 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; + } + /* + * + ********************** NOTIFICATIONS *********************** + * + */ + /** + * {@inheritDoc} + */ + @Override + public boolean saveNotification(Notification n) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + //notification entry + PreparedStatement stmt1 = createNotificationEntry(session); + writeBatch.add(stmt1.bind(UUID.fromString(n.getKey()), + n.getType().toString(), + n.getUserid(), + n.getSubjectid(), + n.getTime().toInstant(), + n.getDescription(), + n.getUri(), + n.getSenderid(), + n.getSenderFullName(), + n.getSenderThumbnail(), + n.isRead())); + + + //an entry in the user Notifications Timeline + PreparedStatement stmt2 = createUserNotificationsEntry(session); + writeBatch.add(stmt2.bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey()))); + + // save key in the unread notifications column family too + PreparedStatement stmt3 = createUnreadNotificationEntry(session); + writeBatch.add(stmt3.bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey()))); + try{ + boolean res = session.execute(writeBatch).wasApplied(); + closeSession(session); + return res; + }catch (Exception e){ + e.printStackTrace(); + return false; + } + } + + 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(new Notification(record)) :Optional.empty(); + } + + /** + * {@inheritDoc} + */ + @Override + public Notification readNotification(String notificationid) throws NotificationIDNotFoundException { + Notification toReturn = new Notification(); + CqlSession session = conn.getKeyspaceSession(); + try { + toReturn = findNotById(notificationid, session).get(); + closeSession(session); + } + catch (Exception e) { + e.printStackTrace(); + closeSession(session); + } + return toReturn; + } + + 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()); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean setNotificationRead(String notificationidToSet) throws NotificationIDNotFoundException, NotificationTypeNotFoundException { + 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 + writeBatch.add(updateNotificationEntry(session,IS_READ).bind(UUID.fromString(notificationidToSet), true)); + + // delete the notification's key from the unread notifications column family + writeBatch.add(deleteUnreadNotEntry(session).bind(toSet.getUserid(), toSet.getTime().toInstant())); + + // execute the operations + try { + boolean res = session.execute(writeBatch).wasApplied(); + closeSession(session); + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + ArrayList toReturn = new ArrayList(); + + // Iterate rows and their columns + for (Row row : result.all()) { + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + ArrayList toReturn = new ArrayList(); + + // Iterate rows and their columns + for (Row row : result.all()) { + toReturn.add(row.getUuid(NOT_ID).toString()); + } + return toReturn; + } + /** + * {@inheritDoc} + */ + @Override + public List getAllNotificationByUser(String userid, int limit) throws NotificationTypeNotFoundException { + ArrayList toReturn = new ArrayList(); + ArrayList notificationsIDs = getUserNotificationsIds(userid); + //check if quantity is greater than user feeds + 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) { + 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 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 feeds size return empty + if (from >= notificationsIDs.size()) { + _log.warn("The starting point of the range is greather than the total number of feeds 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 { + + // 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) { + + 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) { + + 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.trace("Asking for Single Notification preference of " + userid + " Type: " + notificationType); + List toReturn = new ArrayList(); + NotificationChannelType[] toProcess = getUserNotificationPreferences(userid).get(notificationType); + if (toProcess == null) { + _log.warn("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(); + 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(); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + if (res) { + _log.trace("Set New Notification Setting for " + userid + " OK"); + return toReturn; + } + return new ArrayList(); //no notification if sth fails + } + /** + * {@inheritDoc} + */ + @Override + public boolean setUserNotificationPreferences(String userid, Map enabledChannels) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + for (NotificationType nType : enabledChannels.keySet()) { + String valueToInsert = ""; + int channelsNo = (enabledChannels.get(nType) != null) ? enabledChannels.get(nType).length : 0; + for (int i = 0; i < channelsNo; i++) { + valueToInsert += enabledChannels.get(nType)[i]; + if (i < channelsNo-1) + valueToInsert += ","; + } + if (channelsNo == 0) { //in case no channels were selected + valueToInsert = ""; + _log.trace("No Channels selected for " + nType + " by " + userid); + } + writeBatch.add(createNotificationPreferenceEntry(session).bind(userid, nType.toString(), valueToInsert)); + } + + boolean overAllresult = session.execute(writeBatch).wasApplied(); + if (overAllresult) + _log.trace("Set Notification Map for " + userid + " OK"); + else + _log.trace("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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + //if there are no settings for this user create an entry and put all of them at true + if (result.all().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: result.all()){ + 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 *********************** + * + */ + /** + * {@inheritDoc} + */ + @Override + public boolean addComment(Comment comment) { + Post toComment = null; + if (comment == null) + throw new NullArgumentException("Comment must be not null"); + if (comment.getpostid() == null) + throw new NullArgumentException("Comment feed id must be not null"); + + String postid = comment.getpostid(); + try { + toComment = readPost(postid); + if (toComment == null) + throw new PostIDNotFoundException("Could not find Feed with id " + postid + " to associate this comment", postid); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + writeBatch.add(createNewCommentEntry(session).bind( + UUID.fromString(comment.getKey()), + comment.getUserid(), + comment.getFullName(), + comment.getThumbnailURL(), + comment.getText(), + UUID.fromString(comment.getpostid()), + comment.getTime().toInstant(), + null + )); + + try { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + //update the comment count + boolean updateCommentNoResult = updateFeedCommentsCount(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))); + closeSession(session); + if (result.all().isEmpty()) { + throw new CommentIDNotFoundException("The requested commentId: " + commentId + " is not existing"); + } + toReturn = new Comment(result.one()); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + + } + + 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(QueryBuilder + .selectFrom(COMMENTS).all() + .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + try { + result = session.execute(stmtFind.bind(UUID.fromString(postid))); + closeSession(session); + for (Row row : result.all()) { + Comment toAdd = new Comment(row); + toReturn.add(toAdd); + } + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + 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()); + closeSession(session); + + if (!result.all().isEmpty()){ + result.all().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(); + closeSession(session); + } + + if(sort) + Collections.sort(commentsByUser, Collections.reverseOrder()); + return commentsByUser; + } + + 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()); + } + /** + * {@inheritDoc} + */ + @Override + public boolean editComment(Comment comment2Edit) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + writeBatch.add(updateCommentEntry(session, COMMENT).bind(comment2Edit.getText(), UUID.fromString(comment2Edit.getKey()))) + .add(updateCommentEntry(session, IS_EDIT).bind(comment2Edit.isEdit(), UUID.fromString(comment2Edit.getKey()))) + .add(updateCommentEntry(session, LAST_EDIT_TIME).bind(comment2Edit.getTime().toInstant(), UUID.fromString(comment2Edit.getKey()))); + + try { + boolean res = session.execute(writeBatch).wasApplied(); + closeSession(session); + _log.info("Comments update OK to: " + comment2Edit.getText()); + return res; + } catch (Exception e) { + closeSession(session); + _log.error("Comments update NOT OK "); + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean deleteComment(String commentid, String postid) throws ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + Post toUpdate = readPost(postid); + boolean updateCommentNoResult = false; + + updateCommentNoResult = updateFeedCommentsCount(toUpdate, false); + if (updateCommentNoResult) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch().add(deleteCommentEntry(session).bind(UUID.fromString(commentid))); + + try { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + closeSession(session); + _log.error("Comment Delete FAILED for " + commentid + " from Feed " + postid); + e.printStackTrace(); + } + _log.trace("Comment Deleted " + commentid + " from Feed " + postid); + } + + + return updateCommentNoResult; + } + /** + * {@inheritDoc} + */ + @Override + public boolean like(Like like) { + Post toLike = null; + if (like == null) + throw new NullArgumentException("Like must be not null"); + if (like.getpostid() == null) + throw new NullArgumentException("Like feed id must be not null"); + + String feedId = like.getpostid(); + try { + toLike = readPost(feedId); + if (toLike == null) + throw new PostIDNotFoundException("Could not find Feed with id " + feedId + " to associate this like", feedId); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + if (isPostLiked(like.getUserid(), feedId)) { + _log.info("User " + like.getUserid() + " already liked Feed " + feedId); + return true; + } + else { + CqlSession session = conn.getKeyspaceSession(); + // Inserting data + //an entry in the feed CF + //and an entry in the UserLikesCF + BatchStatement writeBatch = getBatch() + .add(createNewLikeEntry(session).bind(UUID.fromString(like.getKey()), + like.getUserid(), + like.getFullName(), + like.getThumbnailURL(), + UUID.fromString(like.getpostid()), + like.getTime().toInstant())) + .add(createNewUserLikesEntry(session).bind(like.getUserid(), + UUID.fromString(like.getKey()), + UUID.fromString(like.getpostid()))); + try { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return updateFeedLikesCount(toLike, true); + } + } + /** + * {@inheritDoc} + */ + 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()); + } + @Override + public boolean unlike(String userid, String likeid, String postid) throws ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + Post toUpdate = readPost(postid); + boolean updateLikeNoResult = false; + + updateLikeNoResult = updateFeedLikesCount(toUpdate, false); //this remove 1 from the Feed 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); + closeSession(session); + } catch (Exception e) { + closeSession(session); + _log.error("Like Delete FAILED for " + likeid + " from Feed " + postid); + e.printStackTrace(); + } + _log.trace("Unlike ok for " + likeid + " from Feed " + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + 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, ColumnNameNotFoundException { + ArrayList toReturn = new ArrayList(); + List likedPostIDs = getAllLikedPostIdsByUser(userid); + + //check if quantity is greater than user feeds + 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 feed + //check if quantity is greater than user feeds + 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 feeds + 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 = new Like(row); + toReturn.add(toAdd); + } + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + return toReturn; + } + /* + * + ********************** HASHTAGS *********************** + * + */ + /** + * {@inheritDoc} + */ + @Override + public boolean saveHashTags(String feedid, String vreid, List hashtags) { + 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(feedid), vreid))).wasApplied(); + boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, true); + if (! (firstInsert && secondInsert)) { + _log.error("saveHashTags: Could not save the hashtag(s)"); + closeSession(session); + return false; + } + } + closeSession(session); + return true; + } + + 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()); + } + /** + * {@inheritDoc} + */ + @Override + public boolean deleteHashTags(String feedid, String vreid, List hashtags) { + 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(feedid))).wasApplied(); + boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, false); + if (! (firstDelete && secondInsert)) { + _log.error("deleteHashTags: Could not delete the hashtag(s)"); + closeSession(session); + return false; + + } + } + closeSession(session); + return true; + } + /** + * {@inheritDoc} + */ + @Override + public boolean saveHashTagsComment(String commentId, String vreid, List hashtags) { + 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)"); + closeSession(session); + return false; + } + } + closeSession(session); + 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)"); + closeSession(session); + return false; + } + }else{ + _log.error("deleteHashTags: Could not delete the hashtag(s)"); + closeSession(session); + return false; + } + } + closeSession(session); + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + + HashMap toReturn = new HashMap (); + + // Iterate rows and their columns + for (Row row : result.all()) { + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + HashMap toReturn = new HashMap (); + + // Iterate rows and their columns + for (Row row : result.all()) { + // retrieve the feeds list for this hashtag + List feeds = null; + try{ + feeds = getVREPostsByHashtag(vreid, row.getString(HASHTAG)); + }catch(Exception e){ + _log.error("Unable to retrieve the list of feeds for hashtag" + row.getString(HASHTAG) + " in vre " + vreid); + continue; + } + + if(feeds.isEmpty()){ + + _log.info("There are no feeds containing hashtag " + row.getString(HASHTAG) + " in vre " + vreid); + continue; + + } + + // retrieve the most recent one among these feeds + Collections.sort(feeds, Collections.reverseOrder()); + + if(feeds.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, 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(); + closeSession(session); + } + + 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(); + closeSession(session); + } + + Set postIds = new HashSet<>(); + // Iterate rows and their columns (feed) + for (Row row : resultPost.all()) { + if (row.getString(VRE_ID).compareTo(vreid)==0) + postIds.add(row.getUuid(POST_ID).toString()); + } + // Iterate rows and their columns (comments) + for (Row row : resultComment.all()) { + 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 *********************** + * + */ + /** + * common part to save a invite + * @param invite + * @return the partial mutation batch instance + */ + private BatchStatement initSaveInvite(Invite invite, CqlSession session) { + BatchStatement writeBatch = getBatch(); + if (invite == null) + throw new NullArgumentException("Invite instance is null"); + // Inserting data + writeBatch.add(createNewInviteEntry(session).bind( + UUID.fromString(invite.getKey()), + invite.getSenderUserId(), + invite.getVreid(), + invite.getInvitedEmail(), + invite.getControlCode(), + invite.getStatus().toString(), + invite.getTime().toInstant(), + invite.getSenderFullName() + )); + + + return writeBatch; + } + + /** + * {@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(); + closeSession(session); + } + + // Iterate rows and their columns + for (Row row : result.all()) { + 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(); + BatchStatement m = initSaveInvite(invite, session); + //an entry in the VRE Invites + m.add(createNewVreInviteEntry(session).bind(invite.getVreid(), UUID.fromString(invite.getKey()), InviteStatus.PENDING.toString())); + //an entry in the EMAIL Invites + m.add(createNewEmailInviteEntry(session).bind(email, invite.getVreid(), UUID.fromString(invite.getKey()))); + boolean result = session.execute(m).wasApplied(); + closeSession(session); + return result ? InviteOperationResult.SUCCESS : InviteOperationResult.FAILED; + } + /** + * {@inheritDoc} + */ + @Override + public Invite readInvite(String inviteid) { + 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))); + if (result.one() == null) { + throw new InviteStatusNotFoundException("The requested inviteid: " + inviteid + " is not existing"); + } + toReturn = new Invite(result.one()); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + 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 + */ + private List getInvitesById(List inviteIds) { + ArrayList toReturn = new ArrayList(); + for (String inviteid : inviteIds) + toReturn.add(readInvite(inviteid)); + + return toReturn; + } + 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()); + } + + /** + * {@inheritDoc} + * @throws InviteStatusNotFoundException + */ + @Override + public boolean setInviteStatus(String vreid, String email, InviteStatus status) throws InviteIDNotFoundException { + 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(); + //update in the Invites Static CF + //updated in the VREInvites Dynamic CF + writeBatch.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); + closeSession(session); + } catch (Exception e) { + _log.error("ERROR while setting Invite " + inviteid + " to " + status.toString()); + closeSession(session); + return false; + } + _log.trace("Invite Status Set to " + status.toString() + " OK"); + return true; + } + /** + * {@inheritDoc} + */ + @Override + public List getInvitedEmailsByVRE(String vreid, InviteStatus... status) { + 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)); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + ArrayList invitesIds = new ArrayList(); + // Iterate rows and their columns + for (Row row : result.all()) { + 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 getAttachmentsByFeedId(String feedId) { + //index error + Post toCheck = null; + try { + toCheck = readPost(feedId); + if (toCheck == null) + throw new PostIDNotFoundException("Could not find Feed with id " + feedId, feedId); + } 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(feedId))); + // Iterate rows and their columns + for (Row row : result.all()) { + _log.trace("Reading attachment if feed=" + row.getUuid(POST_ID).toString()); + Attachment toAdd = new Attachment(row); + toReturn.add(toAdd); + } + closeSession(session); + } catch (Exception e) { + e.printStackTrace(); + closeSession(session); + return null; + } + return toReturn; + } + /** + * {@inheritDoc} + */ + @Override + public void closeConnection() { + conn.closeConnection(); + } + /* + * + ********************** 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 + CqlSession session = conn.getKeyspaceSession(); + //an entry in the Attachment CF + try { + session.execute(createNewaAttachEntry(session).bind( + UUID.fromString(toSave.getId()), + UUID.fromString(feedId), + toSave.getUri(), + toSave.getName(), + toSave.getDescription(), + toSave.getThumbnailURL(), + toSave.getMimeType() + )); + closeSession(session); + } catch (Exception e) { + closeSession(session); + e.printStackTrace(); + return false; + } + return true; + } + + + /** + * + * @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 feed by incrementing or decrementing by (1) the CommentsNo + * used when adding or removing a comment to a feed + * @param toUpdate the feedid + * @param increment set true if you want to add 1, false to subtract 1. + */ + private boolean updateFeedCommentsCount(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 feed CF + try { + session.execute(updatePostEntry(session, COMMENTS_NO).bind((long) newCount, UUID.fromString(toUpdate.getKey()))); + closeSession(session); + } catch (Exception e) { + _log.error("CommentsNo update NOT OK "); + closeSession(session); + return false; + } + _log.info("CommentsNo update OK to: " + newCount); + return true; + } + + /** + * update the feed by incrementing or decrementing by (1) the LikesNo + * used when adding or removing a comment to a feed + * @param toUpdate the feedid + * @param increment set true if you want to add 1, false to subtract 1. + */ + private boolean updateFeedLikesCount(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 feed CF + try { + session.execute(updatePostEntry(session, LIKES_NO).bind((long)newCount, UUID.fromString(toUpdate.getKey()))); + closeSession(session); + } catch (Exception e) { + _log.error("LikesNo update NOT OK "); + closeSession(session); + 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 feed + * @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(); + PreparedStatement stmt; + BatchStatement writeBatch = getBatch(); + 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()); + writeBatch.add(stmt.bind((long)newCount, hashtag, vreid)); + } + else{ + stmt = createNewUHashtagCounterEntry(session); + writeBatch.add(stmt.bind(vreid, hashtag, (long)newCount)); + } + + try { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + _log.error("Hashtag Count update NOT OK "); + closeSession(session); + 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(){ + + List ids = new ArrayList<>(); + + 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.getQuery()); + closeSession(session); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } + + for (Row row : result.all()) { + ids.add(row.getString(VRE_ID)); + } + + _log.debug("VRE ids are " + ids); + + return ids; + + } +} diff --git a/src/main/java/org/gcube/portal/databook/server/DatabookCassandraTest.java b/src/main/java/org/gcube/portal/databook/server/DatabookCassandraTest.java index 33df1eb..0d6cff8 100644 --- a/src/main/java/org/gcube/portal/databook/server/DatabookCassandraTest.java +++ b/src/main/java/org/gcube/portal/databook/server/DatabookCassandraTest.java @@ -5,17 +5,12 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import com.google.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; + private static DBCassandraDatastaxImpl store; @BeforeClass public static void setup() throws Exception { - store = new DBCassandraAstyanaxImpl(); //set to true if you want to drop the KeySpace and recreate it + store = new DBCassandraDatastaxImpl(); //set to true if you want to drop the KeySpace and recreate it } @AfterClass diff --git a/src/main/java/org/gcube/portal/databook/server/DatabookStore.java b/src/main/java/org/gcube/portal/databook/server/DatabookStore.java index 263946f..c6c1797 100644 --- a/src/main/java/org/gcube/portal/databook/server/DatabookStore.java +++ b/src/main/java/org/gcube/portal/databook/server/DatabookStore.java @@ -7,7 +7,6 @@ import javax.mail.internet.AddressException; 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; import org.gcube.portal.databook.shared.InviteOperationResult; import org.gcube.portal.databook.shared.InviteStatus; @@ -16,21 +15,9 @@ import org.gcube.portal.databook.shared.Notification; import org.gcube.portal.databook.shared.NotificationChannelType; import org.gcube.portal.databook.shared.NotificationType; import org.gcube.portal.databook.shared.Post; -import org.gcube.portal.databook.shared.RangeFeeds; import org.gcube.portal.databook.shared.RangePosts; -import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException; -import org.gcube.portal.databook.shared.ex.CommentIDNotFoundException; -import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; -import org.gcube.portal.databook.shared.ex.FeedTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.InviteIDNotFoundException; -import org.gcube.portal.databook.shared.ex.InviteStatusNotFoundException; -import org.gcube.portal.databook.shared.ex.LikeIDNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationChannelTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationIDNotFoundException; -import org.gcube.portal.databook.shared.ex.NotificationTypeNotFoundException; -import org.gcube.portal.databook.shared.ex.PrivacyLevelTypeNotFoundException; +import org.gcube.portal.databook.shared.ex.*; -import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; /** * @author Massimiliano Assante ISTI-CNR @@ -38,51 +25,11 @@ import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; * DatabookStore is the high level interface for querying and adding data to DatabookStore */ public interface DatabookStore { - /** - * userid from requests a friendship to userid to - * @return true if everything went fine - */ - boolean requestFriendship(String from, String to); - /** - * userid from approves a friendship to userid to - * @return true if everything went fine - */ - boolean approveFriendship(String from, String to); - /** - * userid from denies a friendship to userid to - * @return true if everything went fine - */ - boolean denyFriendship(String from, String to); - /** - * @param userid the user id you want to know friends - * @return a List of userid representing the friends for the given userid - */ - List getFriends(String userid); - /** - * @param userid the user id you want to know the pending friend requests - * @return a List of userid representing the friends for the given userid - */ - List getPendingFriendRequests(String userid); - /** - * @deprecated use saveUserPost - * save a Feed instance in the store - * @return true if everything went fine - */ - boolean saveUserFeed(Feed feed); /** * save a Post instance in the store * @return true if everything went fine */ boolean saveUserPost(Post feed); - /** - * Save a Feed instance in the store having more than one attachment - * Use this if you need to attach more than one file to the post - * - * @deprecated use saveUserPost - * @param attachments a list of attachments starting from the second - * @return true if everything went fine - */ - boolean saveUserFeed(Feed feed, List attachments); /** * Save a Post instance in the store having more than one attachment * Use this if you need to attach more than one file to the post @@ -91,54 +38,24 @@ public interface DatabookStore { * @return true if everything went fine */ boolean saveUserPost(Post post, List attachments); - /** - * Delete a Feed from the store - * @deprecated use saveUserPost - * @throws FeedIDNotFoundException - * @return true if everything went fine - */ - boolean deleteFeed(String feedid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException; - /** + /** * delete a Feed from the store - * @throws FeedIDNotFoundException * @return true if everything went fine */ - boolean deletePost(String postid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException; - /** - * Save a post in the VRES TimeLine in the store - * @deprecated use savePostToVRETimeline - * @param feedKey feedKey - * @param vreid vre identifier - * @throws FeedIDNotFoundException - */ - boolean saveFeedToVRETimeline(String feedKey, String vreid) throws FeedIDNotFoundException; + boolean deletePost(String postid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; /** * save a post in the VRES TimeLine in the store * @param postKey the post id * @param vreid vre identifier - * @throws FeedIDNotFoundException */ - boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException; - /** - * @deprecated use saveAppPost - * save a Post instance in the store - * @return true if everything went fine - */ - boolean saveAppFeed(Feed feed); + boolean savePostToVRETimeline(String postKey, String vreid) throws PostIDNotFoundException; + /** * save a Post instance in the store * @return true if everything went fine */ boolean saveAppPost(Post feed); - /** - * @deprecated use saveAppPost - * Save a Post instance in the store - * Use this if your app needs to attach more than one file to the post - * - * @param attachments a list of attachments starting from the second - * @return true if everything went fine - */ - boolean saveAppFeed(Feed feed, List attachments); + /** * Save a Post instance in the store * Use this if your app needs to attach more than one file to the post @@ -147,64 +64,28 @@ public interface DatabookStore { * @return true if everything went fine */ boolean saveAppPost(Post feed, List attachments); - /** - * @deprecated use readPost - * read a feed from a given id - * @throws PrivacyLevelTypeNotFoundException - * @throws FeedTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - Feed readFeed(String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** * read a feed from a given id * @throws PrivacyLevelTypeNotFoundException - * @throws FeedTypeNotFoundException - * @throws ColumnNameNotFoundException + * @throws ColumnNameNotFoundException */ - Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; - /** - * @deprecated use getAllPostsByUser instead + Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException, PostTypeNotFoundException, PostIDNotFoundException; + /** * @param userid user identifier * return all the feeds belonging to the userid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - List getAllFeedsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; - /** - * @param userid user identifier - * return all the feeds belonging to the userid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; - /** - * @deprecated use getAllPostsByApp instead + List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; + /** * @param appid application identifier * return all the feeds belonging to the appid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - List getAllFeedsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; - /** - * @param appid application identifier - * return all the feeds belonging to the appid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; - /** - * @deprecated use getRecentCommentedPostsByUserAndDate instead - * @param userid the user identifier like andrea.rossi - * @param timeInMillis the initial time in millis to be considered - * @return a list of feeds commented by userid starting from timeInMillis - * @throws Exception - */ - List getRecentCommentedFeedsByUserAndDate(String userid, long timeInMillis) throws Exception; - /** + List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; + /** * @param userid the user identifier like andrea.rossi * @param timeInMillis the initial time in millis to be considered * @return a list of feeds commented by userid starting from timeInMillis @@ -212,97 +93,41 @@ public interface DatabookStore { */ List getRecentCommentedPostsByUserAndDate(String userid, long timeInMillis) throws Exception; /** - * @deprecated use getAllPortalPrivacyLevelPosts instead * return all the feeds whose Level is PORTAL * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException * @throws PrivacyLevelTypeNotFoundException */ - List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException; - /** - * return all the feeds whose Level is PORTAL - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - * @throws PrivacyLevelTypeNotFoundException - */ - List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException; + List getAllPortalPrivacyLevelPosts() throws ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException, PostTypeNotFoundException; - /** - * return the most recent feeds for this user up to quantity param - * @deprecated - * @param userid user identifier - * @param quantity the number of most recent feeds for this user - * @return a List of most recent feeds for this user - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - List getRecentFeedsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; /** * return the most recent feeds for this user up to quantity param * @param userid user identifier * @param quantity the number of most recent feeds for this user * @return a List of most recent feeds for this user - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; - /** - * @deprecated use getAllPostsByVRE - * @param vreid vre identifier - * return all the feeds belonging to the userid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; - /** - * @param vreid vre identifier - * return all the feeds belonging to the userid - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; /** - * @deprecated use getRecentPostsByVRE - * return the most recent feeds for this vre up to quantity param - * @param vreid VRES identifier - * @param quantity the number of most recent feeds for this vre - * @return a List of most recent feeds for this vre - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @param vreid vre identifier + * return all the feeds belonging to the userid + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - List getRecentFeedsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; + /** * return the most recent posts for this vre up to quantity param * @param vreid VRES identifier * @param quantity the number of most recent posts for this vre * @return a List of most recent posts for this vre - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - List getRecentPostsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + List getRecentPostsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; - /** - * return the most recent posts for this vre up to quantity param and the last index of the feeds in the timeline - * lastReturnedFeedTimelineIndex is usuful to know from where to start the range the second time you ask - * because there are deletions - * - * @deprecated use getRecentPostsByVREAndRange - * @param vreid VRES identifier - * @param from the range start (most recent feeds for this vre) has to be greater than 0 - * @param quantity the number of most recent feeds for this vre starting from "from" param - * @return a lastReturnedFeedTimelineIndex containing of most recent feeds for this vre - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException - * @throws ColumnNameNotFoundException - */ - RangeFeeds getRecentFeedsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; /** * return the most recent posts for this vre up to quantity param and the last index of the posts in the timeline * lastReturnedPostTimelineIndex is useful to know from where to start the range the next time you ask, because there are deletions @@ -311,19 +136,11 @@ public interface DatabookStore { * @param from the range start (most recent feeds for this vre) has to be greater than 0 * @param quantity the number of most recent feeds for this vre starting from "from" param * @return a RangePosts containing of most recent feeds for this vre - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; - /** - * @deprecated use getRecentPostsByUserAndDate - * @param userid user identifier - * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds - * @return the number of feeds in the range from: today to: timeInMillis - */ - List getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; /** * @param userid user identifier * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds @@ -437,13 +254,7 @@ public interface DatabookStore { * add a comment to a feed * @param comment the Comment instance to add */ - boolean addComment(Comment comment) throws FeedIDNotFoundException; - /** - * @deprecated use getAllCommentByPost - * @param feedid feed identifier - * return all the comments belonging to the feedid - */ - List getAllCommentByFeed(String feedid); + boolean addComment(Comment comment); /** * @param postid the post identifier * return all the comments belonging to the postid @@ -460,20 +271,19 @@ public interface DatabookStore { * @param comment the comment to edit * @return true if success, false otherwise */ - boolean editComment(Comment comment) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException; + boolean editComment(Comment comment) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException; /** * deletes a comment * @param commentid the comment identifier to delete * @param feedid the feedid to which the comment is associated * @return true if success, false otherwise */ - boolean deleteComment(String commentid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException; + boolean deleteComment(String commentid, String feedid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException; /** * add a like to a feed * @param like instance - * @throws FeedIDNotFoundException */ - boolean like(Like like) throws FeedIDNotFoundException; + boolean like(Like like); /** * unlike a feed * @param userid user identifier @@ -481,62 +291,29 @@ public interface DatabookStore { * @param feedid the feedid to which the comment is associated * @return true if success, false otherwise */ - boolean unlike(String userid, String likeid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, FeedIDNotFoundException; - /** - * @deprecated use getAllLikedPostIdsByUser - * @param userid user identifier - * return all the feedids a user has liked - */ - List getAllLikedFeedIdsByUser(String userid); + boolean unlike(String userid, String likeid, String feedid) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException; /** * @param userid user identifier * return all the feedids a user has liked */ List getAllLikedPostIdsByUser(String userid); - /** - * @deprecated use getAllLikedPostsByUser - * @param userid user identifier - * @param limit set 0 to get everything, an int to get the most recent -limit- liked feeds - * @throws ColumnNameNotFoundException . - * @throws FeedIDNotFoundException . - * @throws FeedTypeNotFoundException . - * @throws PrivacyLevelTypeNotFoundException - * @throws FeedIDNotFoundException . - * return all the feeds a user has liked - */ - List getAllLikedFeedsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** * @param userid user identifier * @param limit set 0 to get everything, an int to get the most recent -limit- liked posts * @throws ColumnNameNotFoundException . - * @throws FeedIDNotFoundException . - * @throws FeedTypeNotFoundException . * @throws PrivacyLevelTypeNotFoundException - * @throws FeedIDNotFoundException . * return all the feeds a user has liked */ - List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; - /** - * @deprecated use getRecentLikedPostsByUserAndDate - * @param userid user identifier - * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds - * @return the likes made to feeds in the range from: today to: timeInMillis - */ - List getRecentLikedFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; /** * @param userid user identifier * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds * @return the likes made to feeds in the range from: today to: timeInMillis */ List getRecentLikedPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; - /** - * @deprecated use getAllLikesByPost - * @param postid postid identifier - * return all the likes belonging to the postid - */ - List getAllLikesByFeed(String postid); + /** * @param postid postid identifier * return all the likes belonging to the postid @@ -548,9 +325,8 @@ public interface DatabookStore { * @param postid the postid to which the hashtag is associated * @param vreid VRE identifier * @return true if success, false otherwise - * @throws FeedIDNotFoundException */ - boolean saveHashTags(String postid, String vreid, List hashtags) throws FeedIDNotFoundException; + boolean saveHashTags(String postid, String vreid, List hashtags); /** * * @param hashtags the hashtag including the '#' @@ -566,9 +342,8 @@ public interface DatabookStore { * @param postid the postid to which the hashtag is associated * @param vreid VRE identifier * @return true if success, false otherwise - * @throws FeedIDNotFoundException */ - boolean deleteHashTags(String postid, String vreid, List hashtags) throws FeedIDNotFoundException; + boolean deleteHashTags(String postid, String vreid, List hashtags) ; /** * * @param hashtags the hashtag including the '#' @@ -591,30 +366,15 @@ public interface DatabookStore { * @return a HashMap of vre Hashtags associated with their occurrence */ Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp); - /** - * @deprecated use getVREPostsByHashtag - * @param vreid VRE identifier - * @param hashtag the hashtag to look for including the '#', it is case sensitive - * @throws ColumnNameNotFoundException . - * @throws FeedIDNotFoundException . - * @throws FeedTypeNotFoundException . - * @throws PrivacyLevelTypeNotFoundException - * @throws FeedIDNotFoundException . - * @return all the feeds having the hashtag passed as parameter - */ - List getVREFeedsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** * * @param vreid VRE identifier * @param hashtag the hashtag to look for including the '#', it is case sensitive * @throws ColumnNameNotFoundException . - * @throws FeedIDNotFoundException . - * @throws FeedTypeNotFoundException . - * @throws PrivacyLevelTypeNotFoundException - * @throws FeedIDNotFoundException . - * @return all the feeds having the hashtag passed as parameter + * @throws PrivacyLevelTypeNotFoundException + * @return all the feeds having the hashtag passed as parameter */ - List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, ColumnNameNotFoundException; /** * Save the invite for a given email into a given vre @@ -654,14 +414,13 @@ public interface DatabookStore { * @param feedId * @return the list of attachments of the feed feedId, starting from the second one (first attachment is included in Feed instance already) */ - List getAttachmentsByFeedId(String feedId) throws FeedIDNotFoundException; + List getAttachmentsByFeedId(String feedId); /** * Retrieve all the ids of the vre * @return the set of ids of the vre available or empty list in case of errors. - * @throws ConnectionException */ - public List getAllVREIds() throws ConnectionException; + public List getAllVREIds(); /** * close the connection to the underlying database diff --git a/src/main/java/org/gcube/portal/databook/server/RunningCluster.java b/src/main/java/org/gcube/portal/databook/server/RunningCluster.java index d8ae873..c864ceb 100644 --- a/src/main/java/org/gcube/portal/databook/server/RunningCluster.java +++ b/src/main/java/org/gcube/portal/databook/server/RunningCluster.java @@ -7,9 +7,14 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.List; import java.util.Properties; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.metadata.Metadata; +import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; import org.gcube.common.portal.GCubePortalConstants; import org.gcube.common.portal.PortalContext; import org.gcube.common.resources.gcore.ServiceEndpoint; @@ -22,8 +27,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Massimiliano Assante ISTI-CNR + * @author Ahmed Salah Tawfik Ibrahim ISTI-CNR * - * @version 0.1 Dec 2012 + * @version 2.0.0 October 2023 * */ @SuppressWarnings("serial") @@ -38,7 +44,7 @@ public class RunningCluster implements Serializable { */ private static final String HOST_PROPERTY = "host"; private static final String HOST_PORT_PROPERTY = "port"; - private static final String CLUSTER_NAME_PROPERTY = "cluster"; + private static final String DATACENTER_NAME_PROPERTY = "datacenter"; private static final String KEY_SPACE_NAME_PROPERTY = "keyspace"; /** * other constants @@ -56,11 +62,11 @@ public class RunningCluster implements Serializable { /** * Cluster Name */ - private String clusterName; + private String datacenterName; /** * Keyspace Name */ - private String keyspaceName; + private String keyspaceName; //to be modified /** * @param infrastructureName could be null @@ -76,8 +82,8 @@ public class RunningCluster implements Serializable { * private constructor */ private RunningCluster(String infrastructureName) { - try { - List resources = getConfigurationFromIS(infrastructureName); + //Query the IS (for the future) + /*List resources = getConfigurationFromIS(infrastructureName); if (resources.size() > 1) { _log.error("Too many Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" in this scope "); throw new TooManyRunningClustersException("There exist more than 1 Runtime Resource in this scope having name " @@ -97,8 +103,13 @@ public class RunningCluster implements Serializable { } } catch (Exception e) { e.printStackTrace(); - } + }*/ + + host = "10.1.28.55:9042, 10.1.30.142:9042, 10.1.28.100:9042"; + datacenterName = "1"; + keyspaceName = "dev_mig_new_schema_test"; } + /** * * @return the @@ -125,6 +136,7 @@ public class RunningCluster implements Serializable { } private String readInfrastructureName() { + Properties props = new Properties(); try { StringBuilder sb = new StringBuilder(getCatalinaHome()); @@ -153,7 +165,7 @@ public class RunningCluster implements Serializable { try { props.load(CassandraClusterConnection.class.getResourceAsStream(DEFAULT_CONFIGURATION)); host = props.getProperty(HOST_PROPERTY) + ":" + props.getProperty(HOST_PORT_PROPERTY); - clusterName = props.getProperty(CLUSTER_NAME_PROPERTY); + datacenterName = props.getProperty(DATACENTER_NAME_PROPERTY); keyspaceName = props.getProperty(KEY_SPACE_NAME_PROPERTY); } catch (IOException e) { e.printStackTrace(); @@ -169,25 +181,19 @@ public class RunningCluster implements Serializable { this.host = host; } - public String getClusterName() { - return clusterName; - } - - public void setClusterName(String clusterName) { - this.clusterName = clusterName; - } public String getKeyspaceName() { return keyspaceName; } + public void setKeyspaceName(String keyspaceName) { this.keyspaceName = keyspaceName; } @Override public String toString() { - return "RunningCluster [host=" + host + ", clusterName=" + clusterName + return "RunningCluster [host=" + host + ", datacenterName=" + datacenterName + ", keyspaceName=" + keyspaceName + "]"; } /** @@ -197,4 +203,21 @@ public class RunningCluster implements Serializable { private static String getCatalinaHome() { return (System.getenv("CATALINA_HOME").endsWith("/") ? System.getenv("CATALINA_HOME") : System.getenv("CATALINA_HOME")+"/"); } + public void setDatacenterName(String datacenterName){ + this.datacenterName = datacenterName; + } + + public String getDatacenterName() { + return datacenterName; + } + + public List getHosts() { + List hosts = new ArrayList<>(); + String [] ips = host.split(", "); + for (String ip: ips){ + String[] ip_port = ip.split(":"); + hosts.add(new InetSocketAddress(ip_port[0], Integer.parseInt(ip_port[1]))); + } + return hosts; + } } diff --git a/src/main/java/org/gcube/portal/databook/server/Schema.java b/src/main/java/org/gcube/portal/databook/server/Schema.java new file mode 100644 index 0000000..364ca21 --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/server/Schema.java @@ -0,0 +1,68 @@ +package org.gcube.portal.databook.server; + +public class Schema { + //Tables + public static final String NOTIFICATIONS = "Notifications"; + public static final String POSTS = "Posts"; + public static final String COMMENTS = "Comments"; + public static final String LIKES = "Likes"; + public static final String INVITES = "Invites"; + public static final String VRE_TIMELINE_POSTS = "VRETimeline"; + public static final String USER_TIMELINE_POSTS = "UserTimeline"; + public static final String APP_TIMELINE_POSTS = "AppTimeline"; + public static final String USER_LIKED_POSTS = "UserLikes"; + public static final String USER_NOTIFICATIONS = "UserNotifications"; // regular user notifications timeline (both read and unread, messages are included) + public static final String USER_NOTIFICATIONS_UNREAD = "UserUnreadNotifications"; // only unread user notifications/ notifications messages + public static final String USER_NOTIFICATIONS_PREFERENCES = "UserNotificationsPreferences"; // preferences for notifications + public static final String HASHTAGS_COUNTER = "HashtagsCounter"; // count the hashtags per group and type + public static final String HASHTAGGED_POSTS = "HashtaggedPosts"; // contains hashtags per type associated with vre and POST + public static final String HASHTAGGED_COMMENTS = "HashtaggedComments"; // contains hashtags per type associated with vre and comment + 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 ATTACHMENTS = "Attachments"; //contains the list of all the attachments in a POST + + //columns + public static final String USER_ID = "userid"; //text + public static final String TYPE = "type"; //text + public static final String PREFERENCE = "preference"; //text + public static final String TIMESTAMP = "timestamp"; //timestamp + public static final String NOT_ID = "notid"; //UUID + public static final String VRE_ID = "vreid"; //text + public static final String POST_ID = "postid"; //UUID + public static final String APP_ID = "appid"; //text + public static final String HASHTAG = "hashtag"; //text + public static final String COMMENT_ID = "commentid"; //UUID + public static final String COUNT = "count"; //big int + public static final String LIKE_ID = "likeid"; //UUID + public static final String INVITE_ID = "inviteid"; //UUID + public static final String STATUS = "status"; //text + public static final String EMAIL = "email"; //text + public static final String ATTACH_ID = "attachid"; //UUID + public static final String URI = "uri"; //text + public static final String NAME = "name"; //text + public static final String DESCRIPTION = "description"; //text + public static final String URI_THUMBNAIL = "urithumbnail"; //text + public static final String MIME_TYPE = "mimetype"; //text + public static final String SENDER_USER_ID = "senderuserid"; //text + public static final String CONTROL_CODE = "controlcode"; //text + public static final String SENDER_FULL_NAME = "senderfullname"; //text + public static final String FULL_NAME = "fullname"; //text + public static final String THUMBNAIL_URL = "thumbnailurl"; //text + public static final String COMMENT = "comment"; //text + public static final String IS_EDIT = "isedit"; //bool + public static final String LAST_EDIT_TIME = "lastedittime"; //timestamp + public static final String SUBJECT_ID = "subjectid"; //text + public static final String SENDER_ID = "senderid"; //text + public static final String SENDER_THUMBNAIL_URL = "senderthumbnailurl"; //text + public static final String IS_READ = "isread"; //bool + public static final String LINK_HOST = "linkhost"; //text + public static final String LIKES_NO = "likesno"; //big int + public static final String LINK_DESCRIPTION = "linkdescription"; //text + public static final String IS_APPLICATION_POST = "isapplicationpost"; //bool --> + public static final String ENTITY_ID = "entityid"; //text + public static final String PRIVACY = "privacy"; //text + public static final String MULTI_FILE_UPLOAD = "multifileupload"; //bool + public static final String COMMENTS_NO = "commentsno"; //big int + public static final String LINK_TITLE = "linktitle"; //text + +} diff --git a/src/main/java/org/gcube/portal/databook/server/Tester.java b/src/main/java/org/gcube/portal/databook/server/Tester.java new file mode 100644 index 0000000..c4f6a71 --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/server/Tester.java @@ -0,0 +1,45 @@ +package org.gcube.portal.databook.server; + +import org.gcube.portal.databook.shared.*; +import org.gcube.portal.databook.shared.ex.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class Tester { + private static DBCassandraDatastaxImpl store; + private static Logger LOGGER = LoggerFactory.getLogger(Tester.class); + + public Tester() { + store = new DBCassandraDatastaxImpl("gcube"); //set to true if you want to drop the KeySpace and recreate it + } + + public static void main(String[] args) throws ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + Tester test = new Tester(); + //test.getComment(); + test.testFunc(); + System.exit(0); + + } + public void testFunc() throws ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + String postIdToUpdate = "047c601d-2291-4974-9224-d6732b1fbe26"; + Post read = store.readPost(postIdToUpdate); + + List readC = store.getAllCommentByPost("047c601d-2291-4974-9224-d6732b1fbe26"); + System.out.println(read); + readC.forEach(c -> System.out.println(c.getText())); + } + public void getComment(){ + String uuid = "820969b2-4632-4197-9fd6-5aafab781faa"; + + Comment c; + try { + c = store.readCommentById(uuid); + System.out.println(c); + } catch (CommentIDNotFoundException e) { + // TODO Auto-generated catch block + System.err.println(e.toString()); + } + } +} diff --git a/src/main/java/org/gcube/portal/databook/shared/Attachment.java b/src/main/java/org/gcube/portal/databook/shared/Attachment.java index 5b8e337..67c1313 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Attachment.java +++ b/src/main/java/org/gcube/portal/databook/shared/Attachment.java @@ -1,9 +1,13 @@ package org.gcube.portal.databook.shared; import java.io.Serializable; +import java.util.Objects; +import com.datastax.oss.driver.api.core.cql.Row; import org.jsonmaker.gwt.client.Jsonizer; +import static org.gcube.portal.databook.server.Schema.*; + @SuppressWarnings("serial") public class Attachment implements Serializable { @@ -37,8 +41,18 @@ public class Attachment implements Serializable { this.description = description; this.thumbnailURL = thumbnailURL; this.mimeType = mimeType; - } - + } + + public Attachment(Row record) { + super(); + this.id = Objects.requireNonNull(record.getUuid(ATTACH_ID)).toString(); + this.uri = record.getString(URI); + this.name = record.getString(NAME); + this.description = record.getString(DESCRIPTION); + this.thumbnailURL = record.getString(URI_THUMBNAIL); + this.mimeType = record.getString(MIME_TYPE); + } + public String getId() { return id; } diff --git a/src/main/java/org/gcube/portal/databook/shared/Comment.java b/src/main/java/org/gcube/portal/databook/shared/Comment.java index f8042e8..6a9ada3 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Comment.java +++ b/src/main/java/org/gcube/portal/databook/shared/Comment.java @@ -1,7 +1,13 @@ package org.gcube.portal.databook.shared; +import com.datastax.oss.driver.api.core.cql.Row; + import java.io.Serializable; import java.util.Date; +import java.util.Objects; + +import static org.gcube.portal.databook.server.Schema.*; +import static org.gcube.portal.databook.server.Schema.THUMBNAIL_URL; /** * @@ -15,7 +21,7 @@ public class Comment implements Serializable, Comparable { private String key; private String userid; private Date time; - private String feedid; + private String postid; private String text; private String fullName; private String thumbnailURL; @@ -33,18 +39,18 @@ public class Comment implements Serializable, Comparable { * @param key * @param userid * @param time - * @param feedid + * @param postid * @param text * @param fullName * @param thumbnailURL */ - public Comment(String key, String userid, Date time, String feedid, + public Comment(String key, String userid, Date time, String postid, String text, String fullName, String thumbnailURL) { super(); this.key = key; this.userid = userid; this.time = time; - this.feedid = feedid; + this.postid = postid; this.text = text; this.fullName = fullName; this.thumbnailURL = thumbnailURL; @@ -58,27 +64,39 @@ public class Comment implements Serializable, Comparable { * @param key * @param userid * @param time - * @param feedid + * @param postid * @param text * @param fullName * @param thumbnailURL * @param isEdit * @param editDate */ - public Comment(String key, String userid, Date time, String feedid, + public Comment(String key, String userid, Date time, String postid, String text, String fullName, String thumbnailURL, boolean isEdit, Date editDate) { super(); this.key = key; this.userid = userid; this.time = time; - this.feedid = feedid; + this.postid = postid; this.text = text; this.fullName = fullName; this.thumbnailURL = thumbnailURL; this.isEdit = isEdit; this.lastEditTime = editDate; } - + + public Comment(Row record) { + super(); + this.key = Objects.requireNonNull(record.getUuid(COMMENT_ID)).toString(); + this.userid = record.getString(USER_ID); + this.time = Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))); + this.postid = Objects.requireNonNull(record.getUuid(POST_ID)).toString(); + this.fullName = record.getString(FULL_NAME); + this.thumbnailURL = record.getString(THUMBNAIL_URL); + this.text = record.getString(COMMENT); + this.isEdit = !record.isNull(IS_EDIT) && record.getBoolean(IS_EDIT); + this.lastEditTime = record.isNull(LAST_EDIT_TIME)? null : Date.from(Objects.requireNonNull(record.getInstant(LAST_EDIT_TIME))); + } /** * * @return the text @@ -121,12 +139,12 @@ public class Comment implements Serializable, Comparable { this.time = time; } - public String getFeedid() { - return feedid; + public String getpostid() { + return postid; } - public void setFeedid(String feedid) { - this.feedid = feedid; + public void setpostid(String postid) { + this.postid = postid; } public String getFullName() { @@ -168,7 +186,7 @@ public class Comment implements Serializable, Comparable { @Override public String toString() { return "Comment [key=" + key + ", userid=" + userid + ", time=" + time - + ", feedid=" + feedid + ", text=" + text + ", fullName=" + + ", postid=" + postid + ", text=" + text + ", fullName=" + fullName + ", thumbnailURL=" + thumbnailURL + ", isEdit=" + isEdit + ", lastEditTime=" + lastEditTime + "]"; } diff --git a/src/main/java/org/gcube/portal/databook/shared/EnhancedFeed.java b/src/main/java/org/gcube/portal/databook/shared/EnhancedFeed.java index f258516..78a7a57 100644 --- a/src/main/java/org/gcube/portal/databook/shared/EnhancedFeed.java +++ b/src/main/java/org/gcube/portal/databook/shared/EnhancedFeed.java @@ -10,7 +10,7 @@ import java.util.ArrayList; */ @SuppressWarnings("serial") public class EnhancedFeed implements Serializable{ - private Feed feed; + private Post post; private boolean liked; private boolean isUsers; private ArrayList comments; @@ -20,26 +20,26 @@ public class EnhancedFeed implements Serializable{ public EnhancedFeed() { super(); } - public EnhancedFeed(Feed feed, boolean liked, boolean isUsers) { + public EnhancedFeed(Post post, boolean liked, boolean isUsers) { super(); - this.feed = feed; + this.post = post; this.liked = liked; this.isUsers = isUsers; } - public EnhancedFeed(Feed feed, boolean liked, boolean isUsers, ArrayList comments) { + public EnhancedFeed(Post post, boolean liked, boolean isUsers, ArrayList comments) { super(); this.isUsers = isUsers; - this.feed = feed; + this.post = post; this.liked = liked; this.comments = comments; } - public EnhancedFeed(Feed feed, boolean liked, boolean isUsers, + public EnhancedFeed(Post post, boolean liked, boolean isUsers, ArrayList comments, ArrayList attachments) { super(); - this.feed = feed; + this.post = post; this.liked = liked; this.isUsers = isUsers; this.comments = comments; @@ -51,11 +51,11 @@ public class EnhancedFeed implements Serializable{ public void setComments(ArrayList comments) { this.comments = comments; } - public Feed getFeed() { - return feed; + public Post getPost() { + return post; } - public void setFeed(Feed feed) { - this.feed = feed; + public void setPost(Post post) { + this.post = post; } public boolean isLiked() { return liked; @@ -77,7 +77,7 @@ public class EnhancedFeed implements Serializable{ } @Override public String toString() { - return "EnhancedFeed [feed=" + feed + ", liked=" + liked + ", isUsers=" + return "EnhancedFeed [post=" + post + ", liked=" + liked + ", isUsers=" + isUsers + ", comments=" + comments + ", attachments=" + attachments + "]"; } diff --git a/src/main/java/org/gcube/portal/databook/shared/Feed.java b/src/main/java/org/gcube/portal/databook/shared/Feed.java deleted file mode 100644 index 514a0db..0000000 --- a/src/main/java/org/gcube/portal/databook/shared/Feed.java +++ /dev/null @@ -1,322 +0,0 @@ -package org.gcube.portal.databook.shared; - -import java.io.Serializable; -import java.util.Date; - -/** - * - * @author Massimiliano Assante, ISTI-CNR - * @deprecated use org.gcube.portal.databook.shared.Post instead - */ -@SuppressWarnings("serial") -public class Feed implements Serializable, Comparable { - - private String key; - private FeedType type; - private String entityId; - private Date time; - private String vreid; - private String uri; - private String uriThumbnail; - private String description; - private PrivacyLevel privacy; - private String fullName; - private String email; - private String thumbnailURL; - private String commentsNo; - private String likesNo; - private String linkTitle; - private String linkDescription; - private String linkHost; - boolean applicationFeed; - /** - * this boolean indicates that the attachments to the post are > 1 - */ - boolean multiFileUpload; - /** - * default constructor - */ - public Feed() { - super(); - } - /** - * To use ONLY for USER Feeds - * - * - * @param key a UUID - * @param type an instance of FeedType - * @param entityId the user or the app unique indentifier - * @param time when - * @param vreid a unique vre id - * @param uri optional uri - * @param uriThumbnail the thumbnail for the link posted - * @param description optional description - * @param privacy the privacy level of PrivacyLevel - * @param fullName - * @param email - * @param thumbnailURL this is the user thumbnail url - * @param linkTitle optional to be used when posting links - * @param linkDescription optional to be used when posting links - * @param linkHost option to be used when posting linkgs - */ - 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 linkTitle, String linkDescription, String linkHost) { - this.key = key; - this.type = type; - this.entityId = entityId; - this.time = time; - this.vreid = vreid; - this.uri = uri; - this.uriThumbnail = uriThumbnail; - this.description = description; - this.privacy = privacy; - this.fullName = fullName; - this.email = email; - this.thumbnailURL = thumbnailURL; - this.commentsNo = "0"; - this.likesNo = "0"; - this.linkDescription = linkDescription; - this.linkTitle = linkTitle; - this.linkHost = linkHost; - this.applicationFeed = false; - } - /** - * To use for USER and ApplicationProfile Feeds - * - * @param key a UUID - * @param type an instance of FeedType - * @param entityId the user or the app unique indentifier - * @param time when - * @param vreid a unique vre id - * @param uri optional uri - * @param uriThumbnail the thumbnail for the link posted - * @param description optional description - * @param privacy the privacy level of PrivacyLevel - * @param fullName - * @param email - * @param thumbnailURL this is the user thumbnail url - * @param linkTitle optional to be used when posting links - * @param linkDescription optional to be used when posting links - * @param applicationFeed tell if this is an application feed or a user 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 linkTitle, String linkDescription, String linkHost, boolean applicationFeed) { - this(key, type, entityId, time, vreid, uri, uriThumbnail, description, privacy, fullName, email, thumbnailURL, linkTitle, linkDescription, linkHost); - this.applicationFeed = applicationFeed; - } - - - /** - * for serialization purposes - * @param key a UUID - * @param type an instance of FeedType - * @param entityId the user or the app unique indentifier - * @param time when - * @param vreid a unique vre id - * @param uri optional uri - * @param uriThumbnail the thumbnail for the link posted - * @param description optional description - * @param privacy the privacy level of PrivacyLevel - * @param fullName - * @param email - * @param thumbnailURL this is the user thumbnail url - * @param linkTitle optional to be used when posting links - * @param linkDescription optional to be used when posting links - */ - 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, boolean multiFileUpload) { - super(); - this.key = key; - this.type = type; - this.entityId = entityId; - this.time = time; - this.vreid = vreid; - this.uri = uri; - this.uriThumbnail = uriThumbnail; - this.description = description; - this.privacy = privacy; - this.fullName = fullName; - this.email = email; - this.thumbnailURL = thumbnailURL; - this.commentsNo = commentsNo; - this.likesNo = likesNo; - this.linkDescription = linkDescription; - this.linkTitle = linkTitle; - this.linkHost = linkHost; - this.applicationFeed = applicationFeed; - this.multiFileUpload = multiFileUpload; - } - /** - * - * @return the key - */ - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public FeedType getType() { - return type; - } - - public void setType(FeedType type) { - this.type = type; - } - /** - * - * @return the User or the App id - */ - public String getEntityId() { - return entityId; - } - /** - * set the User or the App id - * @param entityId the UserId or the AppId id - */ - public void setEntityId(String entityId) { - this.entityId = entityId; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - public String getVreid() { - return vreid; - } - - public void setVreid(String vreid) { - this.vreid = vreid; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public PrivacyLevel getPrivacy() { - return privacy; - } - - public void setPrivacy(PrivacyLevel privacy) { - this.privacy = privacy; - } - - public String getFullName() { - return fullName; - } - - public void setFullName(String fullName) { - this.fullName = fullName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getThumbnailURL() { - return thumbnailURL; - } - - public void setThumbnailURL(String thumbnailURL) { - this.thumbnailURL = thumbnailURL; - } - - public String getCommentsNo() { - return commentsNo; - } - public void setCommentsNo(String commentsNo) { - this.commentsNo = commentsNo; - } - public String getLikesNo() { - return likesNo; - } - public void setLikesNo(String likesNo) { - this.likesNo = likesNo; - } - public String getUriThumbnail() { - return uriThumbnail; - } - public void setUriThumbnail(String uriThumbnail) { - this.uriThumbnail = uriThumbnail; - } - - public String getLinkTitle() { - return linkTitle; - } - public void setLinkTitle(String linkTitle) { - this.linkTitle = linkTitle; - } - public String getLinkDescription() { - return linkDescription; - } - public void setLinkDescription(String linkDescription) { - this.linkDescription = linkDescription; - } - public int compareTo(Feed toCompare) { - if (this.time.after(toCompare.getTime())) - return 1; - if (this.time.before(toCompare.getTime())) - return -1; - return 0; - } - public String getLinkHost() { - return linkHost; - } - public void setLinkHost(String linkHost) { - this.linkHost = linkHost; - } - - public boolean isApplicationFeed() { - return applicationFeed; - } - 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 - + ", time=" + time + ", vreid=" + vreid + ", uri=" + uri - + ", uriThumbnail=" + uriThumbnail + ", description=" - + description + ", privacy=" + privacy + ", fullName=" - + fullName + ", email=" + email + ", thumbnailURL=" - + thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo=" - + likesNo + ", linkTitle=" + linkTitle + ", linkDescription=" - + linkDescription + ", linkHost=" + linkHost - + ", applicationFeed=" + applicationFeed - + ", multiFileUpload=" + multiFileUpload + "]"; - } - -} diff --git a/src/main/java/org/gcube/portal/databook/shared/FeedType.java b/src/main/java/org/gcube/portal/databook/shared/FeedType.java deleted file mode 100644 index 71fe688..0000000 --- a/src/main/java/org/gcube/portal/databook/shared/FeedType.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.gcube.portal.databook.shared; - -/** - * @author Massimiliano Assante ISTI-CNR - * @deprecated use PostType - * @version 1.2 October 2012 - */ -public enum FeedType { - JOIN, SHARE, PUBLISH, TWEET, CONNECTED, - /** - * Special case used when accounting - */ - ACCOUNTING, - /** - * Special case used when a Feed is removed - */ - DISABLED; -} - diff --git a/src/main/java/org/gcube/portal/databook/shared/Invite.java b/src/main/java/org/gcube/portal/databook/shared/Invite.java index be1548d..24bc050 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Invite.java +++ b/src/main/java/org/gcube/portal/databook/shared/Invite.java @@ -1,7 +1,14 @@ package org.gcube.portal.databook.shared; +import com.datastax.oss.driver.api.core.cql.Row; +import org.gcube.portal.databook.shared.ex.InviteStatusNotFoundException; + import java.io.Serializable; import java.util.Date; +import java.util.Objects; + +import static org.gcube.portal.databook.server.Schema.*; + /** * * @author Massimiliano Assante, ISTI-CNR @@ -18,8 +25,23 @@ public class Invite implements Serializable { private InviteStatus status; private Date time; private String senderFullName; - - + + + public 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); + } + + } public Invite() { super(); } @@ -41,6 +63,17 @@ public class Invite implements Serializable { this.senderFullName = senderFullName; } + public Invite(Row record) throws InviteStatusNotFoundException { + super(); + this.key = Objects.requireNonNull(record.getUuid(INVITE_ID)).toString(); + this.senderUserId = record.getString(SENDER_USER_ID); + this.vreid = record.getString(VRE_ID); + this.invitedEmail = record.getString(EMAIL); + this.controlCode = record.getString(CONTROL_CODE); + this.status = getInviteStatusType(Objects.requireNonNull(record.getString(STATUS))); + this.time = Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))); + this.senderFullName = record.getString(SENDER_FULL_NAME); + } diff --git a/src/main/java/org/gcube/portal/databook/shared/Like.java b/src/main/java/org/gcube/portal/databook/shared/Like.java index d772865..e136f66 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Like.java +++ b/src/main/java/org/gcube/portal/databook/shared/Like.java @@ -1,7 +1,15 @@ package org.gcube.portal.databook.shared; +import com.datastax.oss.driver.api.core.cql.Row; +import org.gcube.portal.databook.shared.ex.PostTypeNotFoundException; +import org.gcube.portal.databook.shared.ex.PrivacyLevelTypeNotFoundException; + import java.io.Serializable; import java.util.Date; +import java.util.Objects; + +import static org.gcube.portal.databook.server.Schema.*; + /** * * @author Massimiliano Assante, ISTI-CNR @@ -14,7 +22,7 @@ public class Like implements Serializable { private String key; private String userid; private Date time; - private String feedid; + private String postid; private String fullName; private String thumbnailURL; @@ -22,17 +30,28 @@ public class Like implements Serializable { super(); } - public Like(String key, String userid, Date time, String feedid, + public Like(String key, String userid, Date time, String postid, String fullName, String thumbnailURL) { super(); this.key = key; this.userid = userid; this.time = time; - this.feedid = feedid; + this.postid = postid; this.fullName = fullName; this.thumbnailURL = thumbnailURL; } + public Like(Row record) { + super(); + this.key = Objects.requireNonNull(record.getUuid(LIKE_ID)).toString(); + this.userid = record.getString(USER_ID); + this.time = Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))); + this.postid = Objects.requireNonNull(record.getUuid(POST_ID)).toString(); + this.fullName = record.getString(FULL_NAME); + this.thumbnailURL = record.getString(THUMBNAIL_URL); + } + + public String getKey() { return key; } @@ -57,12 +76,12 @@ public class Like implements Serializable { this.time = time; } - public String getFeedid() { - return feedid; + public String getpostid() { + return postid; } - public void setFeedid(String feedid) { - this.feedid = feedid; + public void setpostid(String postid) { + this.postid = postid; } public String getFullName() { diff --git a/src/main/java/org/gcube/portal/databook/shared/Notification.java b/src/main/java/org/gcube/portal/databook/shared/Notification.java index 36ee57d..be068da 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Notification.java +++ b/src/main/java/org/gcube/portal/databook/shared/Notification.java @@ -1,7 +1,15 @@ package org.gcube.portal.databook.shared; +import com.datastax.oss.driver.api.core.cql.Row; +import org.gcube.portal.databook.shared.ex.NotificationChannelTypeNotFoundException; +import org.gcube.portal.databook.shared.ex.NotificationTypeNotFoundException; + + import java.io.Serializable; import java.util.Date; +import java.util.Objects; + +import static org.gcube.portal.databook.server.Schema.*; /** * @@ -22,9 +30,156 @@ public class Notification implements Serializable { private String senderid; private String senderFullName; private String senderThumbnail; - private String commentKey; + public static 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 feed type + * @param type . + * @return correct enum representing the feed type + * @throws NotificationTypeNotFoundException . + */ + public 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); + } /** * default constructor */ @@ -32,8 +187,6 @@ public class Notification implements Serializable { super(); } - - /** * * @param key @@ -65,41 +218,21 @@ public class Notification implements Serializable { this.senderFullName = senderFullName; this.senderThumbnail = senderThumbnail; } - - /** - * - * @param key - * @param type - * @param userid - * @param subjectid the subject id of this notification, if is a like on a feed then is the feedid, it is a message then is the messageid and so on - * @param time - * @param uri - * @param description - * @param read - * @param senderid - * @param senderFullName - * @param senderThumbnail - * @param commentKey when a mail notification must be sent, stop the embedded discussion at this comment - */ - public Notification(String key, NotificationType type, String userid, - String subjectid, Date time, String uri, String description, - boolean read, String senderid, String senderFullName, - String senderThumbnail, String commentKey) { - super(); - this.key = key; - this.type = type; - this.userid = userid; - this.subjectid = subjectid; - this.time = time; - this.uri = uri; - this.description = description; - this.read = read; - this.senderid = senderid; - this.senderFullName = senderFullName; - this.senderThumbnail = senderThumbnail; - this.commentKey = commentKey; - } + public Notification(Row record) throws NotificationTypeNotFoundException { + super(); + this.key = Objects.requireNonNull(record.getUuid(NOT_ID)).toString(); + this.type = getNotificationType(Objects.requireNonNull(record.getString(TYPE))); + this.userid = record.getString(USER_ID); + this.subjectid = record.getString(SUBJECT_ID); + this.time = Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))); + this.uri = record.getString(URI); + this.description = record.getString(DESCRIPTION); + this.read = record.getBoolean(IS_READ); + this.senderid = record.getString(SENDER_ID); + this.senderFullName = record.getString(SENDER_FULL_NAME); + this.senderThumbnail = record.getString(SENDER_THUMBNAIL_URL); + } /** * * @return . @@ -171,16 +304,6 @@ public class Notification implements Serializable { this.subjectid = subjectid; } - public String getCommentKey() { - return commentKey; - } - - - - public void setCommentKey(String commentKey) { - this.commentKey = commentKey; - } - @Override public String toString() { return "Notification [key=" + key + ", type=" + type + ", userid=" @@ -188,6 +311,6 @@ public class Notification implements Serializable { + ", uri=" + uri + ", description=" + description + ", read=" + read + ", senderid=" + senderid + ", senderFullName=" + senderFullName + ", senderThumbnail=" + senderThumbnail - + ", commentKey=" + commentKey + "]"; + + "]"; } } diff --git a/src/main/java/org/gcube/portal/databook/shared/Post.java b/src/main/java/org/gcube/portal/databook/shared/Post.java index 517d1ff..9822cc0 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Post.java +++ b/src/main/java/org/gcube/portal/databook/shared/Post.java @@ -1,7 +1,15 @@ package org.gcube.portal.databook.shared; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.type.DataTypes; +import org.gcube.portal.databook.shared.ex.PostTypeNotFoundException; +import org.gcube.portal.databook.shared.ex.PrivacyLevelTypeNotFoundException; +import org.gcube.portal.databook.server.Schema.*; import java.io.Serializable; import java.util.Date; +import java.util.Objects; + +import static org.gcube.portal.databook.server.Schema.*; /** * @@ -28,7 +36,7 @@ public class Post implements Serializable, Comparable { private String linkTitle; private String linkDescription; private String linkHost; - boolean applicationFeed; + boolean applicationPost; /** * this boolean indicates that the attachments to the post are > 1 */ @@ -40,7 +48,7 @@ public class Post implements Serializable, Comparable { super(); } /** - * To use ONLY for USER Feeds + * To use ONLY for USER Posts * * * @param key a UUID @@ -79,13 +87,13 @@ public class Post implements Serializable, Comparable { this.linkDescription = linkDescription; this.linkTitle = linkTitle; this.linkHost = linkHost; - this.applicationFeed = false; + this.applicationPost = false; } /** - * To use for USER and ApplicationProfile Feeds + * To use for USER and ApplicationProfile Posts * * @param key a UUID - * @param type an instance of FeedType + * @param type an instance of PostType * @param entityId the user or the app unique indentifier * @param time when * @param vreid a unique vre id @@ -98,13 +106,13 @@ public class Post implements Serializable, Comparable { * @param thumbnailURL this is the user thumbnail url * @param linkTitle optional to be used when posting links * @param linkDescription optional to be used when posting links - * @param applicationFeed tell if this is an application feed or a user feed + * @param applicationPost tell if this is an application Post or a user Post */ public Post(String key, PostType type, String entityId, Date time, String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy, - String fullName, String email, String thumbnailURL, String linkTitle, String linkDescription, String linkHost, boolean applicationFeed) { + String fullName, String email, String thumbnailURL, String linkTitle, String linkDescription, String linkHost, boolean applicationPost) { this(key, type, entityId, time, vreid, uri, uriThumbnail, description, privacy, fullName, email, thumbnailURL, linkTitle, linkDescription, linkHost); - this.applicationFeed = applicationFeed; + this.applicationPost= applicationPost; } @@ -128,7 +136,7 @@ public class Post implements Serializable, Comparable { public Post(String key, PostType 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, boolean multiFileUpload) { + String likesNo, String linkTitle, String linkDescription, String linkHost, boolean applicationPost, boolean multiFileUpload) { super(); this.key = key; this.type = type; @@ -147,10 +155,34 @@ public class Post implements Serializable, Comparable { this.linkDescription = linkDescription; this.linkTitle = linkTitle; this.linkHost = linkHost; - this.applicationFeed = applicationFeed; + this.applicationPost = applicationPost; this.multiFileUpload = multiFileUpload; } - /** + + public Post(Row record) throws PostTypeNotFoundException, PrivacyLevelTypeNotFoundException { + super(); + this.key = Objects.requireNonNull(record.getUuid(POST_ID)).toString(); + this.type = this.getPostType(Objects.requireNonNull(record.getString(TYPE))); + this.entityId = record.getString(ENTITY_ID); + this.time = Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))); + this.vreid = record.getString(VRE_ID); + this.uri = record.getString(URI); + this.uriThumbnail = record.getString(URI_THUMBNAIL); + this.description = record.getString(DESCRIPTION); + this.privacy = this.getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY))); + this.fullName = record.getString(FULL_NAME); + this.email = record.getString(EMAIL); + this.thumbnailURL = record.getString(THUMBNAIL_URL); + this.commentsNo = String.valueOf(record.getLong(COMMENTS_NO)); + this.likesNo = String.valueOf(record.getLong(LIKES_NO)); + this.linkDescription = record.getString(LINK_DESCRIPTION); + this.linkTitle = record.getString(LINK_TITLE); + this.linkHost = record.getString(LINK_HOST); + this.applicationPost = record.getBoolean(IS_APPLICATION_POST); + this.multiFileUpload = record.getBoolean(MULTI_FILE_UPLOAD); + } + + /** * * @return post id */ @@ -293,11 +325,11 @@ public class Post implements Serializable, Comparable { this.linkHost = linkHost; } - public boolean isApplicationFeed() { - return applicationFeed; + public boolean isApplicationPost() { + return applicationPost; } - public void setApplicationFeed(boolean applicationFeed) { - this.applicationFeed = applicationFeed; + public void setApplicationPost(boolean applicationPost) { + this.applicationPost = applicationPost; } public boolean isMultiFileUpload() { return multiFileUpload; @@ -315,8 +347,47 @@ public class Post implements Serializable, Comparable { + thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo=" + likesNo + ", linkTitle=" + linkTitle + ", linkDescription=" + linkDescription + ", linkHost=" + linkHost - + ", applicationFeed=" + applicationFeed + + ", applicationPost=" + applicationPost + ", multiFileUpload=" + multiFileUpload + "]"; } + public 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); + } + public 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); + } + } diff --git a/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java b/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java deleted file mode 100644 index 50d90bb..0000000 --- a/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.gcube.portal.databook.shared; - -import java.io.Serializable; -import java.util.ArrayList; -/** - * - * @author Massimiliano Assante, ISTI-CNR - * @deprecated use RangePosts - */ -@SuppressWarnings("serial") -public class RangeFeeds implements Serializable { - - private int lastReturnedFeedTimelineIndex; - private ArrayList feeds; - - public RangeFeeds() { - super(); - } - - public RangeFeeds(int lastReturnedFeedTimelineIndex, ArrayList feeds) { - super(); - this.lastReturnedFeedTimelineIndex = lastReturnedFeedTimelineIndex; - this.feeds = feeds; - } - - public int getLastReturnedFeedTimelineIndex() { - return lastReturnedFeedTimelineIndex; - } - public void setLastReturnedFeedTimelineIndex(int lastReturnedFeedTimelineIndex) { - this.lastReturnedFeedTimelineIndex = lastReturnedFeedTimelineIndex; - } - public ArrayList getFeeds() { - return feeds; - } - public void setFeeds(ArrayList feeds) { - this.feeds = feeds; - } - - -} diff --git a/src/main/java/org/gcube/portal/databook/shared/ex/FeedTypeNotFoundException.java b/src/main/java/org/gcube/portal/databook/shared/ex/FeedTypeNotFoundException.java deleted file mode 100644 index a39d6dc..0000000 --- a/src/main/java/org/gcube/portal/databook/shared/ex/FeedTypeNotFoundException.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.gcube.portal.databook.shared.ex; - -@SuppressWarnings("serial") -public class FeedTypeNotFoundException extends Exception { - public FeedTypeNotFoundException(String message) { - super(message); - } -} diff --git a/src/main/java/org/gcube/portal/databook/shared/ex/FeedIDNotFoundException.java b/src/main/java/org/gcube/portal/databook/shared/ex/PostIDNotFoundException.java similarity index 58% rename from src/main/java/org/gcube/portal/databook/shared/ex/FeedIDNotFoundException.java rename to src/main/java/org/gcube/portal/databook/shared/ex/PostIDNotFoundException.java index 52c2dce..8fcd23d 100644 --- a/src/main/java/org/gcube/portal/databook/shared/ex/FeedIDNotFoundException.java +++ b/src/main/java/org/gcube/portal/databook/shared/ex/PostIDNotFoundException.java @@ -2,8 +2,8 @@ package org.gcube.portal.databook.shared.ex; @SuppressWarnings("serial") -public class FeedIDNotFoundException extends Exception { - public FeedIDNotFoundException(String message, String postId) { +public class PostIDNotFoundException extends Exception { + public PostIDNotFoundException(String message, String postId) { super("The Post having id: " + postId + " is not present in the database: " + message); } } \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/databook/shared/ex/PostTypeNotFoundException.java b/src/main/java/org/gcube/portal/databook/shared/ex/PostTypeNotFoundException.java new file mode 100644 index 0000000..f8867fa --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/shared/ex/PostTypeNotFoundException.java @@ -0,0 +1,8 @@ +package org.gcube.portal.databook.shared.ex; + +@SuppressWarnings("serial") +public class PostTypeNotFoundException extends Exception { + public PostTypeNotFoundException(String message) { + super(message); + } +}