From 3bd81a415fe3c01bb572d8da32829d964e09b96f Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Mon, 30 Oct 2023 18:52:02 +0100 Subject: [PATCH] Datastax Driver Fully Implemented - Partially Tested - return of deprecated methods --- CHANGELOG.md | 4 +- pom.xml | 93 +- .../server/CassandraClusterConnection.java | 705 ++-- .../server/DBCassandraAstyanaxImpl.java | 2951 +++++++++-------- .../databook/server/RunningCluster.java | 79 +- .../gcube/portal/databook/server/Schema.java | 68 + 6 files changed, 2194 insertions(+), 1706 deletions(-) create mode 100644 src/main/java/org/gcube/portal/databook/server/Schema.java diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb5b9a..da288de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +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). -## [v1.18.0] - 2022-09-20 +## [v2.0.0] - 2023-10-30 - - 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 + - Feature #25901-fix, same as feature 25901 but with minor fixes related to deprecated methods and classes ## [v1.17.0] - 2022-05-13 diff --git a/pom.xml b/pom.xml index d7074d7..d2b63d6 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 maven-parent @@ -11,11 +11,11 @@ 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. - The social networking facilities exploit a NoSQL data store for their storage. Specifically an Apache Cassandra data store. + The gCube Social Networking Library is the 'bridge' between your gCube Applications and the social networking facilities. + The social networking facilities exploit a NoSQL data store for their storage. Specifically an Apache Cassandra data store. scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId} @@ -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..32eed4a 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"); + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java b/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java index c426315..df0b326 100644 --- a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java +++ b/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java @@ -1,63 +1,24 @@ 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 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.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.gcube.portal.databook.shared.*; +import org.gcube.portal.databook.shared.ex.*; + 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; +import static org.gcube.portal.databook.server.CassandraClusterConnection.closeSession; +import static org.gcube.portal.databook.server.Schema.*; /** * @author Massimiliano Assante ISTI-CNR * @author Costantino Perciante ISTI-CNR @@ -69,116 +30,6 @@ 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 @@ -209,22 +60,449 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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; - } /* - * + Utility Functions + */ + private static boolean existRecordbyId(CqlSession session, String id, String tableName, String colName) { + PreparedStatement stmt = session.prepare(QueryBuilder + .selectFrom(tableName).column(colName) + .whereColumn(colName) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + return session.execute(stmt.bind(id)).getAvailableWithoutFetching() > 0; + } + + private static boolean existRecordbyCompId(CqlSession session, String col1, String col2, String id1, String id2, String tableName) { + PreparedStatement stmt = session.prepare(QueryBuilder + .selectFrom(tableName).all() + .whereColumn(col1) + .isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(col2) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + return session.execute(stmt.bind(id1, id2)).getAvailableWithoutFetching() > 0; + } + + private static PreparedStatement updatePostEntry(CqlSession session, String colName){ + return session.prepare(QueryBuilder.update(POSTS) + .setColumn(colName, QueryBuilder.bindMarker()) + .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + private static Optional < Post > findPostById(String postid, CqlSession session) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException { + PreparedStatement stmtFindPost = session.prepare(QueryBuilder + .selectFrom(POSTS).all() + .whereColumn(POST_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + ResultSet rs = session.execute(stmtFindPost.bind(UUID.fromString(postid))); + // We query by the primary key ensuring unicity + Row record = rs.one(); + return (null != record) ? Optional.of(readPostFromRow(record)) :Optional.empty(); + } + + private static Attachment readAttachmentFromRow(Row record) { + Attachment a = new Attachment(); + a.setId(Objects.requireNonNull(record.getUuid(ATTACH_ID)).toString()); + a.setUri(record.getString(URI)); + a.setName(record.getString(NAME)); + a.setDescription(record.getString(DESCRIPTION)); + a.setThumbnailURL(record.getString(URI_THUMBNAIL)); + a.setMimeType(record.getString(MIME_TYPE)); + return a; + } + private static Notification readNotificationFromRow(Row record) throws NotificationTypeNotFoundException { + Notification a = new Notification(); + a.setKey(Objects.requireNonNull(record.getUuid(NOT_ID)).toString()); + a.setType(getNotificationType(Objects.requireNonNull(record.getString(TYPE)))); + a.setUserid(record.getString(USER_ID)); + a.setSubjectid(record.getString(SUBJECT_ID)); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setUri(record.getString(URI)); + a.setDescription(record.getString(DESCRIPTION)); + a.setRead(record.getBoolean(IS_READ)); + a.setSenderid(record.getString(SENDER_ID)); + a.setSenderFullName(record.getString(SENDER_FULL_NAME)); + a.setSenderThumbnail(record.getString(SENDER_THUMBNAIL_URL)); + return a; + } + private static Post readPostFromRow(Row record) throws FeedTypeNotFoundException, PrivacyLevelTypeNotFoundException { + Post a = new Post(); + + a.setKey(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); + a.setType(getPostType(Objects.requireNonNull(record.getString(TYPE)))); + a.setEntityId(record.getString(ENTITY_ID)); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setVreid(record.getString(VRE_ID)); + a.setUri(record.getString(URI)); + a.setUriThumbnail(record.getString(URI_THUMBNAIL)); + a.setDescription(record.getString(DESCRIPTION)); + a.setPrivacy(getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY)))); + a.setFullName(record.getString(FULL_NAME)); + a.setEmail(record.getString(EMAIL)); + a.setThumbnailURL(record.getString(THUMBNAIL_URL)); + a.setCommentsNo(String.valueOf(record.getLong(COMMENTS_NO))); + a.setLikesNo(String.valueOf(record.getLong(LIKES_NO))); + a.setLinkDescription(record.getString(LINK_DESCRIPTION)); + a.setLinkTitle(record.getString(LINK_TITLE)); + a.setLinkHost(record.getString(LINK_HOST)); + a.setApplicationFeed(record.getBoolean(IS_APPLICATION_POST)); + a.setMultiFileUpload(record.getBoolean(MULTI_FILE_UPLOAD)); + + return a; + } + private static Like readLikeFromRow(Row record) { + Like a = new Like(); + a.setKey(Objects.requireNonNull(record.getUuid(LIKE_ID)).toString()); + a.setUserid(record.getString(USER_ID)); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setFeedid(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); + a.setFullName(record.getString(FULL_NAME)); + a.setThumbnailURL(record.getString(THUMBNAIL_URL)); + return a; + } + private static Comment readCommentFromRow(Row record) { + Comment a = new Comment(); + a.setKey(Objects.requireNonNull(record.getUuid(COMMENT_ID)).toString()); + a.setUserid(record.getString(USER_ID)); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setFeedid(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); + a.setFullName(record.getString(FULL_NAME)); + a.setThumbnailURL(record.getString(THUMBNAIL_URL)); + a.setText(record.getString(COMMENT)); + a.setEdit(!record.isNull(IS_EDIT) && record.getBoolean(IS_EDIT)); + a.setLastEditTime(record.isNull(LAST_EDIT_TIME)? null : Date.from(Objects.requireNonNull(record.getInstant(LAST_EDIT_TIME)))); + return a; + } + private static Invite readAInviteFromRow(Row record) throws InviteStatusNotFoundException { + Invite a = new Invite(); + a.setKey(Objects.requireNonNull(record.getUuid(INVITE_ID)).toString()); + a.setSenderUserId(record.getString(SENDER_USER_ID)); + a.setVreid(record.getString(VRE_ID)); + a.setInvitedEmail(record.getString(EMAIL)); + a.setControlCode(record.getString(CONTROL_CODE)); + a.setStatus(getInviteStatusType(Objects.requireNonNull(record.getString(STATUS)))); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setSenderFullName(record.getString(SENDER_FULL_NAME)); + return a; + } + private static Feed readFeedFromRow(Row record) throws FeedTypeNotFoundException, PrivacyLevelTypeNotFoundException { + Feed a = new Feed(); + + a.setKey(Objects.requireNonNull(record.getUuid(POST_ID)).toString()); + a.setType(getFeedType(Objects.requireNonNull(record.getString(TYPE)))); + a.setEntityId(record.getString(ENTITY_ID)); + a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP)))); + a.setVreid(record.getString(VRE_ID)); + a.setUri(record.getString(URI)); + a.setUriThumbnail(record.getString(URI_THUMBNAIL)); + a.setDescription(record.getString(DESCRIPTION)); + a.setPrivacy(getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY)))); + a.setFullName(record.getString(FULL_NAME)); + a.setEmail(record.getString(EMAIL)); + a.setThumbnailURL(record.getString(THUMBNAIL_URL)); + a.setCommentsNo(String.valueOf(record.getLong(COMMENTS_NO))); + a.setLikesNo(String.valueOf(record.getLong(LIKES_NO))); + a.setLinkDescription(record.getString(LINK_DESCRIPTION)); + a.setLinkTitle(record.getString(LINK_TITLE)); + a.setLinkHost(record.getString(LINK_HOST)); + a.setApplicationFeed(record.getBoolean(IS_APPLICATION_POST)); + a.setMultiFileUpload(record.getBoolean(MULTI_FILE_UPLOAD)); + + return a; + } + + + private static Optional < Feed > findFeedById(String postid, CqlSession session) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException { + 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(readFeedFromRow(record)) :Optional.empty(); + } + private static Optional < Notification > findNotById(String notid, CqlSession session) throws NotificationTypeNotFoundException { + PreparedStatement stmtFind = session.prepare(QueryBuilder + .selectFrom(NOTIFICATIONS).all() + .whereColumn(NOT_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + ResultSet rs = session.execute(stmtFind.bind(UUID.fromString(notid))); + // We query by the primary key ensuring unicity + Row record = rs.one(); + return (null != record) ? Optional.of(readNotificationFromRow(record)) :Optional.empty(); + } + + + private static PreparedStatement updateInviteEntry(CqlSession session, String colName){ + return session.prepare(QueryBuilder.update(INVITES) + .setColumn(colName, QueryBuilder.bindMarker()) + .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement updateVreInviteEntry(CqlSession session, String colName){ + return session.prepare(QueryBuilder.update(VRE_INVITES) + .setColumn(colName, QueryBuilder.bindMarker()) + .whereColumn(VRE_ID).isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement deleteHashtagEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_POSTS) + .whereColumn(HASHTAG) + .isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(POST_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement deleteHashtagCommentEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_COMMENTS) + .whereColumn(HASHTAG) + .isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(COMMENT_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement deleteLikeEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(LIKES) + .whereColumn(LIKE_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement deleteUserLikeEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(USER_LIKED_POSTS) + .whereColumn(USER_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(LIKE_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement updateCommentEntry(CqlSession session, String colName){ + return session.prepare(QueryBuilder.update(COMMENTS) + .setColumn(colName, QueryBuilder.bindMarker()) + .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement deleteCommentEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(COMMENTS) + .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement updateNotificationEntry(CqlSession session, String colName){ + return session.prepare(QueryBuilder.update(NOTIFICATIONS) + .setColumn(colName, QueryBuilder.bindMarker()) + .whereColumn(NOT_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + + private static PreparedStatement deleteUnreadNotEntry(CqlSession session){ + return session.prepare(QueryBuilder.deleteFrom(USER_NOTIFICATIONS_UNREAD) + .whereColumn(USER_ID) + .isEqualTo(QueryBuilder.bindMarker()) + .whereColumn(TIMESTAMP) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); + } + private static BatchStatement getBatch(){ + return BatchStatement.builder(BatchType.LOGGED).build(); + } + + private static PreparedStatement createPostEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(POSTS) + .value(POST_ID, QueryBuilder.bindMarker()) + .value(LINK_HOST, QueryBuilder.bindMarker()) + .value(DESCRIPTION, QueryBuilder.bindMarker()) + .value(EMAIL, QueryBuilder.bindMarker()) + .value(LIKES_NO, QueryBuilder.bindMarker()) + .value(THUMBNAIL_URL, QueryBuilder.bindMarker()) + .value(LINK_DESCRIPTION, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(URI, QueryBuilder.bindMarker()) + .value(IS_APPLICATION_POST, QueryBuilder.bindMarker()) + .value(ENTITY_ID, QueryBuilder.bindMarker()) + .value(PRIVACY, QueryBuilder.bindMarker()) + .value(TYPE, QueryBuilder.bindMarker()) + .value(URI_THUMBNAIL, QueryBuilder.bindMarker()) + .value(VRE_ID, QueryBuilder.bindMarker()) + .value(MULTI_FILE_UPLOAD, QueryBuilder.bindMarker()) + .value(FULL_NAME, QueryBuilder.bindMarker()) + .value(COMMENTS_NO, QueryBuilder.bindMarker()) + .value(LINK_TITLE, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createUserTimelineEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(USER_TIMELINE_POSTS) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(POST_ID, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createVreTimelineEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(VRE_TIMELINE_POSTS) + .value(VRE_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(POST_ID, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createAppTimelineEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(APP_TIMELINE_POSTS) + .value(APP_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(POST_ID, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createNotificationEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(NOTIFICATIONS) + .value(NOT_ID, QueryBuilder.bindMarker()) + .value(TYPE, QueryBuilder.bindMarker()) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(SUBJECT_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(DESCRIPTION, QueryBuilder.bindMarker()) + .value(URI, QueryBuilder.bindMarker()) + .value(SENDER_ID, QueryBuilder.bindMarker()) + .value(SENDER_FULL_NAME, QueryBuilder.bindMarker()) + .value(SENDER_THUMBNAIL_URL, QueryBuilder.bindMarker()) + .value(IS_READ, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createUserNotificationsEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(USER_NOTIFICATIONS) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(NOT_ID, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createUnreadNotificationEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(USER_NOTIFICATIONS_UNREAD) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(NOT_ID, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createNotificationPreferenceEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(USER_NOTIFICATIONS_PREFERENCES) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(TYPE, QueryBuilder.bindMarker()) + .value(PREFERENCE, QueryBuilder.bindMarker()) + .build()); + } + private static PreparedStatement createNewCommentEntry(CqlSession session){ + return session.prepare( + QueryBuilder.insertInto(COMMENTS) + .value(COMMENT_ID, QueryBuilder.bindMarker()) + .value(USER_ID, QueryBuilder.bindMarker()) + .value(FULL_NAME, QueryBuilder.bindMarker()) + .value(THUMBNAIL_URL, QueryBuilder.bindMarker()) + .value(COMMENT, QueryBuilder.bindMarker()) + .value(POST_ID, QueryBuilder.bindMarker()) + .value(TIMESTAMP, QueryBuilder.bindMarker()) + .value(IS_EDIT, QueryBuilder.bindMarker()) + .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()); + } + + + /* + * ********************** FRIENDSHIPS (CONNECTIONS) *********************** * */ @@ -233,16 +511,6 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @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; } /** @@ -250,53 +518,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @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; + return true; } /** * {@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; + return true; } /** * {@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; } /** @@ -304,130 +540,111 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @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); + public boolean saveUserFeed(Feed post) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the user Timeline - m.withRow(cf_UserTline, feed.getEntityId()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); + //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.isApplicationFeed(), + 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 (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); + 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()))); + } - return execute(m); + 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) { - MutationBatch m = initSavePost(post); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the user Timeline - m.withRow(cf_UserTline, post.getEntityId()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + //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.isApplicationFeed(), + 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) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, post.getVreid()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + 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()))); + } - return execute(m); + Boolean result = session.execute(writeBatch).wasApplied(); + if (result){ + _log.info("Wrote user post with id " + post.getKey()); + } + closeSession(session); + + return result; } /** * {@inheritDoc} @@ -456,8 +673,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { public boolean saveUserPost(Post post, List attachments) { if (attachments != null && !attachments.isEmpty()) post.setMultiFileUpload(true); - boolean saveFeedResult = saveUserPost(post); - if (saveFeedResult) { + boolean savePostResult = saveUserPost(post); + if (savePostResult) { String postkey = post.getKey(); for (Attachment attachment : attachments) { boolean attachSaveResult = saveAttachmentEntry(postkey, attachment); @@ -474,22 +691,48 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override @Deprecated - public boolean saveAppFeed(Feed feed) { - MutationBatch m = initSaveFeed(feed); + public boolean saveAppFeed(Feed post) { + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the Applications Timeline - m.withRow(cf_AppTline, feed.getEntityId()) - .putColumn(feed.getTime().getTime()+"", feed.getKey().toString(), null); + //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.isApplicationFeed(), + 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 (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); + 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 = execute(m); + + boolean result = session.execute(writeBatch).wasApplied(); if (result) - _log.trace("saveAppFeed OK!"); + _log.info("Wrote app post with id " + post.getKey()); + closeSession(session); return result; } /** @@ -497,21 +740,47 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public boolean saveAppPost(Post post) { - MutationBatch m = initSavePost(post); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the Applications Timeline - m.withRow(cf_AppTline, post.getEntityId()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + //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.isApplicationFeed(), + 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) { - //an entry in the VRES Timeline - m.withRow(cf_VRETline, post.getVreid()) - .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + 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 = execute(m); + + boolean result = session.execute(writeBatch).wasApplied(); if (result) - _log.trace("saveAppFeed OK!"); + _log.info("Wrote app post with id " + post.getKey()); + closeSession(session); return result; } /** @@ -559,44 +828,58 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @Deprecated @Override public boolean saveFeedToVRETimeline(String feedKey, String vreid) throws FeedIDNotFoundException { - String feedId = feedKey; - Feed toCheck = null; + Feed toCheck; try { - toCheck = readFeed(feedId); + toCheck = readFeed(feedKey); if (toCheck == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId, feedId); + throw new FeedIDNotFoundException("Could not find Post with id " + feedKey, feedKey); } catch (Exception e) { e.printStackTrace(); return false; - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + } + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the user Timeline - m.withRow(cf_VRETline, vreid) - .putColumn(toCheck.getTime().getTime()+"", feedKey, null); - return execute(m); + 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; + } } /** * {@inheritDoc} */ @Override public boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException { - String postId = postKey; - Post toCheck = null; + Post toCheck; try { - toCheck = readPost(postId); + toCheck = readPost(postKey); if (toCheck == null) - throw new FeedIDNotFoundException("Could not find Post with id " + postId, postId); + throw new FeedIDNotFoundException("Could not find Post with id " + postKey, postKey); } catch (Exception e) { e.printStackTrace(); return false; - } - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + } + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the user Timeline - m.withRow(cf_VRETline, vreid) - .putColumn(toCheck.getTime().getTime()+"", postKey, null); - return execute(m); + 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; + } } /** * {@inheritDoc} @@ -606,52 +889,17 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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) { + CqlSession session = conn.getKeyspaceSession(); + Feed post; + try{ + post = findFeedById(feedid, session).get(); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); return null; - } - return toReturn; + } + return post; } /** * {@inheritDoc} @@ -660,52 +908,17 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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) { + CqlSession session = conn.getKeyspaceSession(); + Post post; + try{ + post = findPostById(postid, session).get(); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); return null; - } - return toReturn; + } + return post; } /** * {@inheritDoc} @@ -717,33 +930,42 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); - OperationResult> result = null; + ResultSet result = null; try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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 = 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()); + List toReturn = result.all().stream().map(row-> { + try { + Instant postTime = row.getInstant(TIMESTAMP); + if (Date.from(postTime).getTime() > timeInMillis){ + try{ + Feed toCheck = readFeed(row.getUuid(POST_ID).toString()); if (toCheck.getType() != FeedType.DISABLED) - toReturn.add(toCheck); - } catch (PrivacyLevelTypeNotFoundException - | FeedTypeNotFoundException - | FeedIDNotFoundException - | ColumnNameNotFoundException e) { - e.printStackTrace(); - } - } + return toCheck; + } catch (ColumnNameNotFoundException | + PrivacyLevelTypeNotFoundException e) { + throw new RuntimeException(e); + } catch (FeedIDNotFoundException e) { + throw new RuntimeException(e); + } catch (FeedTypeNotFoundException e) { + throw new RuntimeException(e); + } + } + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } + return null; + }).collect(Collectors.toList()); + return toReturn; } /** @@ -755,33 +977,42 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { if (timeInMillis > now.getTime()) throw new IllegalArgumentException("the timeInMillis must be before today"); - OperationResult> result = null; + ResultSet result = null; try { - result = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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 = 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()); + 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) - toReturn.add(toCheck); - } catch (PrivacyLevelTypeNotFoundException - | FeedTypeNotFoundException - | FeedIDNotFoundException - | ColumnNameNotFoundException e) { - e.printStackTrace(); - } - } + return toCheck; + } catch (ColumnNameNotFoundException | + PrivacyLevelTypeNotFoundException e) { + throw new RuntimeException(e); + } catch (FeedIDNotFoundException e) { + throw new RuntimeException(e); + } catch (FeedTypeNotFoundException e) { + throw new RuntimeException(e); + } + } + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } + return null; + }).collect(Collectors.toList()); + return toReturn; } /** @@ -791,16 +1022,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @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); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + PreparedStatement stmt1 = updatePostEntry(session, TYPE); + writeBatch.add(stmt1.bind(FeedType.DISABLED.toString(), UUID.fromString(toDelete.getKey()))); + try { - m.execute(); - } catch (ConnectionException e) { - _log.error("Delete Feed ERROR for feedid " + feedId); + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + _log.error("Delete Post ERROR for postid " + feedId); + closeSession(session); return false; } - _log.info("Delete Feed OK"); + _log.info("Delete Post OK"); return true; } /** @@ -809,13 +1045,18 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @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); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); + + PreparedStatement stmt1 = updatePostEntry(session, TYPE); + writeBatch.add(stmt1.bind(PostType.DISABLED.toString(), UUID.fromString(toDelete.getKey()))); + try { - m.execute(); - } catch (ConnectionException e) { + 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"); @@ -852,7 +1093,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } /** * {@inheritDoc} - * @throws Exception + * @throws Exception */ @Deprecated @Override @@ -872,17 +1113,17 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { List lastComments = getRecentCommentsByUserAndDateBody(userid, timeInMillis, false); // evaluate unique feeds' ids - HashSet feedsIds = new HashSet(); + HashSet postIds = new HashSet(); for (Comment comment : lastComments) { - String feedId = comment.getFeedid(); + String postId = comment.getFeedid(); try{ - if(!feedsIds.contains(feedId)){ - feedsIds.add(feedId); - toReturn.add(readFeed(feedId)); + if(!postIds.contains(postId)){ + postIds.add(postId); + toReturn.add(readFeed(postId)); } }catch(Exception e){ - _log.error("Unable to retrieve feed with id " + feedId, e); + _log.error("Unable to retrieve feed with id " + postId, e); } } @@ -891,7 +1132,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } /** * {@inheritDoc} - * @throws Exception + * @throws Exception */ @Override public List getRecentCommentedPostsByUserAndDate(String userid, @@ -932,10 +1173,10 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * helper method that retrieve all the feeds belongin to a list of Ids * @param feedIds * @return - * @throws ColumnNameNotFoundException - * @throws FeedIDNotFoundException - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + * @throws FeedIDNotFoundException + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException */ private List getFeedsByIds(List feedIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { ArrayList toReturn = new ArrayList(); @@ -950,10 +1191,10 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * helper method that retrieve all the feeds belongin to a list of Ids * @param postIds * @return - * @throws ColumnNameNotFoundException - * @throws FeedIDNotFoundException - * @throws FeedTypeNotFoundException - * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + * @throws FeedIDNotFoundException + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException */ private List getPostsByIds(List postIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { ArrayList toReturn = new ArrayList(); @@ -971,24 +1212,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Deprecated private ArrayList getUserFeedIds(String userid) { - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } /** * helper method that retrieve all the post Ids belonging to a user @@ -996,49 +1244,62 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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; + 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 = conn.getKeyspace().prepareQuery(cf_UserTline) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } /** - * helper method that return whether the user + * helper method that return whether the user * @param userid user identifier - * @param feedid the feed identifier + * @param postid 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(); - } + private boolean isPostLiked(String userid, String postid) { - // 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; + 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); + } + for (Row row: result.all()){ + if (row.getUuid(POST_ID).toString().equals(postid)){ + return true; } } + return false; } @@ -1050,24 +1311,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Deprecated private ArrayList getAppFeedIds(String appid) { - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_AppTline) - .getKeySlice(appid) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind.bind(appid)); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); } - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } /** * helper method that retrieve all the post Ids belonging to an application @@ -1075,157 +1343,84 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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; + 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 = conn.getKeyspace().prepareQuery(cf_AppTline) - .getKeySlice(appid) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind.bind(appid)); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); } - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } - + /** * {@inheritDoc} */ @Deprecated @Override public List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + //possible error index ArrayList toReturn = new ArrayList(); - OperationResult> result; + 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 = 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) { + result = session.execute(stmtFind.bind(PrivacyLevel.PORTAL.toString())); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); - return toReturn; + closeSession(session); + } + for (Row row: result.all()) { + Feed toAdd = readFeedFromRow(row); + if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) + toReturn.add(toAdd); } return toReturn; } @Override public List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + //possible error index ArrayList toReturn = new ArrayList(); - OperationResult> result; + 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 = 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) { + result = session.execute(stmtFind.bind(PrivacyLevel.PORTAL.toString())); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); - return toReturn; + closeSession(session); + } + for (Row row: result.all()) { + Post toAdd = readPostFromRow(row); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) + toReturn.add(toAdd); } return toReturn; } @@ -1262,7 +1457,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { //check if quantity is greater than user feeds quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; - //need them in reverse order + //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) { @@ -1280,7 +1475,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { /** * {@inheritDoc} */ - @Override + @Override @Deprecated public List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { return getFeedsByIds(getVREFeedIds(vreid)); @@ -1325,7 +1520,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { //check if quantity is greater than user posts quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; - //need them in reverse order + //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) { @@ -1347,7 +1542,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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); @@ -1365,15 +1560,15 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { rangeEnd = 0; _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); - //need them in reverse order + //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)); + _log.trace("Read recent post, i=" + i + " id= " + feedIDs.get(i)); } else { - _log.trace("Read and skipped feed, i=" + i + " id=: " + feedIDs.get(i) + " (Removed Feed) ."); + _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; @@ -1390,7 +1585,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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); @@ -1408,7 +1603,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { rangeEnd = 0; _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); - //need them in reverse order + //need them in reverse order int howMany = from; for (int i = rangeStart; i > rangeEnd; i--) { Post toAdd = readPost(feedIDs.get(i)); @@ -1433,24 +1628,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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; + 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 = conn.getKeyspace().prepareQuery(cf_VRETline) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind.bind(vreid)); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); } - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } /** * get a list of user vre post UUIDs in chronological order from the oldest to the more recent @@ -1458,27 +1660,34 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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; + 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 = conn.getKeyspace().prepareQuery(cf_VRETline) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind.bind(vreid)); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); } - ArrayList toReturn = new ArrayList(); - - // Iterate rows and their columns - for (Row row : result.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); + List toReturn = result.all().stream().map(row-> { + try { + String postid = row.getUuid(POST_ID).toString(); + return postid; + } catch (RuntimeException e) { + throw new RuntimeException(e); } - } - return toReturn; + }).collect(Collectors.toList()); + + return (ArrayList) toReturn; } /* - * + * ********************** NOTIFICATIONS *********************** * */ @@ -1487,28 +1696,39 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @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); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //an entry in the user Notifications Timeline - m.withRow(cf_UserNotifications, n.getUserid()).putColumn(n.getTime().getTime()+"", n.getKey().toString(), null); + //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 - m.withRow(cf_UserNotificationsUnread, n.getUserid()).putColumn(n.getTime().getTime()+"", n.getKey().toString(), null); - - return execute(m); + 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; + } } /** @@ -1517,34 +1737,15 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @Override public Notification readNotification(String notificationid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException { Notification toReturn = new Notification(); - OperationResult> result; + CqlSession session = conn.getKeyspaceSession(); 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) { + toReturn = findNotById(notificationid, session).get(); + closeSession(session); + } + catch (Exception e) { e.printStackTrace(); - return null; - } + closeSession(session); + } return toReturn; } /** @@ -1556,46 +1757,51 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { if (toSet == null) throw new NotificationIDNotFoundException("The specified notification to set Read with id: " + notificationidToSet + " does not exist"); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); - //set as read - m.withRow(cf_Notifications, notificationidToSet).putColumn("Read", true, null); + //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 - m.withRow(cf_UserNotificationsUnread, toSet.getUserid()).deleteColumn(toSet.getTime().getTime()+""); + writeBatch.add(deleteUnreadNotEntry(session).bind(toSet.getUserid(), toSet.getTime().toInstant())); // execute the operations try { - m.execute(); - } catch (ConnectionException e) { + boolean res = session.execute(writeBatch).wasApplied(); + closeSession(session); + return res; + } catch (Exception 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; + 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 = conn.getKeyspace().prepareQuery(cf_UserNotifications) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } + // Iterate rows and their columns + for (Row row : result.all()) { + toReturn.add(row.getUuid(NOT_ID).toString()); } return toReturn; } @@ -1605,22 +1811,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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; + 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 = conn.getKeyspace().prepareQuery(cf_UserNotificationsUnread) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } + // Iterate rows and their columns + for (Row row : result.all()) { + toReturn.add(row.getUuid(NOT_ID).toString()); } return toReturn; } @@ -1634,7 +1844,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { //check if quantity is greater than user feeds limit = (limit > notificationsIDs.size()) ? notificationsIDs.size() : limit; - //need them in reverse order + //need them in reverse order for (int i = notificationsIDs.size()-1; i >= (notificationsIDs.size()-limit); i--) { Notification toAdd = null; try { @@ -1644,7 +1854,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { _log.error("Notification not found id=" + notificationsIDs.get(i)); } } - return toReturn; + return toReturn; } /** * {@inheritDoc} @@ -1654,7 +1864,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { ArrayList toReturn = new ArrayList(); ArrayList notificationsIDs = getUnreadUserNotificationsIds(userid); - //need them in reverse order + //need them in reverse order for (int i = notificationsIDs.size()-1; i >= 0; i--) { try{ toReturn.add(readNotification(notificationsIDs.get(i))); @@ -1663,7 +1873,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } } - return toReturn; + return toReturn; } /** * {@inheritDoc} @@ -1672,7 +1882,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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); @@ -1690,12 +1900,12 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { rangeEnd = 0; _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); - //need them in reverse order + //need them in reverse order for (int i = rangeStart; i > rangeEnd; i--) { Notification toAdd = readNotification(notificationsIDs.get(i)); toReturn.add(toAdd); } - return toReturn; + return toReturn; } /** * {@inheritDoc} @@ -1714,16 +1924,16 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } catch (NotificationIDNotFoundException e) { _log.error("Could not set read notification with id =" + notificationsIDs.get(i)); - } + } } - return true; + return true; } /** * {@inheritDoc} */ @Override - public boolean checkUnreadNotifications(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException { + public boolean checkUnreadNotifications(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException { ArrayList unreadNotifications = getUnreadUserNotificationsIds(userid); @@ -1762,7 +1972,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { return false; } /* - * + * ********************** NOTIFICATION SETTINGS *********************** * */ @@ -1778,7 +1988,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { _log.warn("Single Notification preference of " + userid + " Type: " + notificationType + " not existing ... creating default"); return createNewNotificationType(userid, notificationType); } - else if (toProcess.length == 0) + else if (toProcess.length == 0) return toReturn; else for (int i = 0; i < toProcess.length; i++) { @@ -1792,7 +2002,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ private List createNewNotificationType(String userid, NotificationType notificationType) { List toReturn = new ArrayList(); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); + String valueToInsert = ""; NotificationChannelType[] wpTypes = NotificationChannelType.values(); @@ -1802,9 +2013,20 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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) { + + 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; } @@ -1815,7 +2037,8 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public boolean setUserNotificationPreferences(String userid, Map enabledChannels) { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); for (NotificationType nType : enabledChannels.keySet()) { String valueToInsert = ""; @@ -1829,35 +2052,43 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { valueToInsert = ""; _log.trace("No Channels selected for " + nType + " by " + userid); } - m.withRow(cf_UserNotificationsPreferences, userid).putColumn(nType.toString(), valueToInsert, null); + writeBatch.add(createNotificationPreferenceEntry(session).bind(userid, nType.toString(), valueToInsert)); } - boolean overAllresult = execute(m); + 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; + 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; + + 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 = conn.getKeyspace().prepareQuery(cf_UserNotificationsPreferences) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult().getRowByIndex(0).getColumns().size() == 0) { + if (result.all().isEmpty()) { _log.info("Userid " + userid + " settings not found, initiating its preferences..."); HashMap toCreate = new HashMap(); @@ -1877,26 +2108,25 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } 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])); - } + 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(column.getName()), toAdd); } + toReturn.put(getNotificationType(row.getString(TYPE)), toAdd); } + } } return toReturn; } /* - * + * ********************** COMMENTS *********************** * */ @@ -1911,30 +2141,33 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { if (comment.getFeedid() == null) throw new NullArgumentException("Comment feed id must be not null"); - String feedId = comment.getFeedid(); + String postid = comment.getFeedid(); try { - toComment = readFeed(feedId); + toComment = readFeed(postid); if (toComment == null) - throw new FeedIDNotFoundException("Could not find Feed with id " + feedId + " to associate this comment", feedId); + throw new FeedIDNotFoundException("Could not find Feed with id " + postid + " to associate this comment", postid); } 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); + } + 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.getFeedid()), + comment.getTime().toInstant(), + null + )); try { - m.execute(); - } catch (ConnectionException e) { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { e.printStackTrace(); return false; } @@ -1946,34 +2179,28 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ public Comment readCommentById(String commentId) throws CommentIDNotFoundException { - Comment toReturn = new Comment(); - OperationResult> result; - try { - result = conn.getKeyspace().prepareQuery(cf_Comments) - .getKey(commentId) - .execute(); + Comment toReturn = null; - ColumnList columns = result.getResult(); - if (columns.size() == 0) { + 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 = readCommentFromRow(result.one()); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); - 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; } /** @@ -1989,54 +2216,32 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getAllCommentByPost(String postid) { + //possible error index List toReturn = new ArrayList(); - - PreparedIndexExpression clause = cf_Comments.newIndexClause().whereColumn("Feedid").equals().value(postid); - OperationResult> result; + ResultSet result = null; + CqlSession session = conn.getKeyspaceSession(); + PreparedStatement stmtFind = session.prepare(QueryBuilder + .selectFrom(COMMENTS).all() + .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); 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()); - } - } + result = session.execute(stmtFind.bind(UUID.fromString(postid))); + closeSession(session); + for (Row row : result.all()) { + Comment toAdd = readCommentFromRow(row); toReturn.add(toAdd); } - } catch (Exception e) { + } catch (Exception e){ e.printStackTrace(); - return null; + closeSession(session); } + return toReturn; } /** * {@inheritDoc} - * @throws Exception + * @throws Exception */ @Override public List getRecentCommentsByUserAndDate(final String userid, @@ -2054,8 +2259,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { commentsByUser = getRecentCommentsByUserAndDateBody(userid, timeInMillis, true); - return commentsByUser; - } + return commentsByUser; } /** * Private method that allows also to specify if the returned list must be sorted or not @@ -2063,74 +2267,48 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @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 long timeInMillis, boolean sort){ + //possible error 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) { + CqlSession session = conn.getKeyspaceSession(); - // use a temporary list for each thread - List partialCommentsList = new ArrayList(); + ResultSet result = null; + PreparedStatement stmtFind = session.prepare(QueryBuilder + .selectFrom(COMMENTS) + .all() + .build()); + try { + result = session.execute(stmtFind.bind()); + closeSession(session); - nextRow: for (Row row : rows) { - for(Column column: row.getColumns()){ - if(column.getName().equals("Userid")){ - if(column.getStringValue().equals(userid)){ + if (!result.all().isEmpty()){ + result.all().parallelStream().forEach( row->{ + if(row.getString(USER_ID).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); + Comment c = readCommentById(row.getUuid(COMMENT_ID).toString()); + Post p = readPost(c.getFeedid()); + 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.getKey(), e); + _log.error("Unable to read comment with id" + row.getString(COMMENT_ID), 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; - } - } - }); + } catch (Exception e){ + e.printStackTrace(); + closeSession(session); + } if(sort) Collections.sort(commentsByUser, Collections.reverseOrder()); - return commentsByUser; - } /** @@ -2138,19 +2316,23 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @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); + 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 { - m.execute(); - } catch (ConnectionException e) { + 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; } - _log.info("Comments update OK to: " + comment2Edit.getText()); - return true; } /** @@ -2163,13 +2345,14 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { updateCommentNoResult = updateFeedCommentsCount(toUpdate, false); if (updateCommentNoResult) { - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_Comments, commentid) - .delete(); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch().add(deleteCommentEntry(session).bind(UUID.fromString(commentid))); try { - m.execute(); - } catch (ConnectionException e) { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + closeSession(session); _log.error("Comment Delete FAILED for " + commentid + " from Feed " + feedid); e.printStackTrace(); } @@ -2198,30 +2381,33 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } catch (Exception e) { e.printStackTrace(); return false; - } - if (isFeedLiked(like.getUserid(), feedId)) { + } + if (isPostLiked(like.getUserid(), feedId)) { _log.info("User " + like.getUserid() + " already liked Feed " + feedId); return true; } else { + CqlSession session = conn.getKeyspaceSession(); // 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); - + BatchStatement writeBatch = getBatch() + .add(createNewLikeEntry(session).bind(UUID.fromString(like.getKey()), + like.getUserid(), + like.getFullName(), + like.getThumbnailURL(), + UUID.fromString(like.getFeedid()), + like.getTime().toInstant())) + .add(createNewUserLikesEntry(session).bind(like.getUserid(), + UUID.fromString(like.getKey()), + UUID.fromString(like.getFeedid()))); try { - m.execute(); - } catch (ConnectionException e) { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { e.printStackTrace(); return false; - } + } return updateFeedLikesCount(toLike, true); } } @@ -2235,23 +2421,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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); - - - + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch().add(deleteLikeEntry(session).bind(UUID.fromString(likeid))) + .add(deleteUserLikeEntry(session).bind(userid, UUID.fromString(likeid))); try { - m.execute(); - } catch (ConnectionException e) { + session.execute(writeBatch); + closeSession(session); + } catch (Exception e) { + closeSession(session); _log.error("Like Delete FAILED for " + likeid + " from Feed " + feedid); e.printStackTrace(); } _log.trace("Unlike ok for " + likeid + " from Feed " + feedid); } return updateLikeNoResult; + } /** * {@inheritDoc} @@ -2266,53 +2450,55 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getAllLikedPostIdsByUser(String userid) { - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_UserLikedFeeds) - .getKeySlice(userid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - toReturn.add(column.getStringValue()); - } + for (Row row: result){ + toReturn.add(row.getUuid(POST_ID).toString()); } return toReturn; } /** - * {@inheritDoc} + * {@inheritDoc} */ @Override public List getAllLikedFeedsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { - ArrayList toReturn = new ArrayList(); - List likedFeedIDs = getAllLikedFeedIdsByUser(userid); + ArrayList toReturn = new ArrayList<>(); + List likedPostIDs = getAllLikedPostIdsByUser(userid); //check if quantity is greater than user feeds - limit = (limit > likedFeedIDs.size()) ? likedFeedIDs.size() : limit; + limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; - //need them in reverse order - for (int i = likedFeedIDs.size()-1; i >= (likedFeedIDs.size()-limit); i--) { - Feed toAdd = readFeed(likedFeedIDs.get(i)); + //need them in reverse order + for (int i = likedPostIDs.size()-1; i >= (likedPostIDs.size()-limit); i--) { + Feed toAdd = readFeed(likedPostIDs.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)); + _log.trace("Read recent post: " + likedPostIDs.get(i)); } else { - _log.trace("Read and skipped feed: " + likedFeedIDs.get(i) + " (Removed Feed)"); + _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 > likedFeedIDs.size()) ? likedFeedIDs.size() : limit; + limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; } } return toReturn; } /** - * {@inheritDoc} + * {@inheritDoc} */ @Override public List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { @@ -2322,7 +2508,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { //check if quantity is greater than user feeds limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; - //need them in reverse order + //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) { @@ -2345,7 +2531,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { public List getRecentLikedFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { - List toReturn = new ArrayList(); + List toReturn = new ArrayList<>(); Date now = new Date(); if (timeInMillis > now.getTime()) @@ -2355,20 +2541,20 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { throw new IllegalArgumentException("the userId parameter cannot be null/empty"); // get the list of liked feeds - List likedFeedsIdsByUser = getAllLikedFeedIdsByUser(userid); + List likedPostsIdsByUser = getAllLikedFeedIdsByUser(userid); - if(likedFeedsIdsByUser != null && !likedFeedsIdsByUser.isEmpty()){ - for(int i = likedFeedsIdsByUser.size() - 1; i >= 0; i--){ - String feedId = likedFeedsIdsByUser.get(i); + if(likedPostsIdsByUser != null && !likedPostsIdsByUser.isEmpty()){ + for(int i = likedPostsIdsByUser.size() - 1; i >= 0; i--){ + String postid = likedPostsIdsByUser.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 Post + Feed toCheck = readFeed(postid); + boolean isPostOk = (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); + // retrieve the like of the user for the post + if(isPostOk){ + List likes = getAllLikesByFeed(postid); for (Like like : likes) { if(like.getTime().getTime() >= timeInMillis && like.getUserid().equals(userid)) toReturn.add(toCheck); @@ -2376,16 +2562,17 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } }catch(Exception e){ - _log.error("Skipped feed with id " + feedId, 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 + // 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} @@ -2430,7 +2617,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } } - // please check consider that if a user made like recently to an old post, well it could happen that this + // 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()); @@ -2450,43 +2637,30 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getAllLikesByPost(String postid) { + //possible error index + List toReturn = new ArrayList(); - OperationResult> result; - PreparedIndexExpression clause = cf_Likes.newIndexClause().whereColumn("Feedid").equals().value(postid); + ResultSet result = null; + CqlSession session = conn.getKeyspaceSession(); + PreparedStatement stmtFind = session.prepare(QueryBuilder + .selectFrom(LIKES).all() + .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); 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()); - } - } + result = session.execute(stmtFind.bind(UUID.fromString(postid))); + for (Row row: result) { + Like toAdd = readLikeFromRow(row); toReturn.add(toAdd); } - } catch (ConnectionException e) { + closeSession(session); + } catch (Exception e){ e.printStackTrace(); + closeSession(session); } return toReturn; } /* - * + * ********************** HASHTAGS *********************** * */ @@ -2500,17 +2674,18 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineFeed, lowerCaseHashtag).putColumn(feedid, vreid, null); - boolean firstInsert = execute(m); + 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; } /** @@ -2523,17 +2698,19 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineFeed, lowerCaseHashtag).deleteColumn(feedid); - boolean firstDelete = execute(m); + 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; } /** @@ -2546,19 +2723,20 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { noduplicatesHashtags = new HashSet(hashtags); } // Inserting datacommentIdcommentId - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineComment, lowerCaseHashtag).putColumn(commentId, vreid, null); - boolean firstInsert = execute(m); + 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; } /** @@ -2571,22 +2749,24 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { noduplicatesHashtags = new HashSet(hashtags); } // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); for (String hashtag : noduplicatesHashtags) { String lowerCaseHashtag = hashtag.toLowerCase(); - m.withRow(cf_HashtagTimelineComment, lowerCaseHashtag).deleteColumn(commentId); - boolean firstDelete = execute(m); + 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; } /** @@ -2594,25 +2774,32 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public Map getVREHashtagsWithOccurrence(String vreid) { - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_HashtagsCounter) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - int curValue = Integer.parseInt(column.getStringValue()); - if (curValue > 0) - toReturn.put(column.getName(), curValue); - } + // 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; } /** @@ -2620,50 +2807,53 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp){ - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_HashtagsCounter) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { + 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.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); + // 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; } @@ -2673,45 +2863,53 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getVREFeedsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { - List toReturn = new ArrayList(); - OperationResult> resultFeed = null; - OperationResult> resultComment = null; + 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 { - resultFeed = conn.getKeyspace().prepareQuery(cf_HashtagTimelineFeed) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { + 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 = conn.getKeyspace().prepareQuery(cf_HashtagTimelineComment) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { + resultComment = session.execute(stmtFind2.bind(hashtag)); + } catch (Exception e){ e.printStackTrace(); - } - Set feedIds = new HashSet(); + closeSession(session); + } + + Set postIds = 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()); - } + 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.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()); - } + 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.getFeedid()); + } catch (CommentIDNotFoundException e) { + _log.warn("Failed to fetch comment with id " + row.getString(COMMENT_ID)); } } } - toReturn = getFeedsByIds(new ArrayList(feedIds)); + toReturn = getFeedsByIds(new ArrayList<>(postIds)); return toReturn; } /** @@ -2720,48 +2918,56 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @Override public List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { List toReturn = new ArrayList<>(); - OperationResult> resultPost = null; - OperationResult> resultComment = null; + CqlSession session = conn.getKeyspaceSession(); + + ResultSet resultPost = null; + PreparedStatement stmtFind1 = session.prepare(QueryBuilder + .selectFrom(HASHTAGGED_POSTS).all() + .whereColumn(HASHTAG) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); try { - resultPost = conn.getKeyspace().prepareQuery(cf_HashtagTimelineFeed) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { + 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 = conn.getKeyspace().prepareQuery(cf_HashtagTimelineComment) - .getKeySlice(hashtag) - .execute(); - } catch (ConnectionException e) { + 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.getResult()) { - for (Column column : row.getColumns()) { - if (column.getStringValue().compareTo(vreid)==0) - postIds.add(column.getName()); - } + 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.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()); - } + 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.getFeedid()); + } catch (CommentIDNotFoundException e) { + _log.warn("Failed to fetch comment with id " + row.getString(COMMENT_ID)); } } } - toReturn = getPostsByIds(new ArrayList(postIds)); + toReturn = getPostsByIds(new ArrayList<>(postIds)); return toReturn; } /* - * + * ********************** Invites *********************** * */ @@ -2770,21 +2976,24 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @param invite * @return the partial mutation batch instance */ - private MutationBatch initSaveInvite(Invite invite) { + private BatchStatement initSaveInvite(Invite invite, CqlSession session) { + BatchStatement writeBatch = getBatch(); 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; + 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; } /** @@ -2792,20 +3001,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public String isExistingInvite(String vreid, String email) { - OperationResult> result = null; + CqlSession session = conn.getKeyspaceSession(); + + ResultSet result = null; + PreparedStatement stmtFind1 = session.prepare(QueryBuilder + .selectFrom(EMAIL_INVITES).all() + .whereColumn(EMAIL) + .isEqualTo(QueryBuilder.bindMarker()) + .build()); try { - result = conn.getKeyspace().prepareQuery(cf_EmailInvites) - .getKeySlice(email) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind1.bind(email)); + } catch (Exception 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(); - } + 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; } @@ -2825,16 +3040,14 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { 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); + 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; } /** @@ -2842,51 +3055,44 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public Invite readInvite(String inviteid) throws InviteIDNotFoundException, InviteStatusNotFoundException { - Invite toReturn = new Invite(); - OperationResult> result; + 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 = conn.getKeyspace().prepareQuery(cf_Invites) - .getKey(inviteid) - .execute(); - - ColumnList columns = result.getResult(); - if (columns.size() == 0) { + result = session.execute(stmtFind.bind(UUID.fromString(inviteid))); + if (result.one() == null) { 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) { + toReturn = readAInviteFromRow(result.one()); + closeSession(session); + } catch (Exception e){ e.printStackTrace(); - return null; - } + 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 - * @throws InviteIDNotFoundException - * @throws InviteStatusNotFoundException + * @throws InviteIDNotFoundException + * @throws InviteStatusNotFoundException */ private List getInvitesById(List inviteIds) throws InviteIDNotFoundException, InviteStatusNotFoundException { ArrayList toReturn = new ArrayList(); - for (String inviteid : inviteIds) + for (String inviteid : inviteIds) toReturn.add(readInvite(inviteid)); return toReturn; } /** * {@inheritDoc} - * @throws InviteStatusNotFoundException + * @throws InviteStatusNotFoundException */ @Override public boolean setInviteStatus(String vreid, String email, InviteStatus status) throws InviteIDNotFoundException, InviteStatusNotFoundException { @@ -2895,15 +3101,18 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { if (toSet == null) throw new InviteIDNotFoundException("The specified invite to set with id: " + inviteid + " does not exist"); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); + BatchStatement writeBatch = getBatch(); //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); + writeBatch.add(updateInviteEntry(session, STATUS).bind(status.toString(), UUID.fromString(inviteid))) + .add(updateVreInviteEntry(session, STATUS).bind(status.toString(), vreid, UUID.fromString(inviteid))); try { - m.execute(); - } catch (ConnectionException e) { + 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"); @@ -2914,29 +3123,32 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getInvitedEmailsByVRE(String vreid, InviteStatus... status) throws InviteIDNotFoundException, InviteStatusNotFoundException{ - OperationResult> result = null; + 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 = conn.getKeyspace().prepareQuery(cf_VREInvites) - .getKeySlice(vreid) - .execute(); - } catch (ConnectionException e) { + result = session.execute(stmtFind.bind(vreid)); + closeSession(session); + } catch (Exception 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()); - } + 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 { - for (Column column : row.getColumns()) - invitesIds.add(column.getName()); + invitesIds.add(row.getUuid(INVITE_ID).toString()); } } return getInvitesById(invitesIds); @@ -2946,51 +3158,35 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ @Override public List getAttachmentsByFeedId(String feedId) throws FeedIDNotFoundException { - Feed toCheck = null; + //index error + Post toCheck = null; try { - toCheck = readFeed(feedId); + toCheck = readPost(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; + CqlSession session = conn.getKeyspaceSession(); + PreparedStatement stmtFind = session.prepare(QueryBuilder + .selectFrom(ATTACHMENTS).all() + .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker()) + .build()); + ResultSet result = null; 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()); - } - } + 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 = readAttachmentFromRow(row); toReturn.add(toAdd); } + closeSession(session); } catch (Exception e) { e.printStackTrace(); + closeSession(session); return null; } return toReturn; @@ -3014,18 +3210,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ private boolean saveAttachmentEntry(String feedId, Attachment toSave) { // Inserting data - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + CqlSession session = conn.getKeyspaceSession(); //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) { + 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; } @@ -3035,7 +3234,6 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { /** * simply return an enum representing the privacy level - * @param privacyLevel . * @return correct enum representing the privacy level * @throws NotificationChannelTypeNotFoundException * @throws FeedTypeNotFoundException @@ -3057,7 +3255,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @return correct enum representing the privacy level * @throws FeedTypeNotFoundException */ - private PrivacyLevel getPrivacyLevel(String privacyLevel) throws PrivacyLevelTypeNotFoundException { + private static PrivacyLevel getPrivacyLevel(String privacyLevel) throws PrivacyLevelTypeNotFoundException { if (privacyLevel.compareTo("CONNECTION") == 0) return PrivacyLevel.CONNECTION; else if (privacyLevel.compareTo("PRIVATE") == 0) @@ -3077,9 +3275,9 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * simply return an enum representing the feed type * @param type . * @return correct enum representing the feed type - * @throws TypeNotFoundException . + * @throws FeedTypeNotFoundException . */ - private FeedType getFeedType(String type) throws FeedTypeNotFoundException { + private static FeedType getFeedType(String type) throws FeedTypeNotFoundException { if (type.compareTo("TWEET") == 0) { return FeedType.TWEET; } @@ -3105,9 +3303,9 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * simply return an enum representing the feed type * @param type . * @return correct enum representing the feed type - * @throws TypeNotFoundException . + * @throws FeedTypeNotFoundException . */ - private PostType getPostType(String type) throws FeedTypeNotFoundException { + private static PostType getPostType(String type) throws FeedTypeNotFoundException { if (type.compareTo("TWEET") == 0) { return PostType.TWEET; } @@ -3134,9 +3332,9 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * simply return an enum representing the invite status type * @param type . * @return correct enum representing the feed type - * @throws TypeNotFoundException . + * @throws InviteStatusNotFoundException . */ - private InviteStatus getInviteStatusType(String type) throws InviteStatusNotFoundException { + private static InviteStatus getInviteStatusType(String type) throws InviteStatusNotFoundException { switch (type) { case "PENDING": return InviteStatus.PENDING; @@ -3156,9 +3354,9 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * simply return an enum representing the feed type * @param type . * @return correct enum representing the feed type - * @throws TypeNotFoundException . + * @throws NotificationTypeNotFoundException . */ - private NotificationType getNotificationType(String type) throws NotificationTypeNotFoundException { + private static NotificationType getNotificationType(String type) throws NotificationTypeNotFoundException { if (type.compareTo("WP_FOLDER_SHARE") == 0) { return NotificationType.WP_FOLDER_SHARE; } @@ -3308,20 +3506,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ private boolean updateFeedCommentsCount(Feed toUpdate, boolean increment) { int newCount = 0; - try { + 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(); + CqlSession session = conn.getKeyspaceSession(); //an entry in the feed CF - m.withRow(cf_Feeds, toUpdate.getKey().toString()).putColumn("CommentsNo", ""+newCount, null); try { - m.execute(); - } catch (ConnectionException e) { + 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); @@ -3336,20 +3535,21 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ private boolean updateFeedLikesCount(Feed toUpdate, boolean increment) { int newCount = 0; - try { + 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(); + CqlSession session = conn.getKeyspaceSession(); //an entry in the feed CF - m.withRow(cf_Feeds, toUpdate.getKey().toString()).putColumn("LikesNo", ""+newCount, null); try { - m.execute(); - } catch (ConnectionException e) { + 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); @@ -3357,7 +3557,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } /** - * update the hashtag count by incrementing or decrementing it by (1) + * 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 @@ -3365,14 +3565,14 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ private boolean updateVREHashtagCount(String vreid, String hashtag, boolean increment) { Map vreHashtags = getVREHashtagsWithOccurrence(vreid); - //if the hashtag not yet exist + //if the hashtag not yet exist int newCount = 0; if (!vreHashtags.containsKey(hashtag)) { newCount = 1; } else { - try { + try { int current = vreHashtags.get(hashtag); newCount = increment ? current+1 : current-1; } @@ -3381,12 +3581,28 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } } _log.debug("Updating counter for " + hashtag + " to " + newCount); - MutationBatch m = conn.getKeyspace().prepareMutationBatch(); - m.withRow(cf_HashtagsCounter, vreid).putColumn(hashtag, ""+newCount, null); + 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 { - m.execute(); - } catch (ConnectionException e) { + 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); @@ -3411,18 +3627,25 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { @Override - public List getAllVREIds() throws ConnectionException{ + public List getAllVREIds(){ List ids = new ArrayList<>(); - OperationResult> rows = conn.getKeyspace().prepareQuery(cf_VRETline).getAllRows() - .withColumnRange(new RangeBuilder().setLimit(0).build()) - .execute(); + 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); + } - Rows res = rows.getResult(); - - for (Row row : res) { - ids.add(row.getKey()); + for (Row row : result.all()) { + ids.add(row.getString(VRE_ID)); } _log.debug("VRE ids are " + ids); 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..303357a 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 - * - * @version 0.1 Dec 2012 + * @author Ahmed Salah Tawfik Ibrahim ISTI-CNR + * + * @version 2.0.0 October 2023 * */ @SuppressWarnings("serial") @@ -36,9 +42,9 @@ public class RunningCluster implements Serializable { /** * properties to read */ - private static final String HOST_PROPERTY = "host"; + 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 @@ -71,13 +77,13 @@ public class RunningCluster implements Serializable { singleton = new RunningCluster(infrastructureName); } return singleton; - } + } /** * 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,10 +103,15 @@ 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 * @throws Exception */ @@ -122,16 +133,17 @@ public class RunningCluster implements Serializable { List toReturn = client.submit(query); ScopeProvider.instance.set(currScope); return toReturn; - } + } private String readInfrastructureName() { + Properties props = new Properties(); try { StringBuilder sb = new StringBuilder(getCatalinaHome()); sb.append(File.separator) - .append(PortalContext.CONFIGURATION_FOLDER) - .append(File.separator) - .append(PortalContext.INFRA_PROPERTY_FILENAME); + .append(PortalContext.CONFIGURATION_FOLDER) + .append(File.separator) + .append(PortalContext.INFRA_PROPERTY_FILENAME); String propertyfile = sb.toString(); File propsFile = new File(propertyfile); FileInputStream fis = new FileInputStream(propsFile); @@ -141,19 +153,19 @@ public class RunningCluster implements Serializable { catch(IOException e) { _log.error("infrastructure.properties file not found under $CATALINA_HOME/conf/ dir, setting default infrastructure Name " + "gcube"); return "gcube"; - } + } } /** - * + * */ private void loadDefaultConfiguration() { Properties props = new Properties(); 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,32 +181,43 @@ 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 + "]"; } /** - * + * * @return $CATALINA_HOME */ 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; + } +} \ No newline at end of file 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..522093e --- /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 + +} \ No newline at end of file