From aeb8f61104bc6eeaf4ae721050513ee3060fae66 Mon Sep 17 00:00:00 2001 From: Andre Askari Date: Wed, 16 Aug 2017 10:21:29 -0700 Subject: [PATCH 1/5] Created cassandra connector --- build.sbt | 19 +- modules/cassandra/app/Module.java | 12 + .../cassandra/controllers/EdgeController.java | 121 ++++++++ .../controllers/GraphController.java | 130 +++++++++ .../cassandra/controllers/HomeController.java | 17 ++ .../controllers/LineageEdgeController.java | 118 ++++++++ .../controllers/LineageGraphController.java | 119 ++++++++ .../cassandra/controllers/NodeController.java | 119 ++++++++ .../controllers/StructureController.java | 130 +++++++++ .../ground/cassandra/dao/CqlConstants.java | 89 ++++++ .../ground/cassandra/dao/CqlConstants2.java | 89 ++++++ .../cassandra/dao/core/CassandraEdgeDao.java | 92 +++++++ .../dao/core/CassandraEdgeVersionDao.java | 136 +++++++++ .../cassandra/dao/core/CassandraGraphDao.java | 73 +++++ .../dao/core/CassandraGraphVersionDao.java | 87 ++++++ .../cassandra/dao/core/CassandraNodeDao.java | 66 +++++ .../dao/core/CassandraNodeVersionDao.java | 73 +++++ .../dao/core/CassandraRichVersionDao.java | 240 ++++++++++++++++ .../dao/core/CassandraStructureDao.java | 77 ++++++ .../core/CassandraStructureVersionDao.java | 107 ++++++++ .../dao/usage/CassandraLineageEdgeDao.java | 75 +++++ .../usage/CassandraLineageEdgeVersionDao.java | 87 ++++++ .../dao/usage/CassandraLineageGraphDao.java | 73 +++++ .../CassandraLineageGraphVersionDao.java | 102 +++++++ .../dao/version/CassandraItemDao.java | 169 ++++++++++++ .../dao/version/CassandraTagDao.java | 213 ++++++++++++++ .../dao/version/CassandraVersionDao.java | 48 ++++ .../CassandraVersionHistoryDagDao.java | 196 +++++++++++++ .../version/CassandraVersionSuccessorDao.java | 168 ++++++++++++ .../cassandra/filters/GroundFilter.java | 37 +++ .../cassandra/start/ApplicationStart.java | 38 +++ .../cassandra/util/CassandraDatabase.java | 126 +++++++++ .../cassandra/util/CassandraStatements.java | 46 ++++ .../ground/cassandra/util/CassandraUtils.java | 160 +++++++++++ .../ground/cassandra/util/GroundUtils.java | 112 ++++++++ modules/cassandra/app/views/index.scala.html | 3 + modules/cassandra/app/views/main.scala.html | 16 ++ modules/cassandra/conf/application.conf | 45 +++ modules/cassandra/conf/logback.xml | 41 +++ modules/cassandra/conf/routes | 45 +++ modules/cassandra/conf/swagger.yml | 10 + modules/cassandra/project/build.properties | 4 + modules/cassandra/project/plugins.sbt | 6 + modules/cassandra/public/images/favicon.png | Bin 0 -> 8328 bytes modules/cassandra/public/javascripts/hello.js | 3 + modules/cassandra/public/stylesheets/main.css | 0 .../ground/cassandra/dao/CassandraTest.java | 143 ++++++++++ .../ground/cassandra/dao/DaoTest.java | 259 ++++++++++++++++++ .../dao/core/CassandraEdgeDaoTest.java | 131 +++++++++ .../dao/core/CassandraEdgeVersionDaoTest.java | 166 +++++++++++ .../dao/core/CassandraGraphDaoTest.java | 103 +++++++ .../core/CassandraGraphVersionDaoTest.java | 118 ++++++++ .../dao/core/CassandraNodeDaoTest.java | 160 +++++++++++ .../dao/core/CassandraNodeVersionDaoTest.java | 94 +++++++ .../dao/core/CassandraRichVersionDaoTest.java | 128 +++++++++ .../dao/core/CassandraStructureDaoTest.java | 118 ++++++++ .../CassandraStructureVersionDaoTest.java | 74 +++++ .../dao/core/CassandraTagDaoTest.java | 69 +++++ .../usage/CassandraLineageEdgeDaoTest.java | 99 +++++++ .../CassandraLineageEdgeVersionDaoTest.java | 88 ++++++ .../usage/CassandraLineageGraphDaoTest.java | 104 +++++++ .../CassandraLineageGraphVersionDaoTest.java | 116 ++++++++ .../dao/version/CassandraItemDaoTest.java | 258 +++++++++++++++++ .../CassandraVersionHistoryDagDaoTest.java | 39 +++ .../CassandraVersionSuccessorDaoTest.java | 89 ++++++ .../version/mock/TestCassandraItemDao.java | 40 +++ .../mock/TestCassandraRichVersionDao.java | 29 ++ .../version/mock/TestCassandraVersionDao.java | 23 ++ resources/scripts/cassandra/cassandra.cql | 8 +- 69 files changed, 6187 insertions(+), 6 deletions(-) create mode 100644 modules/cassandra/app/Module.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/HomeController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/filters/GroundFilter.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/start/ApplicationStart.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraDatabase.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java create mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java create mode 100644 modules/cassandra/app/views/index.scala.html create mode 100644 modules/cassandra/app/views/main.scala.html create mode 100644 modules/cassandra/conf/application.conf create mode 100644 modules/cassandra/conf/logback.xml create mode 100644 modules/cassandra/conf/routes create mode 100644 modules/cassandra/conf/swagger.yml create mode 100644 modules/cassandra/project/build.properties create mode 100644 modules/cassandra/project/plugins.sbt create mode 100644 modules/cassandra/public/images/favicon.png create mode 100644 modules/cassandra/public/javascripts/hello.js create mode 100644 modules/cassandra/public/stylesheets/main.css create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/CassandraTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraTagDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraItemDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraItemDao.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraRichVersionDao.java create mode 100644 modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraVersionDao.java diff --git a/build.sbt b/build.sbt index 1cfc7122..0f15a93c 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import de.johoop.jacoco4sbt.XMLReport -name := """ground""" +name := """ground""" lazy val commonSettings = Seq( organization := "edu.berkeley.ground", @@ -14,7 +14,7 @@ lazy val root = (project in file(".")).enablePlugins(PlayJava) commonSettings, name := "ground" ) - .aggregate(common, postgres) + .aggregate(common, postgres, cassandra) lazy val common = (project in file("modules/common")) @@ -45,6 +45,21 @@ lazy val postgres = (project in file("modules/postgres")) ).dependsOn(common) +lazy val cassandra = (project in file("modules/cassandra")) + .enablePlugins(PlayJava, JavaAppPackaging) + .settings( + commonSettings, + name := "ground-cassandra", + libraryDependencies += javaJdbc, + libraryDependencies += cache, + libraryDependencies += "com.datastax.cassandra" % "cassandra-driver-core" % "3.0.0", + libraryDependencies += "commons-beanutils" % "commons-beanutils-core" % "1.8.3", + jacoco.settings, + parallelExecution in jacoco.Config := false, + Keys.fork in jacoco.Config := true, + jacoco.reportFormats in jacoco.Config := Seq(XMLReport(encoding = "utf-8")) + ).dependsOn(common) + jacoco.settings parallelExecution in jacoco.Config := false diff --git a/modules/cassandra/app/Module.java b/modules/cassandra/app/Module.java new file mode 100644 index 00000000..1b26cfa9 --- /dev/null +++ b/modules/cassandra/app/Module.java @@ -0,0 +1,12 @@ +import com.google.inject.AbstractModule; +import edu.berkeley.ground.cassandra.start.ApplicationStart; +import java.time.Clock; + +public class Module extends AbstractModule { + + @Override + public void configure() { + bind(Clock.class).toInstance(Clock.systemDefaultZone()); + bind(ApplicationStart.class).asEagerSingleton(); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java new file mode 100644 index 00000000..d3dc3e29 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java @@ -0,0 +1,121 @@ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.model.core.EdgeVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraEdgeDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraEdgeVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class EdgeController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraEdgeDao cassandraEdgeDao; + private CassandraEdgeVersionDao cassandraEdgeVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraEdgeDao = new CassandraEdgeDao(dbSource, idGenerator); + this.cassandraEdgeVersionDao = new CassandraEdgeVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getEdge(final String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "edges", + () -> Json.toJson(this.cassandraEdgeDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addEdge() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + Edge edge = Json.fromJson(json, Edge.class); + + try { + edge = this.cassandraEdgeDao.create(edge); + } catch (GroundException e) { + throw new CompletionException(e); + } + + return Json.toJson(edge); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getEdgeVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "edge_versions", + () -> Json.toJson(this.cassandraEdgeVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addEdgeVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + + ((ObjectNode) json).remove("parentIds"); + EdgeVersion edgeVersion = Json.fromJson(json, EdgeVersion.class); + + try { + edgeVersion = this.cassandraEdgeVersionDao.create(edgeVersion, parentIds); + } catch (GroundException e) { + throw new CompletionException(e); + } + + return Json.toJson(edgeVersion); + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java new file mode 100644 index 00000000..88544e2e --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java @@ -0,0 +1,130 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Graph; +import edu.berkeley.ground.common.model.core.GraphVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraGraphDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraGraphVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class GraphController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraGraphDao cassandraGraphDao; + private CassandraGraphVersionDao cassandraGraphVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraGraphDao = new CassandraGraphDao(dbSource, idGenerator); + + this.cassandraGraphVersionDao = new CassandraGraphVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getGraph(String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "graphs", + () -> Json.toJson(this.cassandraGraphDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getGraphVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse("graph_versions", + () -> Json.toJson(this.cassandraGraphVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addGraph() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + Graph graph = Json.fromJson(json, Graph.class); + + try { + graph = this.cassandraGraphDao.create(graph); + } catch (GroundException e) { + throw new CompletionException(e); + } + + return Json.toJson(graph); + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addGraphVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + ((ObjectNode) json).remove("parentIds"); + GraphVersion graphVersion = Json.fromJson(json, GraphVersion.class); + + try { + graphVersion = this.cassandraGraphVersionDao.create(graphVersion, parentIds); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(graphVersion); + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/HomeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/HomeController.java new file mode 100644 index 00000000..17863b02 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/HomeController.java @@ -0,0 +1,17 @@ +package edu.berkeley.ground.cassandra.controllers; + +import play.mvc.*; +import views.html.*; + +/** This controller contains an action to handle HTTP requests to the application's home page. */ +public class HomeController extends Controller { + + /** + * An action that renders an HTML page with a welcome message. The configuration in the + * routes file means that this method will be called when the application receives a + * GET request with a path of /. + */ + public Result index() { + return ok(index.render("Your new application is ready.")); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java new file mode 100644 index 00000000..e0244b69 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java @@ -0,0 +1,118 @@ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageEdge; +import edu.berkeley.ground.common.model.usage.LineageEdgeVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageEdgeDao; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageEdgeVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class LineageEdgeController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraLineageEdgeDao cassandraLineageEdgeDao; + private CassandraLineageEdgeVersionDao cassandraLineageEdgeVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraLineageEdgeDao = new CassandraLineageEdgeDao(dbSource, idGenerator); + this.cassandraLineageEdgeVersionDao = new CassandraLineageEdgeVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getLineageEdge(String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "lineage_edges", + () -> Json.toJson(this.cassandraLineageEdgeDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getLineageEdgeVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "lineage_edge_versions", + () -> Json.toJson(this.cassandraLineageEdgeVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage createLineageEdge() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + LineageEdge lineageEdge = Json.fromJson(json, LineageEdge.class); + try { + lineageEdge = this.cassandraLineageEdgeDao.create(lineageEdge); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(lineageEdge); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage createLineageEdgeVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + ((ObjectNode) json).remove("parentIds"); + + LineageEdgeVersion lineageEdgeVersion = Json.fromJson(json, LineageEdgeVersion.class); + + try { + lineageEdgeVersion = this.cassandraLineageEdgeVersionDao.create(lineageEdgeVersion, parentIds); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(lineageEdgeVersion); + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java new file mode 100644 index 00000000..d61dbc15 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java @@ -0,0 +1,119 @@ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageGraph; +import edu.berkeley.ground.common.model.usage.LineageGraphVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageGraphDao; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageGraphVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class LineageGraphController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraLineageGraphDao cassandraLineageGraphDao; + private CassandraLineageGraphVersionDao cassandraLineageGraphVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, + final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraLineageGraphDao = new CassandraLineageGraphDao(dbSource, idGenerator); + this.cassandraLineageGraphVersionDao = new CassandraLineageGraphVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getLineageGraph(String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "lineage_graphs", + () -> Json.toJson(this.cassandraLineageGraphDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getLineageGraphVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "lineage_graph_versions", + () -> Json.toJson(this.cassandraLineageGraphVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage createLineageGraph() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + LineageGraph lineageGraph = Json.fromJson(json, LineageGraph.class); + try { + lineageGraph = this.cassandraLineageGraphDao.create(lineageGraph); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(lineageGraph); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage createLineageGraphVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + ((ObjectNode) json).remove("parentIds"); + + LineageGraphVersion lineageGraphVersion = Json.fromJson(json, LineageGraphVersion.class); + + try { + lineageGraphVersion = this.cassandraLineageGraphVersionDao.create(lineageGraphVersion, parentIds); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(lineageGraphVersion); + }, + CassandraUtils.getDbSourceHttpContext(actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java new file mode 100644 index 00000000..58a50600 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java @@ -0,0 +1,119 @@ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.model.core.NodeVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraNodeDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraNodeVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class NodeController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraNodeDao cassandraNodeDao; + private CassandraNodeVersionDao cassandraNodeVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraNodeDao = new CassandraNodeDao(dbSource, idGenerator); + this.cassandraNodeVersionDao = new CassandraNodeVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getNode(String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "nodes", + () -> Json.toJson(this.cassandraNodeDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addNode() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + Node node = Json.fromJson(json, Node.class); + try { + node = this.cassandraNodeDao.create(node); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(node); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getNodeVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "node_versions", + () -> Json.toJson(this.cassandraNodeVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addNodeVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + ((ObjectNode) json).remove("parentIds"); + NodeVersion nodeVersion = Json.fromJson(json, NodeVersion.class); + + try { + nodeVersion = this.cassandraNodeVersionDao.create(nodeVersion, parentIds); + } catch (GroundException e) { + e.printStackTrace(); + throw new CompletionException(e); + } + return Json.toJson(nodeVersion); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java new file mode 100644 index 00000000..fecfb3ef --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java @@ -0,0 +1,130 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.controllers; + +import akka.actor.ActorSystem; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Structure; +import edu.berkeley.ground.common.model.core.StructureVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraStructureDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraStructureVersionDao; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import javax.inject.Inject; +import play.cache.CacheApi; +// import play.db.Database; +import play.libs.Json; +import play.mvc.BodyParser; +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Results; + +public class StructureController extends Controller { + + private CacheApi cache; + private ActorSystem actorSystem; + + private CassandraStructureDao cassandraStructureDao; + private CassandraStructureVersionDao cassandraStructureVersionDao; + + @Inject + final void injectUtils(final CacheApi cache, final CassandraDatabase dbSource, final ActorSystem actorSystem, final IdGenerator idGenerator) { + this.actorSystem = actorSystem; + this.cache = cache; + + this.cassandraStructureDao = new CassandraStructureDao(dbSource, idGenerator); + this.cassandraStructureVersionDao = new CassandraStructureVersionDao(dbSource, idGenerator); + } + + public final CompletionStage getStructure(String sourceKey) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "structures", + () -> Json.toJson(this.cassandraStructureDao.retrieveFromDatabase(sourceKey)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + public final CompletionStage getStructureVersion(Long id) { + return CompletableFuture.supplyAsync( + () -> { + try { + return this.cache.getOrElse( + "structure_versions", + () -> Json.toJson(this.cassandraStructureVersionDao.retrieveFromDatabase(id)), + Integer.parseInt(System.getProperty("ground.cache.expire.secs"))); + } catch (Exception e) { + throw new CompletionException(e); + } + }, CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::ok) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addStructure() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + Structure structure = Json.fromJson(json, Structure.class); + + try { + structure = this.cassandraStructureDao.create(structure); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(structure); + }, + + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } + + @BodyParser.Of(BodyParser.Json.class) + public final CompletionStage addStructureVersion() { + return CompletableFuture.supplyAsync( + () -> { + JsonNode json = request().body().asJson(); + + List parentIds = GroundUtils.getListFromJson(json, "parentIds"); + ((ObjectNode) json).remove("parentIds"); + + StructureVersion structureVersion = Json.fromJson(json, StructureVersion.class); + + try { + structureVersion = this.cassandraStructureVersionDao.create(structureVersion, parentIds); + } catch (GroundException e) { + throw new CompletionException(e); + } + return Json.toJson(structureVersion); + }, + CassandraUtils.getDbSourceHttpContext(this.actorSystem)) + .thenApply(Results::created) + .exceptionally(e -> GroundUtils.handleException(e, request())); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java new file mode 100644 index 00000000..c17a1f3c --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java @@ -0,0 +1,89 @@ +package edu.berkeley.ground.cassandra.dao; + +public class CqlConstants { + + /* General insert statements */ + public static final String INSERT_GENERIC_ITEM_WITH_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', \'%s\');"; + public static final String INSERT_GENERIC_ITEM_WITHOUT_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', null);"; + + /* General select statements */ + public static final String SELECT_STAR_BY_SOURCE_KEY = "SELECT * FROM %s WHERE source_key = \'%s\' ALLOW FILTERING;"; + public static final String SELECT_STAR_ITEM_BY_ID = "SELECT * FROM %s WHERE item_id = %d ALLOW FILTERING;"; + public static final String SELECT_STAR_BY_ID = "SELECT * FROM %s WHERE id = %d ALLOW FILTERING;"; + public static final String DELETE_BY_ID = "DELETE FROM %s WHERE id = %d;"; + + /* Version-specific statements */ + public static final String INSERT_VERSION = "INSERT INTO version (id) VALUES (%d);"; + + /* Version Successor-specific statements */ + public static final String INSERT_VERSION_SUCCESSOR = "INSERT INTO version_successor (id, from_version_id, to_version_id) VALUES (%d, %d, %d);"; + public static final String SELECT_VERSION_SUCCESSOR = "SELECT * FROM version_successor where id = %d ALLOW FILTERING;"; + public static final String SELECT_VERSION_SUCCESSOR_BY_ENDPOINT = "SELECT * FROM version_successor WHERE to_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_VERSION_SUCCESSOR = "DELETE FROM version_successor WHERE id = %d;"; + + /* Version History DAG-specific statements */ + public static final String INSERT_VERSION_HISTORY_DAG_EDGE = "INSERT INTO version_history_dag (item_id, version_successor_id) VALUES (%d, %d);"; + public static final String SELECT_VERSION_HISTORY_DAG = "SELECT * FROM version_history_dag WHERE item_id = %d ALLOW FILTERING;"; + public static final String DELETE_SUCCESSOR_FROM_DAG = "DELETE FROM version_history_dag WHERE item_id = %d AND version_successor_id = %d;"; + + /* Item-specific statements */ + public static final String INSERT_ITEM = "INSERT INTO item (id) VALUES (%d);"; + public static final String INSERT_ITEM_TAG_WITH_VALUE = + "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, " + "\'%s\', \'%s\', \'%s\');"; + public static final String INSERT_ITEM_TAG_NO_VALUE = "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, \'%s\', null, null);"; + public static final String SELECT_ITEM_TAGS = "SELECT * FROM item_tag WHERE item_id = %d ALLOW FILTERING;"; + public static final String SELECT_ITEM_TAGS_BY_KEY = "SELECT * FROM item_tag WHERE key = \'%s\' ALLOW FILTERING;"; + + /* Edge-specific statements */ + public static final String INSERT_EDGE_WITH_NAME = + "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, \'%s\');"; + public static final String INSERT_EDGE_WITHOUT_NAME = + "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, null);"; + public static final String INSERT_EDGE_VERSION = "INSERT INTO edge_version (id, edge_id, from_node_version_start_id, from_node_version_end_id, " + + "to_node_version_start_id, to_node_version_end_id) VALUES (%d, %d, %d, %d, %d, %d);"; + public static final String UPDATE_EDGE_VERSION = "UPDATE edge_version SET from_node_version_end_id = %d, to_node_version_end_id = %d WHERE id = " + + "%d;"; + + /* Graph-specific statements */ + public static final String INSERT_GRAPH_VERSION = "INSERT INTO graph_version (id, graph_id) VALUES (%d, %d);"; + public static final String INSERT_GRAPH_VERSION_EDGE = "INSERT INTO graph_version_edge (graph_version_id, edge_version_id) VALUES (%d, %d);"; + public static final String SELECT_GRAPH_VERSION_EDGES = "SELECT * FROM graph_version_edge WHERE graph_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_ALL_GRAPH_VERSION_EDGES = "DELETE FROM %s WHERE %s_version_id = %d;"; + + /* Node-specific statements */ + public static final String INSERT_NODE_VERSION = "INSERT INTO node_version (id, node_id) VALUES (%d, %d);"; + + /* Rich Version-specific statements */ + public static final String INSERT_RICH_VERSION_WITH_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " + + "\'%s\');"; + public static final String INSERT_RICH_VERSION_WITHOUT_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " + + "null);"; + public static final String INSERT_RICH_VERSION_TAG_WITH_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " + + "\'%s\', \'%s\', \'%s\');"; + public static final String INSERT_RICH_VERSION_TAG_NO_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " + + "\'%s\', null, null);"; + public static final String INSERT_RICH_VERSION_EXTERNAL_PARAMETER = "INSERT INTO rich_version_external_parameter (rich_version_id, key, value) " + + "VALUES (%d, \'%s\', \'%s\');"; + public static final String SELECT_RICH_VERSION_EXTERNAL_PARAMETERS = "SELECT * FROM rich_version_external_parameter WHERE rich_version_id = %d ALLOW FILTERING;"; + public static final String SELECT_RICH_VERSION_TAGS = "SELECT * FROM rich_version_tag WHERE rich_version_id = %d ALLOW FILTERING;"; + public static final String SELECT_RICH_VERSION_TAGS_BY_KEY = "SELECT * FROM rich_version_tag WHERE key = \'%s\' ALLOW FILTERING;"; + public static final String DELETE_RICH_VERSION_TAGS = "DELETE FROM rich_version_tag WHERE rich_version_id = %d;"; + public static final String DELETE_RICH_EXTERNAL_PARAMETERS = "DELETE FROM rich_version_external_parameter WHERE rich_version_id = %d"; + + /* Structure-specific statements */ + public static final String INSERT_STRUCTURE_VERSION = "INSERT INTO structure_version (id, structure_id) VALUES (%d, %d);"; + public static final String INSERT_STRUCTURE_VERSION_ATTRIBUTE = "INSERT INTO structure_version_attribute (structure_version_id, key, type) " + + "VALUES (%d, \'%s\', \'%s\');"; + public static final String SELECT_STRUCTURE_VERSION_ATTRIBUTES = "SELECT * FROM structure_version_attribute WHERE structure_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_STRUCTURE_VERSION_ATTRIBUTES = "DELETE FROM structure_version_attribute WHERE structure_version_id = %d"; + + /* Lineage Edge-specific statements */ + public static final String INSERT_LINEAGE_EDGE_VERSION = "INSERT INTO lineage_edge_version (id, lineage_edge_id, from_rich_version_id, " + + "to_rich_version_id, principal_id) VALUES (%d, %d, %d, %d, %d);"; + + /* Lineage Graph-specific statements */ + public static final String INSERT_LINEAGE_GRAPH_VERSION = "INSERT INTO lineage_graph_version (id, lineage_graph_id) VALUES (%d, %d);"; + public static final String INSERT_LINEAGE_GRAPH_VERSION_EDGE = "INSERT INTO lineage_graph_version_edge (lineage_graph_version_id, " + + "lineage_edge_version_id) VALUES (%d, %d);"; + public static final String SELECT_LINEAGE_GRAPH_VERSION_EDGES = "SELECT * FROM lineage_graph_version_edge WHERE lineage_graph_version_id = %d ALLOW FILTERING;"; +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java new file mode 100644 index 00000000..d9e74bba --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java @@ -0,0 +1,89 @@ +package edu.berkeley.ground.cassandra.dao; + +public class CqlConstants2 { + + /* General insert statements */ + public static final String INSERT_GENERIC_ITEM_WITH_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; + public static final String INSERT_GENERIC_ITEM_WITHOUT_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', null) ALLOW FILTERING;"; + + /* General select statements */ + public static final String SELECT_STAR_BY_SOURCE_KEY = "SELECT * FROM %s WHERE source_key = \'%s\' ALLOW FILTERING;"; + public static final String SELECT_STAR_ITEM_BY_ID = "SELECT * FROM %s WHERE item_id = %d ALLOW FILTERING;"; + public static final String SELECT_STAR_BY_ID = "SELECT * FROM %s WHERE id = %d ALLOW FILTERING;"; + public static final String DELETE_BY_ID = "DELETE FROM %s WHERE id = %d ALLOW FILTERING;"; + + /* Version-specific statements */ + public static final String INSERT_VERSION = "INSERT INTO version (id) VALUES (%d) ALLOW FILTERING;"; + + /* Version Successor-specific statements */ + public static final String INSERT_VERSION_SUCCESSOR = "INSERT INTO version_successor (id, from_version_id, to_version_id) VALUES (%d, %d, %d) ALLOW FILTERING;"; + public static final String SELECT_VERSION_SUCCESSOR = "SELECT * FROM version_successor where id = %d ALLOW FILTERING;"; + public static final String SELECT_VERSION_SUCCESSOR_BY_ENDPOINT = "SELECT * FROM version_successor WHERE to_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_VERSION_SUCCESSOR = "DELETE FROM version_successor WHERE id = %d ALLOW FILTERING;"; + + /* Version History DAG-specific statements */ + public static final String INSERT_VERSION_HISTORY_DAG_EDGE = "INSERT INTO version_history_dag (item_id, version_successor_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String SELECT_VERSION_HISTORY_DAG = "SELECT * FROM version_history_dag WHERE item_id = %d ALLOW FILTERING;"; + public static final String DELETE_SUCCESSOR_FROM_DAG = "DELETE FROM version_history_dag WHERE version_successor_id = %d ALLOW FILTERING;"; + + /* Item-specific statements */ + public static final String INSERT_ITEM = "INSERT INTO ITEM (id) VALUES (%d) ALLOW FILTERING;"; + public static final String INSERT_ITEM_TAG_WITH_VALUE = + "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, " + "\'%s\', \'%s\', \'%s\') ALLOW FILTERING;"; + public static final String INSERT_ITEM_TAG_NO_VALUE = "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, \'%s\', null, null) ALLOW FILTERING;"; + public static final String SELECT_ITEM_TAGS = "SELECT * FROM item_tag WHERE item_id = %d ALLOW FILTERING;"; + public static final String SELECT_ITEM_TAGS_BY_KEY = "SELECT * FROM item_tag WHERE key = \'%s\' ALLOW FILTERING;"; + + /* Edge-specific statements */ + public static final String INSERT_EDGE_WITH_NAME = + "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, \'%s\') ALLOW FILTERING;"; + public static final String INSERT_EDGE_WITHOUT_NAME = + "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, null) ALLOW FILTERING;"; + public static final String INSERT_EDGE_VERSION = "INSERT INTO edge_version (id, edge_id, from_node_version_start_id, from_node_version_end_id, " + + "to_node_version_start_id, to_node_version_end_id) VALUES (%d, %d, %d, %d, %d, %d) ALLOW FILTERING;"; + public static final String UPDATE_EDGE_VERSION = "UPDATE edge_version SET from_node_version_end_id = %d, to_node_version_end_id = %d WHERE id = " + + "%d ALLOW FILTERING;"; + + /* Graph-specific statements */ + public static final String INSERT_GRAPH_VERSION = "INSERT INTO graph_version (id, graph_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String INSERT_GRAPH_VERSION_EDGE = "INSERT INTO graph_version_edge (graph_version_id, edge_version_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String SELECT_GRAPH_VERSION_EDGES = "SELECT * FROM graph_version_edge WHERE graph_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_ALL_GRAPH_VERSION_EDGES = "DELETE FROM %s WHERE %s_version_id = %d ALLOW FILTERING;"; + + /* Node-specific statements */ + public static final String INSERT_NODE_VERSION = "INSERT INTO node_version (id, node_id) VALUES (%d, %d) ALLOW FILTERING;"; + + /* Rich Version-specific statements */ + public static final String INSERT_RICH_VERSION_WITH_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " + + "\'%s\') ALLOW FILTERING;"; + public static final String INSERT_RICH_VERSION_WITHOUT_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " + + "null) ALLOW FILTERING;"; + public static final String INSERT_RICH_VERSION_TAG_WITH_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " + + "\'%s\', \'%s\', \'%s\') ALLOW FILTERING;"; + public static final String INSERT_RICH_VERSION_TAG_NO_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " + + "\'%s\', null, null) ALLOW FILTERING;"; + public static final String INSERT_RICH_VERSION_EXTERNAL_PARAMETER = "INSERT INTO rich_version_external_parameter (rich_version_id, key, value) " + + "VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; + public static final String SELECT_RICH_VERSION_EXTERNAL_PARAMETERS = "SELECT * FROM rich_version_external_parameter WHERE rich_version_id = %d ALLOW FILTERING;"; + public static final String SELECT_RICH_VERSION_TAGS = "SELECT * FROM rich_version_tag WHERE rich_version_id = %d ALLOW FILTERING;"; + public static final String SELECT_RICH_VERSION_TAGS_BY_KEY = "SELECT * FROM rich_version_tag WHERE key = \'%s\' ALLOW FILTERING;"; + public static final String DELETE_RICH_VERSION_TAGS = "DELETE FROM rich_version_tag WHERE rich_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_RICH_EXTERNAL_PARAMETERS = "DELETE FROM rich_version_external_parameter WHERE rich_version_id = %d"; + + /* Structure-specific statements */ + public static final String INSERT_STRUCTURE_VERSION = "INSERT INTO structure_version (id, structure_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String INSERT_STRUCTURE_VERSION_ATTRIBUTE = "INSERT INTO structure_version_attribute (structure_version_id, key, type) " + + "VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; + public static final String SELECT_STRUCTURE_VERSION_ATTRIBUTES = "SELECT * FROM structure_version_attribute WHERE structure_version_id = %d ALLOW FILTERING;"; + public static final String DELETE_STRUCTURE_VERSION_ATTRIBUTES = "DELETE FROM structure_version_attribute WHERE structure_version_id = %d"; + + /* Lineage Edge-specific statements */ + public static final String INSERT_LINEAGE_EDGE_VERSION = "INSERT INTO lineage_edge_version (id, lineage_edge_id, from_rich_version_id, " + + "to_rich_version_id, principal_id) VALUES (%d, %d, %d, %d, %d) ALLOW FILTERING;"; + + /* Lineage Graph-specific statements */ + public static final String INSERT_LINEAGE_GRAPH_VERSION = "INSERT INTO lineage_graph_version (id, lineage_graph_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String INSERT_LINEAGE_GRAPH_VERSION_EDGE = "INSERT INTO lineage_graph_version_edge (lineage_graph_version_id, " + + "lineage_edge_version_id) VALUES (%d, %d) ALLOW FILTERING;"; + public static final String SELECT_LINEAGE_GRAPH_VERSION_EDGES = "SELECT * FROM lineage_graph_version_edge WHERE lineage_graph_version_id = %d ALLOW FILTERING;"; +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java new file mode 100644 index 00000000..482145fd --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java @@ -0,0 +1,92 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.core.EdgeDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import play.libs.Json; + + +public class CassandraEdgeDao extends CassandraItemDao implements EdgeDao { + + public CassandraEdgeDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return Edge.class; + } + + @Override + public Edge create(Edge edge) throws GroundException { + super.verifyItemNotExists(edge.getSourceKey()); + + CassandraStatements statements; + long uniqueId = idGenerator.generateItemId(); + + Edge newEdge = new Edge(uniqueId, edge); + try { + statements = super.insert(newEdge); + + String name = edge.getName(); + + if (name != null) { // Andre - Again CQL + statements.append(String.format(CqlConstants.INSERT_EDGE_WITH_NAME, uniqueId, edge.getSourceKey(), edge.getFromNodeId(), + edge.getToNodeId(), name)); + } else { + statements.append(String.format(CqlConstants.INSERT_EDGE_WITHOUT_NAME, uniqueId, edge.getSourceKey(), edge.getFromNodeId(), + edge.getToNodeId())); + } + + } catch (Exception e) { + throw new GroundException(e); + } + CassandraUtils.executeCqlList(dbSource, statements); + return newEdge; + } + + @Override + protected Edge retrieve(String cql, Object field) throws GroundException { + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.ITEM_NOT_FOUND, this.getType().getSimpleName(), field.toString()); + } + + Edge edge = Json.fromJson(json.get(0), Edge.class); + long id = edge.getId(); + return new Edge(id, edge.getName(), edge.getSourceKey(), edge.getFromNodeId(), edge.getToNodeId(), + super.cassandraTagDao.retrieveFromDatabaseByItemId(id)); + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + Edge edge = retrieveFromDatabase(sourceKey); + return super.getLeaves(edge.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java new file mode 100644 index 00000000..016a784c --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java @@ -0,0 +1,136 @@ +package edu.berkeley.ground.cassandra.dao.core; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.core.EdgeVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.model.core.EdgeVersion; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraVersionHistoryDagDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; +import play.libs.Json; + +public class CassandraEdgeVersionDao extends CassandraRichVersionDao implements EdgeVersionDao { + + private CassandraEdgeDao cassandraEdgeDao; + + public CassandraEdgeVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraEdgeDao = new CassandraEdgeDao(dbSource, idGenerator); + } + + @Override + public EdgeVersion create(final EdgeVersion edgeVersion, List parentIds) throws GroundException { + final long uniqueId = this.idGenerator.generateVersionId(); + EdgeVersion newEdgeVersion = new EdgeVersion(uniqueId, edgeVersion); + + CassandraStatements updateVersionList = this.cassandraEdgeDao.update(newEdgeVersion.getEdgeId(), newEdgeVersion.getId(), parentIds); + + for (long parentId : parentIds) { + if (parentId != 0) { + updateVersionList.merge(this.updatePreviousVersion(newEdgeVersion, newEdgeVersion.getEdgeId(), parentId)); + } + } + + try { + CassandraStatements statements = super.insert(newEdgeVersion); + Long fromEndId = edgeVersion.getFromNodeVersionEndId(); + Long toEndId = edgeVersion.getToNodeVersionEndId(); + + if (fromEndId == -1) { + fromEndId = null; + } + + if (toEndId == -1) { + toEndId = null; + } + + statements.append(String.format(CqlConstants.INSERT_EDGE_VERSION, uniqueId, edgeVersion.getEdgeId(), edgeVersion.getFromNodeVersionStartId(), + fromEndId, edgeVersion.getToNodeVersionStartId(), toEndId)); // Andre - CQL + + statements.merge(updateVersionList); + + CassandraUtils.executeCqlList(dbSource, statements); // Andre - Make into executeCqlList() - BATCH + } catch (Exception e) { + throw new GroundException(e); + } + + return newEdgeVersion; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "edge_version", id)); // Andre - CQL + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + /** + * Set the from and to end versions of a previous edge version. + * + * @param currentVersion the new version created + * @param edgeId the id of the edge we're updating + * @param parentId the id of the parent we're updating + * @return a set of statements to set the end versions + */ + private CassandraStatements updatePreviousVersion(EdgeVersion currentVersion, long edgeId, long parentId) throws GroundException { + CassandraStatements statements = new CassandraStatements(); + + CassandraVersionHistoryDagDao versionHistoryDagDao = + new CassandraVersionHistoryDagDao(this.dbSource, this.idGenerator); + + EdgeVersion parentVersion = this.retrieveFromDatabase(parentId); + Edge edge = this.cassandraEdgeDao.retrieveFromDatabase(edgeId); + + long fromNodeId = edge.getFromNodeId(); + long toNodeId = edge.getToNodeId(); + + long fromEndId = -1; + long toEndId = -1; + + if (parentVersion.getFromNodeVersionEndId() == -1) { + // update from end id + VersionHistoryDag dag = versionHistoryDagDao.retrieveFromDatabase(fromNodeId); + fromEndId = dag.getParent(currentVersion.getFromNodeVersionStartId()).get(0); + } + + if (parentVersion.getToNodeVersionEndId() == -1) { + // update to end id + VersionHistoryDag dag = versionHistoryDagDao.retrieveFromDatabase(toNodeId); + toEndId = dag.getParent(currentVersion.getToNodeVersionStartId()).get(0); + } + + if (fromEndId != -1 || toEndId != -1) { + statements.append(String.format(CqlConstants.UPDATE_EDGE_VERSION, fromEndId, toEndId, parentId)); + } + + return statements; + } + + @Override + public EdgeVersion retrieveFromDatabase(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "edge_version", id); // Andre - CQL + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); // Andre - executeCqlList + + if (json.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + json = json.get(0); + EdgeVersion edgeVersion = Json.fromJson(json, EdgeVersion.class); + RichVersion richVersion = super.retrieveFromDatabase(id); + + return new EdgeVersion(id, richVersion, edgeVersion); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java new file mode 100644 index 00000000..a520fa76 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java @@ -0,0 +1,73 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import edu.berkeley.ground.common.dao.core.GraphDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Graph; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; + + +public class CassandraGraphDao extends CassandraItemDao implements GraphDao { + + public CassandraGraphDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return Graph.class; + } + + @Override + public Graph create(Graph graph) throws GroundException { + super.verifyItemNotExists(graph.getSourceKey()); + + CassandraStatements statements; + long uniqueId = idGenerator.generateItemId(); + Graph newGraph = new Graph(uniqueId, graph); + + try { + statements = super.insert(newGraph); + + String name = graph.getName(); + if (name != null) { // Andre - CQL u know it + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "graph", uniqueId, graph.getSourceKey(), name)); + } else { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "graph", uniqueId, graph.getSourceKey())); + } + } catch (Exception e) { + throw new GroundException(e); + } + + CassandraUtils.executeCqlList(dbSource, statements); + return newGraph; + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + Graph graph = retrieveFromDatabase(sourceKey); + return super.getLeaves(graph.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java new file mode 100644 index 00000000..8c59ac34 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java @@ -0,0 +1,87 @@ +package edu.berkeley.ground.cassandra.dao.core; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.core.GraphVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.GraphVersion; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.ArrayList; +import java.util.List; +//import play.db.Database; +import play.libs.Json; + +public class CassandraGraphVersionDao extends CassandraRichVersionDao implements GraphVersionDao { + + private CassandraGraphDao cassandraGraphDao; + + public CassandraGraphVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraGraphDao = new CassandraGraphDao(dbSource, idGenerator); + } + + @Override + public GraphVersion create(final GraphVersion graphVersion, List parentIds) + throws GroundException { + + final long uniqueId = idGenerator.generateVersionId(); + GraphVersion newGraphVersion = new GraphVersion(uniqueId, graphVersion); + + CassandraStatements updateVersionList = this.cassandraGraphDao.update(newGraphVersion.getGraphId(), newGraphVersion.getId(), parentIds); + + try { + CassandraStatements statements = super.insert(newGraphVersion); + statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION, uniqueId, graphVersion.getGraphId())); // Andre - CQL its lit + statements.merge(updateVersionList); + + for (Long id : newGraphVersion.getEdgeVersionIds()) { + statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION_EDGE, newGraphVersion.getId(), id)); // Andre - CQL + } + + CassandraUtils.executeCqlList(dbSource, statements); // Andre - executeCqlList + } catch (Exception e) { + throw new GroundException(e); + } + return newGraphVersion; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_ALL_GRAPH_VERSION_EDGES, "graph_version_edge", "graph_version_id", id)); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "graph_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + @Override + public GraphVersion retrieveFromDatabase(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "graph_version", id); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + GraphVersion graphVersion = Json.fromJson(json.get(0), GraphVersion.class); + List edgeIds = new ArrayList<>(); + cql = String.format(CqlConstants.SELECT_GRAPH_VERSION_EDGES, id); + + JsonNode edgeJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + for (JsonNode edge : edgeJson) { + edgeIds.add(edge.get("edgeVersionId").asLong()); + } + + RichVersion richVersion = super.retrieveFromDatabase(id); + return new GraphVersion(id, richVersion.getTags(), richVersion.getStructureVersionId(), richVersion.getReference(), richVersion.getParameters(), + graphVersion.getGraphId(), edgeIds); + } +} + diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java new file mode 100644 index 00000000..5af7e15c --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java @@ -0,0 +1,66 @@ +package edu.berkeley.ground.cassandra.dao.core; + +import edu.berkeley.ground.common.dao.core.NodeDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; // Andre - What is this - CQL needed +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +//import play.db.Database; + + +public class CassandraNodeDao extends CassandraItemDao implements NodeDao { + + public CassandraNodeDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return Node.class; + } + + @Override + public Node create(Node node) throws GroundException { + super.verifyItemNotExists(node.getSourceKey()); + + CassandraStatements statements; + long uniqueId = idGenerator.generateItemId(); + + Node newNode = new Node(uniqueId, node); + try { + statements = super.insert(newNode); + + String name = node.getName(); + + // Andre -- SQL to CQL + if (name != null) { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "node", uniqueId, node.getSourceKey(), name)); + } else { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "node", uniqueId, node.getSourceKey())); + } + } catch (Exception e) { + throw new GroundException(e); + } + + // Andre -- SQL to CQL + CassandraUtils.executeCqlList(dbSource, statements); + return newNode; + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + Node node = this.retrieveFromDatabase(sourceKey); + return super.getLeaves(node.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } + +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java new file mode 100644 index 00000000..58b7b4cf --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java @@ -0,0 +1,73 @@ +package edu.berkeley.ground.cassandra.dao.core; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.core.NodeVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.NodeVersion; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; // Andre - SQL to CQL +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +//import play.db.Database; +import play.libs.Json; + +public class CassandraNodeVersionDao extends CassandraRichVersionDao implements NodeVersionDao { + + private CassandraNodeDao cassandraNodeDao; + + public CassandraNodeVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraNodeDao = new CassandraNodeDao(dbSource, idGenerator); + } + + @Override + public NodeVersion create(final NodeVersion nodeVersion, List parentIds) + throws GroundException { + + final long uniqueId = idGenerator.generateVersionId(); + NodeVersion newNodeVersion = new NodeVersion(uniqueId, nodeVersion); + + CassandraStatements updateVersionList = this.cassandraNodeDao.update(newNodeVersion.getNodeId(), newNodeVersion.getId(), parentIds); // Andre - Problem line + + try { + CassandraStatements statements = super.insert(newNodeVersion); // Andre - SQL to CQL + statements.append(String.format(CqlConstants.INSERT_NODE_VERSION, uniqueId, nodeVersion.getNodeId())); + statements.merge(updateVersionList); + + CassandraUtils.executeCqlList(dbSource, statements); // Andre - SQL to CQL + } catch (Exception e) { + e.printStackTrace(); + throw new GroundException(e); + } + return newNodeVersion; + } + + @Override + public CassandraStatements delete(long id) { // Andre - Modify CassandraStatements? + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "node_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + @Override + public NodeVersion retrieveFromDatabase(long id) throws GroundException { // Andre - refresh on Cassandra queries + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "node_version", id); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + NodeVersion nodeVersion = Json.fromJson(json.get(0), NodeVersion.class); + RichVersion richVersion = super.retrieveFromDatabase(id); + + return new NodeVersion(id, richVersion, nodeVersion); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java new file mode 100644 index 00000000..ef72647c --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java @@ -0,0 +1,240 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import edu.berkeley.ground.common.dao.core.RichVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.core.StructureVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraTagDao; +import edu.berkeley.ground.cassandra.dao.version.CassandraVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.QueryExecutionException; + +// import java.sql.Connection; // Andre - what to do here +// import java.sql.ResultSet; +// import java.sql.SQLException; +// import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; +import play.Logger; // Not necessary +// import play.db.Database; + +public abstract class CassandraRichVersionDao extends CassandraVersionDao implements RichVersionDao { + + private CassandraTagDao cassandraTagDao; + + public CassandraRichVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraTagDao = new CassandraTagDao(dbSource); + } + + @Override + public CassandraStatements insert(final T richVersion) throws GroundException { + long id = richVersion.getId(); + Long structureVersionId; + + if (richVersion.getStructureVersionId() == -1) { + structureVersionId = null; + } else { + CassandraStructureVersionDao cassandraStructureVersionDao = new CassandraStructureVersionDao(dbSource, idGenerator); + StructureVersion structureVersion = cassandraStructureVersionDao.retrieveFromDatabase(richVersion.getStructureVersionId()); + structureVersionId = richVersion.getStructureVersionId(); + checkStructureTags(structureVersion, richVersion.getTags()); + } + + CassandraStatements statements = super.insert(richVersion); + + String reference = richVersion.getReference(); + if (reference != null) { + statements.append(String.format(CqlConstants.INSERT_RICH_VERSION_WITH_REFERENCE, id, structureVersionId, reference)); + } else { + statements.append(String.format(CqlConstants.INSERT_RICH_VERSION_WITHOUT_REFERENCE, id, structureVersionId)); + } + + final Map tags = richVersion.getTags(); + for (String tagKey : tags.keySet()) { + Tag tag = tags.get(tagKey); + + statements.merge(this.cassandraTagDao.insertRichVersionTag(new Tag(id, tag.getKey(), tag.getValue(), tag.getValueType()))); + } + + Map parameters = richVersion.getParameters(); + if (!parameters.isEmpty()) { + for (String key : parameters.keySet()) { + statements.append(String.format(CqlConstants.INSERT_RICH_VERSION_EXTERNAL_PARAMETER, richVersion.getId(), key, parameters.get(key))); + } + } + + return statements; // Andre - What happens to these statements that are returned? + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + + statements.append(String.format(CqlConstants.DELETE_RICH_VERSION_TAGS, id)); + statements.append(String.format(CqlConstants.DELETE_RICH_EXTERNAL_PARAMETERS, id)); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "rich_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + + @Override + public RichVersion retrieveFromDatabase(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "rich_version", id); + + // ResultSet resultSet; + String reference; + long structureVersionId; + + // Cluster cluster = this.dbSource.getCluster(); + // Session session = this.dbSource.getSession(cluster); + + Session session = this.dbSource.getSession(); + + + try { + ResultSet resultSet = session.execute(cql); + + if (resultSet.isExhausted()) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, RichVersion.class.getSimpleName(), String.format("%d", id)); + } + + Row nextRow = resultSet.one(); + + // Logger.debug("Andre: nextRow: " + nextRow.getColumnDefinitions().size()); + // for (int i = 0; i < nextRow.getColumnDefinitions().size(); i++) { + // Logger.debug("Andre: nextRow: " + nextRow.getColumnDefinitions().getName(i)); + // } + + reference = nextRow.getString("reference"); // Andre - Modified index + structureVersionId = nextRow.getLong("structure_version_id"); // Andre - Modified index + + } catch (QueryExecutionException e) { + throw new GroundException(e); + } + + // session.close(); + // cluster.close(); + + // try (Connection con = dbSource.getConnection()) { + // Statement stmt = con.createStatement(); + // resultSet = stmt.executeQuery(cql); + + // if (!resultSet.next()) { + // throw new GroundException(ExceptionType.VERSION_NOT_FOUND, RichVersion.class.getSimpleName(), String.format("%d", id)); + // } + + // reference = resultSet.getString(3); + // structureVersionId = resultSet.getLong(2); + // stmt.close(); + // con.close(); + // } catch (SQLException e) { // Andre - WTF DO I DO HERE! CQLException???? + // throw new GroundException(e); + // } + + Map tags = this.cassandraTagDao.retrieveFromDatabaseByVersionId(id); + Map referenceParams = getReferenceParameters(id); + structureVersionId = structureVersionId == 0 ? -1 : structureVersionId; + + return new RichVersion(id, tags, structureVersionId, reference, referenceParams); + } + + private Map getReferenceParameters(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_RICH_VERSION_EXTERNAL_PARAMETERS, id); + Map referenceParameters = new HashMap<>(); + + // Cluster cluster = this.dbSource.getCluster(); + // Session session = this.dbSource.getSession(cluster); + + Session session = this.dbSource.getSession(); + + ResultSet parameterSet = session.execute(cql); + // Row nextRow = parameterSet.one(); + if (parameterSet.isExhausted()) { + return referenceParameters; + } + + // referenceParameters.put(nextRow.getString("key"), nextRow.getString("value")); // Andre - Modified index + for (Row row: parameterSet.all()) { + referenceParameters.put(row.getString("key"), row.getString("value")); // Andre - Modified index + } + + // session.close(); + // cluster.close(); + + // try (Connection con = dbSource.getConnection()) { + // Statement stmt = con.createStatement(); + // ResultSet parameterSet = stmt.executeQuery(cql); + // if (!parameterSet.next()) { + // return referenceParameters; + // } + // do { + // referenceParameters.put(parameterSet.getString(2), parameterSet.getString(3)); + // } while (parameterSet.next()); + + // stmt.close(); + // con.close(); + // } catch (Exception e) { + // throw new GroundException(e); + // } + return referenceParameters; + } + + + /** + * Validate that the given Tags satisfy the StructureVersion's requirements. + * + * @param structureVersion the StructureVersion to check against + * @param tags the provided tags + */ + private static void checkStructureTags(StructureVersion structureVersion, Map tags) + throws GroundException { + + Map structureVersionAttributes = structureVersion.getAttributes(); + + if (tags.isEmpty()) { + throw new GroundException(ExceptionType.OTHER, String.format("No tags were specified even though a StructureVersion (%d) was.", + structureVersion.getId())); + } + + for (String key : structureVersionAttributes.keySet()) { + if (!tags.keySet().contains(key)) { + // check if such a tag exists + throw new GroundException(ExceptionType.OTHER, String.format("No tag with key %s was specified.", key)); + } else if (tags.get(key).getValueType() == null) { + // check that value type is specified + throw new GroundException(ExceptionType.OTHER, String.format("Tag with key %s did not have a value.", key)); + } else if (!tags.get(key).getValueType().equals(structureVersionAttributes.get(key))) { + // check that the value type is the same + throw new GroundException(ExceptionType.OTHER, String.format( + "Tag with key %s did not have a value of the correct type: expected [%s] but found [%s].", key, structureVersionAttributes.get(key), + tags.get(key).getValueType())); + } + } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java new file mode 100644 index 00000000..0d75aac2 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java @@ -0,0 +1,77 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import edu.berkeley.ground.common.dao.core.StructureDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Structure; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; + + +public class CassandraStructureDao extends CassandraItemDao implements StructureDao { + + public CassandraStructureDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return Structure.class; + } + + @Override + public Structure create(Structure structure) throws GroundException { + super.verifyItemNotExists(structure.getSourceKey()); + + CassandraStatements cassandraStatements; + long uniqueId = idGenerator.generateItemId(); + + Structure newStructure = new Structure(uniqueId, structure); + + try { + cassandraStatements = super.insert(newStructure); + + String name = structure.getName(); + + if (name != null) { // Andre - Make into CQL statements + cassandraStatements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "structure", uniqueId, structure.getSourceKey(), name)); + } else { + cassandraStatements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "structure", uniqueId, structure.getSourceKey())); + } + } catch (GroundException e) { + throw e; + } catch (Exception e) { + throw new GroundException(e); + } + + CassandraUtils.executeCqlList(dbSource, cassandraStatements); // Andre - Batch CQL? + return newStructure; + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + Structure structure = retrieveFromDatabase(sourceKey); + return super.getLeaves(structure.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java new file mode 100644 index 00000000..8fa1e95c --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java @@ -0,0 +1,107 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.core.StructureVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.StructureVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +//import play.db.Database; +import play.libs.Json; + +public class CassandraStructureVersionDao extends CassandraVersionDao implements StructureVersionDao { + + private CassandraStructureDao cassandraStructureDao; + + public CassandraStructureVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraStructureDao = new CassandraStructureDao(dbSource, idGenerator); + } + + @Override + public final StructureVersion create(final StructureVersion structureVersion, List parentIds) throws GroundException { + + long uniqueId = idGenerator.generateItemId(); + StructureVersion newStructureVersion = new StructureVersion(uniqueId, structureVersion); + CassandraStatements updateVersionList = this.cassandraStructureDao + .update(newStructureVersion.getStructureId(), newStructureVersion.getId(), parentIds); + + try { + CassandraStatements statements = super.insert(newStructureVersion); // Andre - Get statements from insertion? + statements.append(String.format(CqlConstants.INSERT_STRUCTURE_VERSION, uniqueId, structureVersion.getStructureId())); + + for (Map.Entry attribute : structureVersion.getAttributes().entrySet()) { // Andre - Change to CQL + statements.append(String.format(CqlConstants.INSERT_STRUCTURE_VERSION_ATTRIBUTE, uniqueId, attribute.getKey(), attribute.getValue())); + } + + statements.merge(updateVersionList); // Andre - Update some type of lineage tree of versions? + + CassandraUtils.executeCqlList(dbSource, statements); + } catch (Exception e) { + throw new GroundException(e); + } + + return newStructureVersion; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_STRUCTURE_VERSION_ATTRIBUTES, id)); // Andre - CQL + statements.append(String.format(CqlConstants.DELETE_BY_ID, "structure_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + @Override + public StructureVersion retrieveFromDatabase(final long id) throws GroundException { + HashMap attributes; + try { + String resultQuery = String.format(CqlConstants.SELECT_STAR_BY_ID, "structure_version", id); + JsonNode resultJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, resultQuery)); // Andre - Async call? May be blocking/waiting? + + if (resultJson.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + StructureVersion structureVersion = Json.fromJson(resultJson.get(0), StructureVersion.class); + + String attributeQuery = String.format(CqlConstants.SELECT_STRUCTURE_VERSION_ATTRIBUTES, id); + JsonNode attributeJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, attributeQuery)); + + attributes = new HashMap<>(); + + for (JsonNode attribute : attributeJson) { + GroundType type = GroundType.fromString(attribute.get("type").asText()); + attributes.put(attribute.get("key").asText(), type); + } + + structureVersion = new StructureVersion(structureVersion.getId(), structureVersion.getStructureId(), attributes); + return structureVersion; + } catch (Exception e) { + throw new GroundException(e); + } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java new file mode 100644 index 00000000..f6a03006 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java @@ -0,0 +1,75 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.usage; + +import edu.berkeley.ground.common.dao.usage.LineageEdgeDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageEdge; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; + +public class CassandraLineageEdgeDao extends CassandraItemDao implements LineageEdgeDao { + + public CassandraLineageEdgeDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return LineageEdge.class; + } + + @Override + public LineageEdge create(LineageEdge lineageEdge) throws GroundException { + super.verifyItemNotExists(lineageEdge.getSourceKey()); + + long uniqueId = this.idGenerator.generateItemId(); + LineageEdge newLineageEdge = new LineageEdge(uniqueId, lineageEdge); + CassandraStatements statements = super.insert(newLineageEdge); + + String name = lineageEdge.getName(); + + if (name != null) { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "lineage_edge", newLineageEdge.getId(), + newLineageEdge.getSourceKey(), name)); + } else { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "lineage_edge", newLineageEdge.getId(), + newLineageEdge.getSourceKey())); + } + + try { + CassandraUtils.executeCqlList(this.dbSource, statements); + return newLineageEdge; + } catch (Exception e) { + throw new GroundException(e); + } + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + LineageEdge lineageEdge = retrieveFromDatabase(sourceKey); + return super.getLeaves(lineageEdge.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } + +} + diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java new file mode 100644 index 00000000..b6b6ae6d --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java @@ -0,0 +1,87 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.usage; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.usage.LineageEdgeVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.usage.LineageEdgeVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.core.CassandraRichVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; +import play.libs.Json; + +public class CassandraLineageEdgeVersionDao extends CassandraRichVersionDao implements LineageEdgeVersionDao { + + private CassandraLineageEdgeDao cassandraLineageEdgeDao; + + public CassandraLineageEdgeVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraLineageEdgeDao = new CassandraLineageEdgeDao(dbSource, idGenerator); + } + + @Override + public LineageEdgeVersion create(final LineageEdgeVersion lineageEdgeVersion, + List parentIds) throws GroundException { + final long uniqueId = idGenerator.generateVersionId(); + + LineageEdgeVersion newLineageEdgeVersion = new LineageEdgeVersion(uniqueId, lineageEdgeVersion); + + CassandraStatements updateVersionList = this.cassandraLineageEdgeDao + .update(newLineageEdgeVersion.getLineageEdgeId(), newLineageEdgeVersion.getId(), parentIds); + + try { + CassandraStatements statements = super.insert(newLineageEdgeVersion); + statements.append(String.format(CqlConstants.INSERT_LINEAGE_EDGE_VERSION, uniqueId, newLineageEdgeVersion.getLineageEdgeId(), + newLineageEdgeVersion.getFromId(), newLineageEdgeVersion.getToId(), null)); + statements.merge(updateVersionList); + + CassandraUtils.executeCqlList(dbSource, statements); + } catch (Exception e) { + throw new GroundException(e); + } + return newLineageEdgeVersion; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "lineage_edge_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + + @Override + public LineageEdgeVersion retrieveFromDatabase(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "lineage_edge_version", id); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + LineageEdgeVersion lineageEdgeVersion = Json.fromJson(json.get(0), LineageEdgeVersion.class); + RichVersion richVersion = super.retrieveFromDatabase(id); + + return new LineageEdgeVersion(id, richVersion, lineageEdgeVersion); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java new file mode 100644 index 00000000..33a517db --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java @@ -0,0 +1,73 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.usage; + +import edu.berkeley.ground.common.dao.usage.LineageGraphDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageGraph; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; + +public class CassandraLineageGraphDao extends CassandraItemDao implements LineageGraphDao { + + public CassandraLineageGraphDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return LineageGraph.class; + } + + @Override + public LineageGraph create(LineageGraph lineageGraph) throws GroundException { + super.verifyItemNotExists(lineageGraph.getSourceKey()); + + long uniqueId = idGenerator.generateItemId(); + LineageGraph newLineageGraph = new LineageGraph(uniqueId, lineageGraph); + + CassandraStatements statements = super.insert(newLineageGraph); + + String name = lineageGraph.getName(); + if (name != null) { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "lineage_graph", newLineageGraph.getId(), + newLineageGraph.getSourceKey(), name)); + } else { + statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "lineage_graph", newLineageGraph.getId(), + newLineageGraph.getSourceKey())); + } + + try { + CassandraUtils.executeCqlList(dbSource, statements); + return newLineageGraph; + } catch (Exception e) { + throw new GroundException(e); + } + } + + @Override + public List getLeaves(String sourceKey) throws GroundException { + LineageGraph lineageGraph = retrieveFromDatabase(sourceKey); + return super.getLeaves(lineageGraph.getId()); + } + + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + super.truncate(itemId, numLevels); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java new file mode 100644 index 00000000..24b9d7f6 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java @@ -0,0 +1,102 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.usage; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.usage.LineageGraphVersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.usage.LineageGraphVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.dao.core.CassandraRichVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.ArrayList; +import java.util.List; +// import play.db.Database; +import play.libs.Json; + +public class CassandraLineageGraphVersionDao extends CassandraRichVersionDao implements LineageGraphVersionDao { + + private CassandraLineageGraphDao cassandraLineageGraphDao; + + public CassandraLineageGraphVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + this.cassandraLineageGraphDao = new CassandraLineageGraphDao(dbSource, idGenerator); + } + + @Override + public LineageGraphVersion create(LineageGraphVersion lineageGraphVersion, List parentIds) + throws GroundException { + final long uniqueId = idGenerator.generateVersionId(); + LineageGraphVersion newLineageGraphVersion = new LineageGraphVersion(uniqueId, lineageGraphVersion); + + CassandraStatements updateVersionList = this.cassandraLineageGraphDao + .update(newLineageGraphVersion.getLineageGraphId(), newLineageGraphVersion.getId(), + parentIds); + + try { + CassandraStatements statements = super.insert(newLineageGraphVersion); + statements.append(String.format(CqlConstants.INSERT_LINEAGE_GRAPH_VERSION, uniqueId, newLineageGraphVersion.getLineageGraphId())); + + statements.merge(updateVersionList); + + for (Long id : newLineageGraphVersion.getLineageEdgeVersionIds()) { + statements.append(String.format(CqlConstants.INSERT_LINEAGE_GRAPH_VERSION_EDGE, newLineageGraphVersion.getId(), id)); + } + + CassandraUtils.executeCqlList(dbSource, statements); + } catch (Exception e) { + throw new GroundException(e); + } + + return newLineageGraphVersion; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_ALL_GRAPH_VERSION_EDGES, "lineage_graph_version_edge", "lineage_graph_version_id", id)); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "graph_version", id)); + + CassandraStatements superStatements = super.delete(id); + superStatements.merge(statements); + return superStatements; + } + + @Override + public LineageGraphVersion retrieveFromDatabase(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "lineage_graph_version", id); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); + } + + LineageGraphVersion lineageGraphVersion = Json.fromJson(json.get(0), LineageGraphVersion.class); + + List edgeIds = new ArrayList<>(); + cql = String.format(CqlConstants.SELECT_LINEAGE_GRAPH_VERSION_EDGES, id); + + JsonNode edgeJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + for (JsonNode edge : edgeJson) { + edgeIds.add(edge.get("lineageEdgeVersionId").asLong()); + } + + RichVersion richVersion = super.retrieveFromDatabase(id); + return new LineageGraphVersion(id, richVersion.getTags(), richVersion.getStructureVersionId(), richVersion.getReference(), + richVersion.getParameters(), lineageGraphVersion.getLineageGraphId(), edgeIds); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java new file mode 100644 index 00000000..1d210aa4 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java @@ -0,0 +1,169 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.version; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.base.CaseFormat; +import edu.berkeley.ground.common.dao.version.ItemDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.version.Item; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +//import play.db.Database; +import play.libs.Json; +import play.Logger; // Andre + +public abstract class CassandraItemDao implements ItemDao { + + private CassandraVersionHistoryDagDao cassandraVersionHistoryDagDao; + protected CassandraTagDao cassandraTagDao; + protected CassandraDatabase dbSource; + protected IdGenerator idGenerator; + + public CassandraItemDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + this.dbSource = dbSource; + this.idGenerator = idGenerator; + this.cassandraVersionHistoryDagDao = new CassandraVersionHistoryDagDao(dbSource, idGenerator); + this.cassandraTagDao = new CassandraTagDao(dbSource); + } + + @Override + public CassandraStatements insert(final T item) throws GroundException { + long id = item.getId(); + + final List cqlList = new ArrayList<>(); + cqlList.add(String.format(CqlConstants.INSERT_ITEM, id)); + + final Map tags = item.getTags(); + CassandraStatements statements = new CassandraStatements(cqlList); + // statements.intendToCreateId(id); // Andre - added for modified statements + + if (tags != null) { + for (String key : tags.keySet()) { + Tag tag = tags.get(key); + statements.merge(this.cassandraTagDao.insertItemTag(new Tag(id, tag.getKey(), tag.getValue(), tag.getValueType()))); + } + } + + return new CassandraStatements(cqlList); + } + + @Override + public T retrieveFromDatabase(String sourceKey) throws GroundException { + return this.retrieve(String.format(CqlConstants.SELECT_STAR_BY_SOURCE_KEY, CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, + this.getType().getSimpleName()), sourceKey), sourceKey); + } + + @Override + public T retrieveFromDatabase(long id) throws GroundException { + return this.retrieve(String.format(CqlConstants.SELECT_STAR_ITEM_BY_ID, CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, + this.getType().getSimpleName()), id), id); + } + + @Override + public List getLeaves(long itemId) throws GroundException { + try { + VersionHistoryDag dag = this.cassandraVersionHistoryDagDao.retrieveFromDatabase(itemId); + + return dag.getLeaves(); + } catch (GroundException e) { + if (!e.getMessage().contains("No results found for query:")) { + throw e; + } + + return new ArrayList<>(); + } + } + + /** + * Add a new Version to this Item. The provided parentIds will be the parents of this particular + * version. What's provided in the default case varies based on which database we are writing + * into. + * + * @param itemId the id of the Item we're updating + * @param childId the new version's id + * @param parentIds the ids of the parents of the child + */ + @Override + public CassandraStatements update(long itemId, long childId, List parentIds) throws GroundException { + + if (parentIds.isEmpty()) { + parentIds.add(0L); + } + + VersionHistoryDag dag = this.cassandraVersionHistoryDagDao.retrieveFromDatabase(itemId); + CassandraStatements statements = new CassandraStatements(); + + for (String s: statements.getAllStatements()) { + Logger.debug("Andre statement: " + s); + } + + for (long parentId : parentIds) { + Logger.debug("Andre: PARENTID: " + parentId); + if (parentId != 0L && !dag.checkItemInDag(parentId)) { + throw new GroundException(ExceptionType.OTHER, String.format("Parent %d is not in Item %d.", parentId, itemId)); + } + + statements.merge(this.cassandraVersionHistoryDagDao.addEdge(dag, parentId, childId, itemId)); + } + + return statements; + } + + /** + * Truncate the item to only have the most recent levels. + * + * @param numLevels the levels to keep + * @throws GroundException an error while removing versions + */ + @Override + public void truncate(long itemId, int numLevels) throws GroundException { + VersionHistoryDag dag; + dag = cassandraVersionHistoryDagDao.retrieveFromDatabase(itemId); + this.cassandraVersionHistoryDagDao.truncate(dag, numLevels, this.getType()); + } + + protected T retrieve(String cql, Object field) throws GroundException { + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.ITEM_NOT_FOUND, this.getType().getSimpleName(), field.toString()); + } + + Class type = this.getType(); + JsonNode itemJson = json.get(0); + long id = itemJson.get("itemId").asLong(); + String name = itemJson.get("name").asText(); + String sourceKey = itemJson.get("sourceKey").asText(); + + Object[] args = {id, name, sourceKey, this.cassandraTagDao.retrieveFromDatabaseByItemId(id)}; + + Constructor constructor; + try { + constructor = type.getConstructor(long.class, String.class, String.class, Map.class); + return constructor.newInstance(args); + } catch (Exception e) { + throw new GroundException(ExceptionType.OTHER, String.format("Catastrophic failure: Unable to instantiate Item.\n%s: %s.", + e.getClass().getName(), e.getMessage())); + } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java new file mode 100644 index 00000000..e61e4835 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java @@ -0,0 +1,213 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ *

http://www.apache.org/licenses/LICENSE-2.0 + *

+ *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.version; + +import edu.berkeley.ground.common.dao.version.TagDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.QueryExecutionException; + +// import java.sql.Connection; // Andre - what do to here? +// import java.sql.ResultSet; +// import java.sql.SQLException; +// import java.sql.Statement; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +//import play.db.Database; +import play.Logger; // Andre unnecessary + +public class CassandraTagDao implements TagDao { + + private CassandraDatabase dbSource; + + public CassandraTagDao(CassandraDatabase dbSource) { + this.dbSource = dbSource; + } + + @Override + public CassandraStatements insertItemTag(final Tag tag) { + List cqlList = new ArrayList<>(); + if (tag.getValue() != null) { + cqlList.add(String.format(CqlConstants.INSERT_ITEM_TAG_WITH_VALUE, tag.getId(), tag.getKey(), tag.getValue(), tag.getValueType())); + } else { + cqlList.add( + String.format(CqlConstants.INSERT_ITEM_TAG_NO_VALUE, tag.getId(), tag.getKey())); + } + return new CassandraStatements(cqlList); + } + + @Override + public CassandraStatements insertRichVersionTag(final Tag tag) { + List cqlList = new ArrayList<>(); + if (tag.getValue() != null) { + cqlList.add(String.format(CqlConstants.INSERT_RICH_VERSION_TAG_WITH_VALUE, tag.getId(), tag.getKey(), tag.getValue(), tag.getValueType())); + } else { + cqlList.add(String.format(CqlConstants.INSERT_RICH_VERSION_TAG_NO_VALUE, tag.getId(), tag.getKey())); + } + + return new CassandraStatements(cqlList); + } + + @Override + public Map retrieveFromDatabaseByVersionId(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_RICH_VERSION_TAGS, id); + return this.retrieveFromDatabaseById(id, cql); + } + + @Override + public Map retrieveFromDatabaseByItemId(long id) throws GroundException { + String cql = String.format(CqlConstants.SELECT_ITEM_TAGS, id); + return this.retrieveFromDatabaseById(id, cql); + } + + private Map retrieveFromDatabaseById(long id, String cql) throws GroundException { + Map results = new HashMap<>(); + + // Cluster cluster = this.dbSource.getCluster(); + // Session session = this.dbSource.getSession(cluster); + + Session session = this.dbSource.getSession(); + // Logger.debug + + ResultSet resultSet = session.execute(cql); + for (Row row: resultSet.all()) { + String key = row.getString("key"); // Andre - Modified index + + // these methods will return null if the input is null, so there's no need to check + GroundType type = GroundType.fromString(row.getString("type")); // Andre - Modified index + Object value = this.getValue(type, row, "value"); // Andre - Modified index + // Logger.debug("id: " + id); + // Logger.debug("key: " + key); + // Logger.debug("value: " + value); + // Logger.debug("type: " + type); + + results.put(key, new Tag(id, key, value, type)); + } + + // session.close(); + // cluster.close(); + + // try { + // Connection con = this.dbSource.getConnection(); + // Statement stmt = con.createStatement(); + + // ResultSet resultSet = stmt.executeQuery(cql); + + // while (resultSet.next()) { + // String key = resultSet.getString(2); + + // // these methods will return null if the input is null, so there's no need to check + // GroundType type = GroundType.fromString(resultSet.getString(4)); + // Object value = this.getValue(type, resultSet, 3); + + // results.put(key, new Tag(id, key, value, type)); + // } + + // stmt.close(); + // con.close(); + // } catch (SQLException e) { // Andre - CQLException???? + // throw new GroundException(e); + // } + + return results; + } + + @Override + public List getVersionIdsByTag(String tag) throws GroundException { + String cql = String.format(CqlConstants.SELECT_RICH_VERSION_TAGS_BY_KEY, tag); + return this.getIdsByTag(cql, "rich_version_id"); + } + + @Override + public List getItemIdsByTag(String tag) throws GroundException { + String cql = String.format(CqlConstants.SELECT_ITEM_TAGS_BY_KEY, tag); + return this.getIdsByTag(cql, "item_id"); + } + + private List getIdsByTag(String cql, String idColumn) throws GroundException { + List result = new ArrayList<>(); + + // Cluster cluster = this.dbSource.getCluster(); + // Session session = this.dbSource.getSession(cluster); + + Session session = this.dbSource.getSession(); + + try { + ResultSet resultSet = session.execute(cql); + for (Row row: resultSet.all()) { + result.add(row.getLong(idColumn)); // Andre - Modified + } + } catch (QueryExecutionException e) { // Andre - CQLException?? + throw new GroundException(e); + } + + // session.close(); + // cluster.close(); + + // try { + // Connection con = this.dbSource.getConnection(); + // Statement stmt = con.createStatement(); + // ResultSet resultSet = stmt.executeQuery(cql); + + // while (resultSet.next()) { + // result.add(resultSet.getLong(1)); + // } + + // } catch (SQLException e) { // Andre - CQLException?? + // throw new GroundException(e); + // } + + return result; + } + + // private Object getValue(GroundType type, ResultSet resultSet, String columnName) throws GroundException, SQLException { // Andre - CQLException?? + private Object getValue(GroundType type, Row row, String columnName) throws GroundException { // Andre - CQLException?? + + if (type == null) { + return null; + } + + Logger.debug(type.toString()); + Logger.debug(row.getString(columnName)); + + switch (type) { + case STRING: + // return row.getString(columnName); + return row.getString(columnName); // Andre + case INTEGER: + // return row.getInt(columnName); + return Integer.valueOf(row.getString(columnName)); // Andre + case LONG: + // return row.getLong(columnName); + return Long.valueOf(row.getString(columnName)); // Andre + case BOOLEAN: + // return row.getBool(columnName); + return Boolean.valueOf(row.getString(columnName)); // Andre + default: + // this should never happen because we've listed all types + throw new GroundException(ExceptionType.OTHER, String.format("Unidentified type: %s", type)); + } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java new file mode 100644 index 00000000..b9f8b841 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java @@ -0,0 +1,48 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.version; + +import edu.berkeley.ground.common.dao.version.VersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.version.Version; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +//import play.db.Database; + +public abstract class CassandraVersionDao implements VersionDao { + + protected CassandraDatabase dbSource; + protected IdGenerator idGenerator; + + public CassandraVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + this.dbSource = dbSource; + this.idGenerator = idGenerator; + } + + @Override + public CassandraStatements insert(T version) throws GroundException { + CassandraStatements statements = new CassandraStatements(); + + statements.append(String.format(CqlConstants.INSERT_VERSION, version.getId())); + return statements; + } + + @Override + public CassandraStatements delete(long id) { + CassandraStatements statements = new CassandraStatements(); + statements.append(String.format(CqlConstants.DELETE_BY_ID, "version", id)); + + return statements; + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java new file mode 100644 index 00000000..5b388019 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java @@ -0,0 +1,196 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.version; + +import edu.berkeley.ground.common.dao.version.VersionHistoryDagDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.version.Item; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.GroundUtils; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; + +// import java.sql.Connection; // Andre - what do I do here... +// import java.sql.ResultSet; +// import java.sql.Statement; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +// import play.db.Database; + +public class CassandraVersionHistoryDagDao implements VersionHistoryDagDao { + + private CassandraVersionSuccessorDao cassandraVersionSuccessorDao; + private CassandraDatabase dbSource; + private IdGenerator idGenerator; + + public CassandraVersionHistoryDagDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + this.dbSource = dbSource; + this.idGenerator = idGenerator; + + this.cassandraVersionSuccessorDao = new CassandraVersionSuccessorDao(this.dbSource, this.idGenerator); + } + + @Override + public VersionHistoryDag create(long itemId) throws GroundException { + return new VersionHistoryDag(itemId, new ArrayList<>()); + } + + /** + * Retrieve a DAG from the database. + * + * @param itemId the id of the item whose dag we are retrieving + * @return the retrieved DAG + * @throws GroundException an error retrieving the DAG + */ + @Override + public VersionHistoryDag retrieveFromDatabase(long itemId) throws GroundException { + String cql = String.format(CqlConstants.SELECT_VERSION_HISTORY_DAG, itemId); + + List edges = new ArrayList<>(); + + // Cluster cluster = this.dbSource.getCluster(); + // Session session = this.dbSource.getSession(cluster); + + Session session = this.dbSource.getSession(); + + final ResultSet resultSet = session.execute(cql); + List successors = new ArrayList<>(); + for (Row row: resultSet.all()) { + successors.add(row.getLong("version_successor_id")); + } + + for (Long versionSuccessorId : successors) { + VersionSuccessor versionSuccessor = cassandraVersionSuccessorDao.retrieveFromDatabase(versionSuccessorId); + edges.add(versionSuccessor); + } + + // session.close(); + // cluster.close(); + + // try (Connection con = dbSource.getConnection()) { + + // Statement stmt = con.createStatement(); + // final ResultSet resultSet = stmt.executeQuery(cql); + + // List successors = new ArrayList<>(); + // while (resultSet.next()) { + // successors.add(resultSet.getLong("version_successor_id")); + // } + + // stmt.close(); + // con.close(); + + // for (Long versionSuccessorId : successors) { + // VersionSuccessor versionSuccessor = cassandraVersionSuccessorDao.retrieveFromDatabase(versionSuccessorId); + // edges.add(versionSuccessor); + // } + // } catch (Exception e) { + // throw new GroundException(e); + // } + return new VersionHistoryDag(itemId, edges); + } + + /** + * Add an edge to the DAG. + * + * @param dag the DAG to update + * @param parentId the parent's id + * @param childId the child's id + * @param itemId the id of the Item whose DAG we're updating + * @throws GroundException an error adding the edge + */ + @Override + public CassandraStatements addEdge(VersionHistoryDag dag, long parentId, long childId, long itemId) throws GroundException { + VersionSuccessor successor = this.cassandraVersionSuccessorDao.instantiateVersionSuccessor(parentId, childId); + dag.addEdge(parentId, childId, successor.getId()); + + CassandraStatements statements = cassandraVersionSuccessorDao.insert(successor); + statements.append(String.format(CqlConstants.INSERT_VERSION_HISTORY_DAG_EDGE, itemId, successor.getId())); + return statements; + } + + + /** + * Truncate the DAG to only have a certain number of levels, removing everything before that. + * + * @param dag the DAG to truncate + * @param numLevels the number of levels to keep + */ + @Override + public void truncate(VersionHistoryDag dag, int numLevels, Class itemType) throws GroundException { + + int keptLevels = 1; + List lastLevel = new ArrayList<>(); + List previousLevel = dag.getLeaves(); + + while (keptLevels <= numLevels) { + List currentLevel = new ArrayList<>(); + + previousLevel.forEach(id -> currentLevel.addAll(dag.getParent(id))); + + lastLevel = previousLevel; + previousLevel = currentLevel; + + keptLevels++; + } + + List deleteQueue = new ArrayList<>(new HashSet<>(previousLevel)); + Set deleted = new HashSet<>(); + + CassandraStatements statements = new CassandraStatements(); + + // delete the version successors between the last kept level and the first deleted level + for (long id : lastLevel) { + this.cassandraVersionSuccessorDao.deleteFromDestination(statements, id, dag.getItemId()); + this.addEdge(dag, 0, id, dag.getItemId()); + } + + while (deleteQueue.size() > 0) { + long id = deleteQueue.get(0); + + if (id != 0) { + this.cassandraVersionSuccessorDao.deleteFromDestination(statements, id, dag.getItemId()); + GroundUtils.getVersionDaoFromItemType(itemType, this.dbSource, this.idGenerator).delete(id); + + deleted.add(id); + List parents = dag.getParent(id); + + parents.forEach(parentId -> { + if (!deleted.contains(parentId)) { + deleteQueue.add(parentId); + } + }); + } + + deleteQueue.remove(0); + } + + for (long id : lastLevel) { + statements.merge(this.addEdge(dag, 0, id, dag.getItemId())); + } + + CassandraUtils.executeCqlList(dbSource, statements); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java new file mode 100644 index 00000000..7cc31309 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java @@ -0,0 +1,168 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.version; + +import com.fasterxml.jackson.databind.JsonNode; +import edu.berkeley.ground.common.dao.version.VersionSuccessorDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.common.util.DbStatements; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.CqlConstants; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +// import play.db.Database; +import play.libs.Json; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.QueryExecutionException; // Andre - may want to get rid of + +import play.Logger; // Andre - unnecessary + +public class CassandraVersionSuccessorDao implements VersionSuccessorDao { + + private final IdGenerator idGenerator; + private final CassandraDatabase dbSource; + + public CassandraVersionSuccessorDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + this.dbSource = dbSource; + this.idGenerator = idGenerator; + } + + /** + * Create a cqlList containing commands that will persist a new version successor + * + * @param successor the successor to insert + * @return List of CQL expressions to insert version successor + */ + @Override + public CassandraStatements insert(VersionSuccessor successor) { + // Check to see if both are valid ids since we don't have foreign key constraints + // verifyVersion(successor.getFromId()); // Andre - not working for now + // verifyVersion(successor.getFromId()); + + CassandraStatements statements = new CassandraStatements(); + String cql = String.format(CqlConstants.INSERT_VERSION_SUCCESSOR, successor.getId(), successor.getFromId(), successor.getToId()); + statements.append(cql); + + return statements; + } + + /** + * Create and persist a version successor. + * + * @param fromId the id of the parent version + * @param toId the id of the child version + * @return the created version successor + */ + VersionSuccessor instantiateVersionSuccessor(long fromId, long toId) throws GroundException { + // Check to see if both are valid ids since we don't have foreign key constraints + // Logger.debug("Andre: checking versions exist"); + // verifyVersion(fromId); // Andre - not working for now + // verifyVersion(toId); + + long dbId = idGenerator.generateSuccessorId(); + return new VersionSuccessor(dbId, fromId, toId); + } + + /** + * Retrieve a version successor from the database. + * + * @param dbId the id of the successor to retrieve + * @return the retrieved version successor + * @throws GroundException either the successor didn't exist or couldn't be retrieved + */ + @Override + public VersionSuccessor retrieveFromDatabase(long dbId) throws GroundException { + try { + String cql = String.format(CqlConstants.SELECT_VERSION_SUCCESSOR, dbId); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + if (json.size() == 0) { + throw new GroundException(ExceptionType.OTHER, String.format("Version Successor with id %d does not exist.", dbId)); + } + + json = json.get(0); + return new VersionSuccessor(dbId, json.get("fromVersionId").asLong(), json.get("toVersionId").asLong()); + } catch (Exception e) { + throw new GroundException(e); + } + + } + + /** + * Delete a version successor from the database. + * + * @param statementsPointer the list of DB statements to append to + * @param toId the destination version + * @param itemId the id of the item we are deleting from + * @throws GroundException an unexpected error while retrieving the version successors to delete + */ + @Override + public void deleteFromDestination(DbStatements statementsPointer, long toId, long itemId) throws GroundException { + CassandraStatements statements = (CassandraStatements) statementsPointer; + + try { + String cql = String.format(CqlConstants.SELECT_VERSION_SUCCESSOR_BY_ENDPOINT, toId); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + + for (JsonNode result : json) { + Long dbId = result.get("id").asLong(); + + statements.append(String.format(CqlConstants.DELETE_SUCCESSOR_FROM_DAG, itemId, dbId)); // Andre + statements.append(String.format(CqlConstants.DELETE_VERSION_SUCCESSOR, dbId)); + + // statements.append(String.format(CqlConstants.DELETE_SUCCESSOR_FROM_DAG, dbId)); + // statements.append(String.format(CqlConstants.DELETE_VERSION_SUCCESSOR, dbId)); + } + } catch (Exception e) { + throw new GroundException(e); + } + } + + /** + * Verify that id is a valid id since foreign key constraints don't exist. + * + * @param id an idea of a version + */ + private void verifyVersion(long id) throws GroundException { + // List predicate = new ArrayList<>(); + // predicate.add(new DbDataContainer("id", GroundType.LONG, id)); + if (id == 0L ) { + return; + } + + Session session = this.dbSource.getSession(); + + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "version", id); + ResultSet resultSet = session.execute(cql); + + if (resultSet.isExhausted()) { + throw new GroundException(ExceptionType.VERSION_NOT_FOUND, "version", String.valueOf(id)); + } + + // ResultSet resultSet = this.dbClient.equalitySelect("version", DbClient.SELECT_STAR, + // predicate); + + // if (resultSet.isEmpty()) { + // throw new GroundException("Version id " + id + " is not valid."); + // } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/filters/GroundFilter.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/filters/GroundFilter.java new file mode 100644 index 00000000..ddc29ea7 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/filters/GroundFilter.java @@ -0,0 +1,37 @@ +package edu.berkeley.ground.cassandra.filters; + +import akka.stream.Materializer; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executor; +import java.util.function.Function; +import javax.inject.Inject; +import javax.inject.Singleton; +import play.mvc.Filter; +import play.mvc.Http.RequestHeader; +import play.mvc.Result; + +/** + * This is a simple filter that adds a header to all requests. + */ +@Singleton +public class GroundFilter extends Filter { + + private final Executor exec; + + /** + * @param mat This object is needed to handle streaming of requests and responses. + * @param exec This class is needed to execute code asynchronously. It is used below by the thenAsyncApply method. + */ + @Inject + public GroundFilter(Materializer mat, Executor exec) { + super(mat); + this.exec = exec; + } + + @Override + public CompletionStage apply( + Function> next, RequestHeader requestHeader) { + + return next.apply(requestHeader).thenApplyAsync(result -> result.withHeader("X-ExampleFilter", "foo"), exec); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/start/ApplicationStart.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/start/ApplicationStart.java new file mode 100644 index 00000000..2097842a --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/start/ApplicationStart.java @@ -0,0 +1,38 @@ +package edu.berkeley.ground.cassandra.start; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import java.time.Clock; +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import javax.inject.Inject; +import javax.inject.Singleton; +import play.Logger; +import play.api.Configuration; +// import play.db.Database; +import play.inject.ApplicationLifecycle; + +@Singleton +public class ApplicationStart { + + private final Instant start; + + @Inject + public ApplicationStart(Clock clock, ApplicationLifecycle appLifecycle, final Configuration configuration, final CassandraDatabase dbSource) + throws GroundException { + + this.start = clock.instant(); + Logger.info("Ground Cassandra: Starting application at " + this.start); + + Logger.info("Queries will Cache for {} seconds.", configuration.underlying().getString("ground.cache.expire.secs")); + System.setProperty("ground.cache.expire.secs", configuration.underlying().getString("ground.cache.expire.secs")); + + appLifecycle.addStopHook( + () -> { + Instant stop = clock.instant(); + Long runningTime = stop.getEpochSecond() - this.start.getEpochSecond(); + Logger.info("Ground Cassandra: Stopping application at " + clock.instant() + " after " + runningTime + "s."); + return CompletableFuture.completedFuture(null); + }); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraDatabase.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraDatabase.java new file mode 100644 index 00000000..2f4823d1 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraDatabase.java @@ -0,0 +1,126 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.util; + + +import com.datastax.driver.core.BoundStatement; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.PlainTextAuthProvider; +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Session; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; + + +public class CassandraDatabase { +// private static final Logger LOGGER = LoggerFactory.getLogger(CassandraClient.class); + + private final String host; + private final int port; + private final String keyspace; + private final String username; + private final String password; + + private final Cluster cluster; + private final Session session; + + /** + * Constructor for the Cassandra client. + * + * @param host the host address for Cassandra + * @param port the Cassandra port + * @param keyspace the name of the keyspace we're using + * @param username the login username + * @param password the login password + */ + public CassandraDatabase(String host, int port, String keyspace, String username, String password) { + this.host = host; + this.port = port; + this.keyspace = keyspace; + this.username = username; + this.password = password; + + this.cluster = this.makeCluster(); + this.session = this.makeSession(); + } + + /** + * Returns the host of this Cassandra Database + * @return host + */ + public String getHost() { + return this.host; + } + + /** + * Returns the port of this Cassandra Database + * @return port + */ + public int getPort() { + return this.port; + } + + /** + * Returns the keyspace of this Cassandra Database + * @return keyspace + */ + public String getKeyspace() { + return this.keyspace; + } + + /** + * Returns the username of this Cassandra Database + * @return username + */ + public String getUsername() { + return this.username; + } + + /** + * Returns the password of this Cassandra Database + * @return password + */ + public String getPassword() { + return this.password; + } + + /** + * Returns a new Session for this Cassandra Database + * @return session + */ + private Cluster makeCluster() { + return Cluster.builder() + .addContactPoint(this.host) + .withPort(this.port) + .withAuthProvider(new PlainTextAuthProvider(this.username, this.password)) + .build(); + } + + /** + * Returns a new Session for a given cluster + * @param cluster + * @return session + */ + private Session makeSession() { + return this.cluster.connect(this.keyspace); + } + + public Session getSession() { + return this.session; + } + + public void shutdown() { + this.session.close(); + this.cluster.close(); + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java new file mode 100644 index 00000000..86001989 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java @@ -0,0 +1,46 @@ +package edu.berkeley.ground.cassandra.util; + +import edu.berkeley.ground.common.util.DbStatements; +import java.util.ArrayList; +import java.util.List; +// import java.util.HashSet; // Andre +// import play.Logger; // Andre - unnecessary + +public class CassandraStatements implements DbStatements { + + List statements; + // HashSet idsToCreate; // Andre + + public CassandraStatements() { + this.statements = new ArrayList<>(); + // this.idsToCreate = new HashSet(); + } + + public CassandraStatements(List statements) { + this.statements = statements; + } + + @Override + public void append(String statement) { + // Logger.debug("Andre statement append: " + statement); + this.statements.add(statement); + } + + // public void intendToCreateId(Long id) { // Andre + // this.idsToCreate.add(id); + // } + + // public boolean isIntendingToCreateId(Long id) { // Andre + // return this.idsToCreate.contains(id); + // } + + @Override + public void merge(DbStatements other) { + this.statements.addAll(other.getAllStatements()); + } + + @Override + public List getAllStatements() { + return this.statements; + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java new file mode 100644 index 00000000..14db02e4 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java @@ -0,0 +1,160 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.util; + +import akka.actor.ActorSystem; +import com.google.common.base.CaseFormat; +import edu.berkeley.ground.common.exception.GroundException; + +//import java.sql.Connection; // Andre - What to do here? +//import java.sql.ResultSet; +//import java.sql.SQLException; +//import java.sql.Statement; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.QueryExecutionException; + +import edu.berkeley.ground.cassandra.util.CassandraDatabase; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; +import play.Logger; +// import play.db.Database; +import play.libs.concurrent.HttpExecution; + +public final class CassandraUtils { + + private CassandraUtils() { + } + + public static Executor getDbSourceHttpContext(final ActorSystem actorSystem) { // Andre - does this change? + return HttpExecution.fromThread((Executor) actorSystem.dispatchers().lookup("ground.db.context")); + } + + public static String executeQueryToJson(CassandraDatabase dbSource, String cql) throws GroundException { + Logger.debug("executeQueryToJson: {}", cql); + + // Cluster cluster = dbSource.getCluster(); + // Session session = dbSource.getSession(cluster); + + final List> objList = new ArrayList<>(); + Session session = dbSource.getSession(); + + try { + final ResultSet resultSet = session.execute(cql); // Andre - Session conveniently returns a resultSet? + + // final long columnCount = resultSet.getColumnDefinitions().size(); + + for (Row row: resultSet.all()) { + final Map rowData = new HashMap<>(); + + for (int column = 0; column < resultSet.getColumnDefinitions().size(); column++) { + // for (int column = 1; column <= columnCount; column++) { // Andre - Maybe should start from 0? + String key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, resultSet.getColumnDefinitions().getName(column)); + rowData.put(key, row.getObject(column)); + } + + objList.add(rowData); + } + } catch (QueryExecutionException e) { + throw new GroundException(e); + } + + // session.close(); + // cluster.close(); + + Logger.debug("Andre: Returning JSON"); + return GroundUtils.listToJson(objList); + + // try { + // Cluster cluster = dbSource.getCluster(); + // Session session = dbSource.getSession(cluster); + + // final ResultSet resultSet = session.execute(cql); // Andre - Session conveniently returns a resultSet? + // final long columnCount = resultSet.getMetaData().getColumnCount(); + // final List> objList = new ArrayList<>(); + + // while (resultSet.next()) { + // final Map rowData = new HashMap<>(); + + // for (int column = 1; column <= columnCount; column++) { // Andre - Maybe should start from 0? + // String key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, resultSet.getMetaData().getColumnLabel(column)); + // rowData.put(key, resultSet.getObject(column)); + // } + + // objList.add(rowData); + // } + + // session.close(); + // cluster.close(); + // return GroundUtils.listToJson(objList); + // } catch (SQLException e) { + // Logger.error("ERROR: executeQueryToJson CQL : {} Message: {} Trace: {}", cql, e.getMessage(), e.getStackTrace()); + // throw new GroundException(e); + // } + } + + public static void executeCqlList(final CassandraDatabase dbSource, final CassandraStatements statements) throws GroundException { + + // Cluster cluster = dbSource.getCluster(); + // Session session = dbSource.getSession(cluster); + + Session session = dbSource.getSession(); + + try { + for (final String cql : statements.getAllStatements()) { + Logger.debug("executeCqlList cql : {}", cql); + session.execute(cql); + } + } catch (QueryExecutionException e) { + Logger.error("error: Message: {} Trace: {}", e.getMessage(), e.getStackTrace()); + throw new GroundException(e); + } + + // session.close(); + // cluster.close(); + + // try { + // Connection con = dbSource.getConnection(); + // con.setAutoCommit(false); + // Statement stmt = con.createStatement(); + + // for (final String sql : statements.getAllStatements()) { + // Logger.debug("executeSqlList sql : {}", sql); + + // try { + // stmt.execute(sql); + // } catch (final SQLException e) { + // con.rollback(); + // Logger.error("error: Message: {} Trace: {}", e.getMessage(), e.getStackTrace()); + + // throw new GroundException(e); + // } + // } + + // stmt.close(); + // con.commit(); + // con.close(); + // } catch (SQLException e) { + // Logger.error("error: executeSqlList SQL : {} Message: {} Trace: {}", statements.getAllStatements(), e.getMessage(), e.getStackTrace()); + + // throw new GroundException(e); + // } + } +} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java new file mode 100644 index 00000000..82005442 --- /dev/null +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java @@ -0,0 +1,112 @@ +package edu.berkeley.ground.cassandra.util; + +import static play.mvc.Results.badRequest; +import static play.mvc.Results.internalServerError; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import edu.berkeley.ground.common.dao.version.VersionDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.model.core.Graph; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.model.core.Structure; +import edu.berkeley.ground.common.model.usage.LineageEdge; +import edu.berkeley.ground.common.model.usage.LineageGraph; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraEdgeVersionDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraGraphVersionDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraNodeVersionDao; +import edu.berkeley.ground.cassandra.dao.core.CassandraStructureVersionDao; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageEdgeVersionDao; +import edu.berkeley.ground.cassandra.dao.usage.CassandraLineageGraphVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import play.Logger; +// import play.db.Database; +import play.libs.Json; +import play.mvc.Http.Request; +import play.mvc.Result; + +public final class GroundUtils { + + private GroundUtils() { + } + + public static Result handleException(Throwable e, Request request) { + if (e.getCause().getCause() instanceof GroundException) { + return badRequest(GroundUtils.getClientError(request, e.getCause().getCause(), ExceptionType.ITEM_NOT_FOUND)); + } else { + return internalServerError(GroundUtils.getServerError(request, e.getCause().getCause())); + } + } + + private static ObjectNode getServerError(final Request request, final Throwable e) { + Logger.error("Error! Request Path: {}\nError Message: {}\n Stack Trace: {}", request.path(), e.getMessage(), e.getStackTrace()); + + ObjectNode result = Json.newObject(); + result.put("Error", "Unexpected error while processing request."); + result.put("Request Path", request.path()); + + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + result.put("Stack Trace", sw.toString()); + return result; + } + + private static ObjectNode getClientError(final Request request, final Throwable e, ExceptionType type) { + Logger.error("Error! Request Path: {}\nError Message: {}\n Stack Trace: {}", request.path(), e.getMessage(), e.getStackTrace()); + + ObjectNode result = Json.newObject(); + + result.put("Error", String.format("The request to %s was invalid.", request.path())); + result.put("Message", String.format("%s", e.getMessage())); + + return result; + } + + static String listToJson(final List> objList) { + try { + Logger.debug("Andre: " + new ObjectMapper().writeValueAsString(objList)); + return new ObjectMapper().writeValueAsString(objList); + } catch (IOException e) { + throw new RuntimeException("ERROR : listToJson Converting List to JSON." + e.getMessage(), e); + } + } + + public static List getListFromJson(JsonNode jsonNode, String fieldName) { + List parents = new ArrayList<>(); + JsonNode listNode = jsonNode.get(fieldName); + + if (listNode != null) { + listNode.forEach(node -> parents.add(node.asLong())); + } + + return parents; + } + + public static VersionDao getVersionDaoFromItemType(Class klass, CassandraDatabase dbSource, IdGenerator idGenerator) throws GroundException { + if (klass.equals(Node.class)) { + return new CassandraNodeVersionDao(dbSource, idGenerator); + } else if (klass.equals(Edge.class)) { + return new CassandraEdgeVersionDao(dbSource, idGenerator); + } else if (klass.equals(Graph.class)) { + return new CassandraGraphVersionDao(dbSource, idGenerator); + } else if (klass.equals(Structure.class)) { + return new CassandraStructureVersionDao(dbSource, idGenerator); + } else if (klass.equals(LineageEdge.class)) { + return new CassandraLineageEdgeVersionDao(dbSource, idGenerator); + } else if (klass.equals(LineageGraph.class)) { + return new CassandraLineageGraphVersionDao(dbSource, idGenerator); + } else { + throw new GroundException(ExceptionType.OTHER, String.format("Unknown class :%s.", klass.getSimpleName())); + } + } +} diff --git a/modules/cassandra/app/views/index.scala.html b/modules/cassandra/app/views/index.scala.html new file mode 100644 index 00000000..f61f6ee4 --- /dev/null +++ b/modules/cassandra/app/views/index.scala.html @@ -0,0 +1,3 @@ +@(message: String) +@main("Welcome to Ground - Cassandra Plugin") { +} diff --git a/modules/cassandra/app/views/main.scala.html b/modules/cassandra/app/views/main.scala.html new file mode 100644 index 00000000..db7da9a1 --- /dev/null +++ b/modules/cassandra/app/views/main.scala.html @@ -0,0 +1,16 @@ +@(title: String)(content: Html) + + + + + @title + + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + diff --git a/modules/cassandra/conf/application.conf b/modules/cassandra/conf/application.conf new file mode 100644 index 00000000..1d9f631f --- /dev/null +++ b/modules/cassandra/conf/application.conf @@ -0,0 +1,45 @@ +# This is the main configuration file for the Ground Postgres. + + +play.crypto.secret = "groundpostgres" +ground.cache.expire.secs = 5 + +ground.db.context { + fork-join-executor { + parallelism-min = 1 + parallelism-factor = 4 + parallelism-max = 16 + } +} + +## Modules +play.modules { +} + + +## Internationalisation +play.i18n { + # The application languages + langs = ["en"] +} + +## Database Connection Pool +play.db { + # The combination of these two settings results in "db.default" as the + # default JDBC pool: + config = "db" + default = "default" + + prototype { + hikaricp.minimumIdle = 50 + hikaricp.maximumPoolSize = 20 + } +} + +## JDBC Datasource +db { + default.driver = org.postgresql.Driver + default.url = "jdbc:postgresql://localhost:5432/ground" + default.username = ground + default.password = metadata +} diff --git a/modules/cassandra/conf/logback.xml b/modules/cassandra/conf/logback.xml new file mode 100644 index 00000000..86ec12c0 --- /dev/null +++ b/modules/cassandra/conf/logback.xml @@ -0,0 +1,41 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/cassandra/conf/routes b/modules/cassandra/conf/routes new file mode 100644 index 00000000..948ea720 --- /dev/null +++ b/modules/cassandra/conf/routes @@ -0,0 +1,45 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# ~~~~ + +# An example controller showing a sample home page +GET / edu.berkeley.ground.cassandra.controllers.HomeController.index + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) + +# node endpoints +POST /nodes edu.berkeley.ground.cassandra.controllers.NodeController.addNode() +GET /nodes/:sourceKey edu.berkeley.ground.cassandra.controllers.NodeController.getNode(sourceKey: String) +POST /versions/nodes edu.berkeley.ground.cassandra.controllers.NodeController.addNodeVersion() +GET /versions/nodes/:id edu.berkeley.ground.cassandra.controllers.NodeController.getNodeVersion(id: Long) + +# graph endpoints +POST /graphs edu.berkeley.ground.cassandra.controllers.GraphController.addGraph() +GET /graphs/:sourceKey edu.berkeley.ground.cassandra.controllers.GraphController.getGraph(sourceKey: String) +POST /versions/graphs edu.berkeley.ground.cassandra.controllers.GraphController.addGraphVersion() +GET /versions/graphs/:id edu.berkeley.ground.cassandra.controllers.GraphController.getGraphVersion(id: Long) + +# structure endpoints +POST /structures edu.berkeley.ground.cassandra.controllers.StructureController.addStructure() +GET /structures/:sourceKey edu.berkeley.ground.cassandra.controllers.StructureController.getStructure(sourceKey: String) +POST /versions/structures edu.berkeley.ground.cassandra.controllers.StructureController.addStructureVersion() +GET /versions/structures/:id edu.berkeley.ground.cassandra.controllers.StructureController.getStructureVersion(id: Long) + +# edge endpoints +POST /edges edu.berkeley.ground.cassandra.controllers.EdgeController.addEdge() +GET /edges/:sourceKey edu.berkeley.ground.cassandra.controllers.EdgeController.getEdge(sourceKey: String) +POST /versions/edges edu.berkeley.ground.cassandra.controllers.EdgeController.addEdgeVersion() +GET /versions/edges/:id edu.berkeley.ground.cassandra.controllers.EdgeController.getEdgeVersion(id: Long) + +# lineage edge endpoints +POST /lineage_edges edu.berkeley.ground.cassandra.controllers.LineageEdgeController.createLineageEdge() +GET /lineage_edges/:sourceKey edu.berkeley.ground.cassandra.controllers.LineageEdgeController.getLineageEdge(sourceKey: String) +POST /versions/lineage_edges edu.berkeley.ground.cassandra.controllers.LineageEdgeController.createLineageEdgeVersion() +GET /versions/lineage_edges/:id edu.berkeley.ground.cassandra.controllers.LineageEdgeController.getLineageEdgeVersion(id: Long) + +# lineage graph endpoints +POST /lineage_graphs edu.berkeley.ground.cassandra.controllers.LineageGraphController.createLineageGraph() +GET /lineage_graphs/:sourceKey edu.berkeley.ground.cassandra.controllers.LineageGraphController.getLineageGraph(sourceKey: String) +POST /versions/lineage_graphs edu.berkeley.ground.cassandra.controllers.LineageGraphController.createLineageGraphVersion() +GET /versions/lineage_graphs/:id edu.berkeley.ground.cassandra.controllers.LineageGraphController.getLineageGraphVersion(id: Long) diff --git a/modules/cassandra/conf/swagger.yml b/modules/cassandra/conf/swagger.yml new file mode 100644 index 00000000..58840364 --- /dev/null +++ b/modules/cassandra/conf/swagger.yml @@ -0,0 +1,10 @@ +--- + swagger: "2.0" + info: + title: "cassandra Ground API" + description: "cassandra APIs" + version: "0.1" + consumes: + - application/json + produces: + - application/json diff --git a/modules/cassandra/project/build.properties b/modules/cassandra/project/build.properties new file mode 100644 index 00000000..a279d8ae --- /dev/null +++ b/modules/cassandra/project/build.properties @@ -0,0 +1,4 @@ +#Activator-generated Properties +#Tue Oct 04 16:51:22 CDT 2016 +template.uuid=26c759a5-daf0-4e02-bcfa-ac69725267c0 +sbt.version=0.13.15 diff --git a/modules/cassandra/project/plugins.sbt b/modules/cassandra/project/plugins.sbt new file mode 100644 index 00000000..0b0e11c1 --- /dev/null +++ b/modules/cassandra/project/plugins.sbt @@ -0,0 +1,6 @@ +// The Play plugin +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.13") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.0.0") + +addSbtPlugin("de.johoop" % "jacoco4sbt" % "2.2.0") diff --git a/modules/cassandra/public/images/favicon.png b/modules/cassandra/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..483081da32b4f7b5b4456a344ac24dbc46c51e2b GIT binary patch literal 8328 zcmeHM1y>xwmL6aTgAXu3f`l17fz06UZb6eUSa1t&!DVm>!4lkpOM(Y?2ol^qxI==w zEP3zk+ugsg=k=*Nr|Q;s?^oaL)74eoVXDfq_&5|e0001AUQS9K06;^3sJNg<4;Buw z(8Pz%6H7@+Re4ECsH&r#nWeQU0Kgn$Y+#@+$I9GeNNixxGr;l;$I(?iH1vbIfp2ST zKeP|p1#L6R9!LP1aiaEC z6hq1|#jFdOpwO+v*o;p_fTO11FS)rvjA1@dkb*jkf>@Q4kGQFtnTJf6KOI|+I;qfc z?5Q*410LSM98?6Wq6bcn`G%*uUmy-FH`$JEd*23A@UI2k`b#;Zi za>DH#%@OSU{QL+u4g?3siwDFDCwE(CL$?>UPIUha^51c!Or4A!E$y8x?QEfc;~E;- zxi|~c(*7m-_w~}r(wIjnwaTc zOffO5h!*1swq`?t<)G1is$ku+=b1#==Ze`n}D6_uq>Qd7IUpr=AP9aBhljrhf)u zf&2jfDWH>dztL-*?+*Dtj1D2`9$^}bSIJwJb**!2}Da?T#9%dzO@^OXViO=3cVn}DeK*>)Vi zs6d(yBsN{k+6k=&;UfHmPJ$WESkKJJW3(x!v36F*wi*N0*NZRHAV8HNY&!GcX!&4t zwXGnUbu`QwQHJM8CZ8QVR(nWy{xO2`&g_J3mB%j2 zN#b$xID05kJo6q%#R$wg*zLm|iWIoqKh!zj6Rr2sRFIduk6TS;e@v&u<*we|6-Huw zPsYn()FP_(WR@nCvvhufR_q17IpK~E)+DH(wHBYH{a0ZK8!ge zQPKxK3%9mvMMEcG$gBtVyz|wQz8jYGbVb}>WCsxDPVjLxDVyo4gz@U8d2PNNqoF1z zE0Y{2Hi^O{02?r6CWAp}2SV-!*Ap3D^>zy-{Xf}& zdyGH{fKcD*!6-U9BZ?QlmcG7dR-mZFVMF%V{%WQJ_nuGmne}%I$%2MX zZ!aKP19&R|9IEX%m0t7K8oozdt1=#3gT_`%j` z%9`|9rR4d0LkaoHsaX*jH=z_AJ5~b@m3%4=?ioh@m59{U&Ei^>9+)M@?D@;f z=QMffIKvslxM*K*wai+7xl?|RGalnb#owp*k_^wkGrJRmpNZgpG5B00??n@}s&$~70gclDxFG^n7U=CG3^{oike=2hGyg;flOb3rExpd8Si-g(2KXv6hQ zX|2Y?0-SrYSSgbq8giBr2;kFesW+gTBY8vaRr9BO)3*jST8oCwj=cZ5aE>>|V&|9= zEIb7pW`W5q*4oY-)r?J5GS0c;eRKCAio`vu*PQm&2=&t#x+eFBQjqu6*m)f0sv&&6 z(@9CCbtUa?mM2*v!z(hT*uK``pq>V0iWuwM%y;wT+A~fgEP1|pUOeKbW|s%G@+;5X zmNRs=N(SnGKHI*^*KAJvl~Hg-HR(2xwb8OD`nKP&ojy;bLlO`xIu9p2?3ffipUw-= z`<2;_xyp^ZMMJn~FBU5HDPBq}EBZT`g9r)lX7iKM8zD7J0Xd=ti+gW0k?;&Xi-kReRu7sZJD5<(L z*xccA98G^e|x!GO!+k9m&sIw^~~3Q};zl z>2>2IsnilJ&$CAkHS-A z?agzgLh^)4lK(W2jh1MTq}s1@>e^s-YaDN8ooDVgwvt+*rvJWFNly09Vr zj)tYY_4=8mp0rgczxOTBTUs+=|I*vz9cn%fe;;@jxYO?7LhQdYn#H0ui$%NgY&2!E zo^4K9KF$WyL1Sfc+gUsaQ8cs>o0v*eC@~&7iizz^?B5udU$QBeZ+T;1*Xh6!^1{4= zh->zQv`=+l)LB4B`f%{m`-_!E;MYJg9!Pp`e@5@Jt%O7^SI4+~Z%o#&nPDsfVbZw< zoojbZhBTJK&3Ca|`K6%W7U*vz#6A@whM3rYYTg=Ks75?V`14{*N}U`@#l*;3?8~L< z^Lhbty5H*00xl!-->DbZFTaruQGX>D0p>fUz}PW4X#E+=oDS=@eD(v3?!qy$ZuFhZ zzX&(LN-LHx@dp1DE#(lhpFbgH7ADzAZxx(f-8|w4mwGe|H)vM?!9S7Xku*RGeWe0b z3&_KsRNA_8;eqf?~{Zs{gt=Acv70tm@XGamJDeUvauxRIQLXnBMqqzq}u_P5u=a94{!h& ztnK^Wm1s;N2IF5EY+D$Fh4 z^Phd6%Hz|KsY^0;UsYGGg}2m+hQ2^zL4uz3suX>sqSIlV_vb)pnt8V2M=qV2gCoS# zt}zF(^l`6k<%2gROBf(Ibm~Cp@GkuyA+dBA?qJdogRZT+=Qa$eTgGjjuLpXrh$l4A z_vO=LYG}-aRiciso_UccQJNg0Gh5u(sSm%s1{amUqM+q{QX3rm!uZI)_hSI-8CjW`iXn^J17dbzLakrGWD zx#iSb4d8r{$rLc%r`&=9U4%4NW|O`Fsvqd7y4#`6el*Kb&g5DhuZdJJHId*&p%>pVdOA3hWYi_F;i0!H* zA4cW&INH5xSG9rUL{n3r5_G*vcZ#R!siPhh5x zQ&Yx?7L4%zdmqLPmf?x>XIC;Z3k`K1gr?7-z@3d;#m--hz-F}(vN%P0d6KXt2znKf z#R}6hl4&l`&&wHKNb6R6F{6f2JN};y0TLTz5-F;UxH_0JB=VeYQ z`6U{Y8-4Dm=bOZLav5BQKkUP{bKjzC=;KRe4Ad^J1LhH;+!-rp?bH3u+;#aI+cW8a zYIaDtzbwXFWv{nHHLkcZ$(%*a?4NtWh0Bca{SiM9H~RUr!Rq`fJE4bxcnrFAy^x1@A4qB(4=ieEGpw zL~H}J)v3RZKHz~_;5#)E8rn2}uP(~{9$k26Sef$fkqN~ABkp)n5`E`4(}(2(%nLtZ zHa40zTVTs8tjU|61$A}%** zownN=Bn%(0Im^U@-<4H{0A`EJ*(XJaF~JTZ!UfFM%HAd`Bypc;j2KM!Vi6n@)EIt= zmmvq@jnCon5&GY!jw*4DDIS5NF5 z=&k!gt_#C0FhgGCR~mky$Unv=sC$7@mVnB4>VK|H50d-Mb9K?MqaWUlkxnhHMLeNM zhZC5YkYi7Y@%O!He-LfV_-J*sQ_!lW*Bxt!Gs%g9GwVJ&R|dMbG}3D6xZqA*_Z7@M z!nw2Y@e85WJbdA$?@YRHMgb{(*|ZZeozWX;1lTRQy;dYEt~H3#o6%ki7G18CCb(bY z{c)fRaD9JK>m4%NM~XbBWb-G6v0;xI z`wEU2Dh6T`NkK4+Y!vTD#^GGBTz6x(ZNJ-l+nzWt<-D<NhLZ{=qs@Q_{Hhq(i@ z>YUu1`*bK-46CCHXMXer926eg-C&GLe^jO&oE(|T-&%yl_p`^Q8}ZZ>X$ z&s(eV8$~V(R-&lq?551@11+Y+AgJ_ZMm+ zc)*h#&SRq=Tq0J=SgBZC_Mhy22lwP?vGR+n{JQLp%Q9V$+<0wUL2|iIn(BT-dj6ktR zRY;thw|bZJcldQ{iD+VNjM~oKkz7tkTL>)ovF!F-NeM`;_L5*lr3V71#chK(ie;eh zt=rmeM_=>BUgpQ^#l@drCJFOW;^|9uAfn5TQwP)_UHV~jSTvfci|eKp;;W~R)vwqH zBK{R_+n?NAu9H#<;bAxL{WSa7))7H8b?-z)y!03H#mAB4n%dd|oV(+_o>5PQh?@WG zvOaePhT2-=!1$nn1`512OT?h)mlF0dI&Hi;6#|z(?5K|^5tyrE=`PQob90A`Iu1qj4SFYr;lg~)+8JZjsUM1fTQl01!b$> z&hPHpH}>YJ(-J?PMG`G@2{FcI(M3XtR#edLFnXrCQyQCQ1r$0%8}c|RXGVv|k(+uN zI)5~rzD%m>IJHSaJf1TbWM;+E{_HExX-|$nB^8t@O*$XpMJ!xRHLTi>f9S9uhXH35 zg1$|Xnuc0q>8R=_6W!nG&{%tI?yeA3cbN{^2i3XLtBjP*Ou+6>XDEdm9A&=!c|pb+ zmPe+e8D6s}VNVncb2BL_c+>qWIZj~z)>Xv)ezEt5B>Zhh@hT`(>!T9gW9kGM=}YN|D3^HWl@v*souM1OynR#Ce+j5N|reaGIs_ z$4Z2pm$oDY&!`)oeS6jL?TC78`t};2P|t`e$>2zjB{pLAUB#_Bx^4U&Fuhz91hFWg z=BxLBSW65O<$y6Sqsv~VOF*2*RY~Jwe6BV~nAB;6ytWz&Oz=;JT$P5_7bE;dO}SpC zf;D5go?kVAj9Z@ykGQVlt`$-07W-CfS*0{9zw`9{1 zJ+uDc;N@HfQ%(-fA$Wfe-)%tE_}JR~N+y%WhcIGdnenJd>Soyc+C!4nRx~Urk0a?T zftRtwmaL*_YP9fT-_YEjs&uL}l^ZYkbU|>2X>A=oSaZUrwwi^BZwvBwqmR9d>F2`Q zDif2zy4Z`xM*p0fn-vHCO`Myd_>BB_6O^>4CLcgw4%z}ZW$s@%$pAGE9l66eE%4t{z5LJe#-n~n zzE_TgV4!NxNQ_Yt!u|8-&)bv~6nK%5kyqj2IChmY)&=j%+$N?p-L;d2g(s6TdBhK+s>_D234GF7b4r8!v>(q8qa|g1}a^Bu$qMXD_mdg*M1uMBO9S z0&ZKN#8N2UNtKc*J0+DwmQKN#A0ycuTh=plF#5(`?CMj;k7i11Y*wiTS#q@LF^W{! z{`eChG0-c?Inz#~pJ+qNtLD*GQU*HCPv?`X(P0Kd%{$`VgoUEJs*G0c(`9xuaaaM# z^nizf>Z`5i@$5hk9NdGuaA9}00{I7y-`2%1lF#t_9{ZypPfV7QcKQdvXM4&32?N)h z1zBW5LM3zYwa%UsH(z|#qhW_@sbHjT8X(Y*Jw!SRB_g^C>3iegLr1qZIbr@d4oicA z@quZeF?f1ha+{URSQanlz1tg6LwTYP1@ZuiOvVMp)e_MrYuTT<`bEd?x?afeErCyC zl@5MlQ9vkAn6_dF|EPSae^9R_dbhmLH&8<&XBn|Ghr-l^0bol%d-GDY?!5vw%l(YH zG^$WM4h;D3t5g6F+nbOqo~6&tm)WlMGa(}-Zep9SHObjF)An^kiqy`zSJC0dJwNzHCnhM&CFzHE?+-x^h54mBW zH$efgElheHJEACHvrf8>)7By@9d^sPygExh5K7?*LaNpCkJZpq z-)D6&DF%|X?3c-!Ty}wmdYiZxj~zYLkRI-r zC%umaTV>}zvxXs&%?Q^);>e{dPFh#*d3E)G!6E$SKNi9*!p~3VQfln=`xOE-31D zPBUaTX!H$Ju4dJ@YOfSA&%Q&x1>cipq-7QdS>F)#bcq$QGsi-?= z^=XPwKLx)9R&9_t;S+eq?T;7iE}Id56!@Jj)`JH;y<(lHYuU=|ScSiv^)`mdlty{j zQzwXLPCaP*R-k>qzkarJxAK8&>eb5^J)$-A`^cZ23;IuKL&)yl(5%`bRnIPl@^snd z)XJ9RSV$VDL;Q4b#BE+DaZsT(*MWQ5=y2r%P_<`D=oBMjo#N@n=nKwHmj+Y|S8^Hj7` zK7ntwYFm~ecbD!x9STE#pC-TCD*gI1->(tFtyV@WZvY7`)_ zRoVJsM CREATE_KEYSPACE_CQL = keyspace->"create keyspace IF NOT EXISTS " + + keyspace + " with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };"; // Andre - will this be used? + + public CassandraTest() throws GroundException { + + } + + @Before + public void setup() throws IOException, InterruptedException, GroundException { + CassandraDatabase dbSource = new CassandraDatabase( + "localhost", + 9042, + "test", + "user", + "password" + ); + + IdGenerator idGenerator = new IdGenerator(0, 1, false); + + CassandraTest.dbSource = dbSource; + CassandraTest.idGenerator = idGenerator; + + CassandraTest.cassandraVersionDao = new TestCassandraVersionDao(dbSource, idGenerator); + CassandraTest.versionSuccessorDao = new CassandraVersionSuccessorDao(dbSource, idGenerator); + CassandraTest.versionHistoryDagDao = new CassandraVersionHistoryDagDao(dbSource, idGenerator); + CassandraTest.cassandraItemDao = new TestCassandraItemDao(dbSource, idGenerator); + CassandraTest.tagDao = new CassandraTagDao(dbSource); + + CassandraTest.cassandraRichVersionDao = new TestCassandraRichVersionDao(dbSource, idGenerator); + CassandraTest.structureDao = new CassandraStructureDao(dbSource, idGenerator); + CassandraTest.structureVersionDao = new CassandraStructureVersionDao(dbSource, idGenerator); + CassandraTest.edgeDao = new CassandraEdgeDao(dbSource, idGenerator); + CassandraTest.edgeVersionDao = new CassandraEdgeVersionDao(dbSource, idGenerator); + CassandraTest.graphDao = new CassandraGraphDao(dbSource, idGenerator); + CassandraTest.graphVersionDao = new CassandraGraphVersionDao(dbSource, idGenerator); + CassandraTest.nodeDao = new CassandraNodeDao(dbSource, idGenerator); + CassandraTest.nodeVersionDao = new CassandraNodeVersionDao(dbSource, idGenerator); + CassandraTest.lineageEdgeDao = new CassandraLineageEdgeDao(dbSource, idGenerator); + CassandraTest.lineageEdgeVersionDao = new CassandraLineageEdgeVersionDao(dbSource, idGenerator); + CassandraTest.lineageGraphDao = new CassandraLineageGraphDao(dbSource, idGenerator); + CassandraTest.lineageGraphVersionDao = new CassandraLineageGraphVersionDao(dbSource, idGenerator); + + runScript(TRUNCATE_SCRIPT); + runScript(CREATE_SCHEMA_SCRIPT); + } + + @After + public void tearDown() throws IOException, InterruptedException, GroundException { + dbSource.shutdown(); + } + + private static void runScript(String script) { + // Can wrap around with try-catch for a QueryExecutionException if wanted (like in PostgresTest.java for Postgres Connector) + Session session = dbSource.getSession(); + DaoTest.runScript(script, session::execute); + } + + // private static void runScript(String script) { // Andre - What the heck is happening here + // try { + // boolean autoCommitState = dbSource.getConnection().getAutoCommit(); + // dbSource.getConnection().setAutoCommit(false); + // StatementExecutor exec = new StatementExecutor(dbSource.getConnection()); + // CassandraTest.runScript(script, exec::execute); + // dbSource.getConnection().setAutoCommit(autoCommitState); + // } catch (SQLException ex) { + // throw new RuntimeException(ex); + // } + // } + + // private static class StatementExecutor { + + // private final Connection conn; + + // StatementExecutor(Connection conn) { + // this.conn = conn; + // } + + // void execute(String statement) { + // try { + // Statement sqlStatement = conn.createStatement(); + // sqlStatement.execute(statement); + // } catch (SQLException e) { + // String message = e.getMessage(); + // if (message.contains("already exists") || message + // .contains("current transaction is aborted")) { + // System.out.println("Warn: statement [" + statement + "] causes: " + e.getMessage()); + // // ignore errors caused by type already existing + // } else { + // throw new RuntimeException(e); + // } + // } + // } + // } + +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java new file mode 100644 index 00000000..774ffe6c --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java @@ -0,0 +1,259 @@ +package edu.berkeley.ground.cassandra.dao; + +import edu.berkeley.ground.common.dao.core.EdgeDao; +import edu.berkeley.ground.common.dao.core.EdgeVersionDao; +import edu.berkeley.ground.common.dao.core.GraphDao; +import edu.berkeley.ground.common.dao.core.GraphVersionDao; +import edu.berkeley.ground.common.dao.core.NodeDao; +import edu.berkeley.ground.common.dao.core.NodeVersionDao; +import edu.berkeley.ground.common.dao.core.RichVersionDao; +import edu.berkeley.ground.common.dao.core.StructureDao; +import edu.berkeley.ground.common.dao.core.StructureVersionDao; +import edu.berkeley.ground.common.dao.usage.LineageEdgeDao; +import edu.berkeley.ground.common.dao.usage.LineageEdgeVersionDao; +import edu.berkeley.ground.common.dao.usage.LineageGraphDao; +import edu.berkeley.ground.common.dao.usage.LineageGraphVersionDao; +import edu.berkeley.ground.common.dao.version.ItemDao; +import edu.berkeley.ground.common.dao.version.TagDao; +import edu.berkeley.ground.common.dao.version.VersionDao; +import edu.berkeley.ground.common.dao.version.VersionHistoryDagDao; +import edu.berkeley.ground.common.dao.version.VersionSuccessorDao; +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.model.core.EdgeVersion; +import edu.berkeley.ground.common.model.core.Graph; +import edu.berkeley.ground.common.model.core.GraphVersion; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.model.core.NodeVersion; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.core.Structure; +import edu.berkeley.ground.common.model.core.StructureVersion; +import edu.berkeley.ground.common.model.usage.LineageEdge; +import edu.berkeley.ground.common.model.usage.LineageEdgeVersion; +import edu.berkeley.ground.common.model.usage.LineageGraph; +import edu.berkeley.ground.common.model.usage.LineageGraphVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Item; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.common.model.version.Version; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +// import play.db.Database; + + +public class DaoTest { + + protected static CassandraDatabase dbSource; + protected static IdGenerator idGenerator; + protected static VersionSuccessorDao versionSuccessorDao; + protected static VersionHistoryDagDao versionHistoryDagDao; + protected static TagDao tagDao; + protected static EdgeDao edgeDao; + protected static GraphDao graphDao; + protected static LineageEdgeDao lineageEdgeDao; + protected static LineageGraphDao lineageGraphDao; + protected static NodeDao nodeDao; + protected static StructureDao structureDao; + protected static EdgeVersionDao edgeVersionDao; + protected static GraphVersionDao graphVersionDao; + protected static LineageEdgeVersionDao lineageEdgeVersionDao; + protected static LineageGraphVersionDao lineageGraphVersionDao; + protected static NodeVersionDao nodeVersionDao; + protected static StructureVersionDao structureVersionDao; + protected static RichVersionDao cassandraRichVersionDao; + protected static ItemDao cassandraItemDao; + protected static VersionDao cassandraVersionDao; + + public static Node createNode(String sourceKey) throws GroundException { + // id should be replaced by output of IdGenerator + return nodeDao.create(new Node(0L, null, sourceKey, new HashMap())); + } + + public static NodeVersion createNodeVersion(long nodeId) throws GroundException { + return createNodeVersion(nodeId, new ArrayList<>()); + } + + public static NodeVersion createNodeVersion(long nodeId, List parents) + throws GroundException { + NodeVersion nodeVersion = new NodeVersion(0L, new HashMap<>(), -1, null, new HashMap<>(), + nodeId); + return nodeVersionDao.create(nodeVersion, parents); + } + + public static Edge createEdge(String sourceKey, String fromNode, String toNode) + throws GroundException { + + long fromNodeId = nodeDao.retrieveFromDatabase(fromNode).getId(); + long toNodeId = nodeDao.retrieveFromDatabase(toNode).getId(); + Edge edge = new Edge(0L, null, sourceKey, fromNodeId, toNodeId, new HashMap<>()); + return edgeDao.create(edge); + } + + public static EdgeVersion createEdgeVersion(long edgeId, long fromStart, long toStart) + throws GroundException { + + return createEdgeVersion(edgeId, fromStart, toStart, new ArrayList<>()); + } + + public static EdgeVersion createEdgeVersion(long edgeId, + long fromStart, + long toStart, + List parents) + throws GroundException { + EdgeVersion edgeVersion = new EdgeVersion(0L, new HashMap<>(), -1, null, new HashMap<>(), + edgeId, fromStart, -1, toStart, -1); + return edgeVersionDao.create(edgeVersion, parents); + } + + public static EdgeVersion createEdgeVersion(long edgeId, + long fromStart, + long fromEnd, + long toStart, + long toEnd, + List parents) + throws GroundException { + EdgeVersion edgeVersion = new EdgeVersion(0L, new HashMap<>(), -1, null, new HashMap<>(), + edgeId, fromStart, fromEnd, toStart, toEnd); + return edgeVersionDao.create(edgeVersion, parents); + } + + public static Graph createGraph(String sourceKey) throws GroundException { + Graph graph = new Graph(0L, null, sourceKey, new HashMap<>()); + return graphDao.create(graph); + } + + public static GraphVersion createGraphVersion(long graphId, List edgeVersionIds) + throws GroundException { + + return createGraphVersion(graphId, edgeVersionIds, new ArrayList<>()); + } + + public static GraphVersion createGraphVersion(long graphId, + List edgeVersionIds, + List parents) throws GroundException { + + GraphVersion graphVersion = new GraphVersion(0L, new HashMap<>(), -1, null, new HashMap<>(), graphId, edgeVersionIds); + return graphVersionDao.create(graphVersion, parents); + } + + public static LineageEdge createLineageEdge(String sourceKey) throws GroundException { + LineageEdge lineageEdge = new LineageEdge(0L, null, sourceKey, new HashMap<>()); + return lineageEdgeDao.create(lineageEdge); + } + + public static LineageEdgeVersion createLineageEdgeVersion(long lineageEdgeId, + long fromId, + long toId) throws GroundException { + + return createLineageEdgeVersion(lineageEdgeId, fromId, toId, new ArrayList<>()); + } + + public static LineageEdgeVersion createLineageEdgeVersion(long lineageEdgeId, + long fromId, + long toId, + List parents) + throws GroundException { + LineageEdgeVersion lineageEdgeVersion = new LineageEdgeVersion(0L, new HashMap(), + (long) -1, + null, new HashMap<>(), fromId, toId, lineageEdgeId); + return lineageEdgeVersionDao.create(lineageEdgeVersion, parents); + } + + public static LineageGraph createLineageGraph(String sourceKey) throws GroundException { + LineageGraph lineageGraph = new LineageGraph(0L, null, sourceKey, new HashMap<>()); + return lineageGraphDao.create(lineageGraph); + } + + public static LineageGraphVersion createLineageGraphVersion(long lineageGraphId, + List lineageEdgeVersionIds) + throws GroundException { + + return createLineageGraphVersion(lineageGraphId, lineageEdgeVersionIds, new ArrayList<>()); + } + + public static LineageGraphVersion createLineageGraphVersion(long lineageGraphId, + List lineageEdgeVersionIds, + List parents) + throws GroundException { + + LineageGraphVersion lineageGraphVersion = new LineageGraphVersion(0L, new HashMap<>(), -1, null, + new HashMap<>(), lineageGraphId, lineageEdgeVersionIds); + return lineageGraphVersionDao.create(lineageGraphVersion, parents); + } + + + public static Structure createStructure(String sourceKey) throws GroundException { + Structure structure = new Structure(0L, null, sourceKey, new HashMap<>()); + return structureDao.create(structure); + } + + public static StructureVersion createStructureVersion(long structureId) throws GroundException { + return createStructureVersion(structureId, new ArrayList<>()); + } + + public static StructureVersion createStructureVersion(long structureId, List parents) + throws GroundException { + + Map structureVersionAttributes = new HashMap<>(); + structureVersionAttributes.put("intfield", GroundType.INTEGER); + structureVersionAttributes.put("boolfield", GroundType.BOOLEAN); + structureVersionAttributes.put("strfield", GroundType.STRING); + + StructureVersion structureVersion = new StructureVersion(0L, structureId, + structureVersionAttributes); + return structureVersionDao.create(structureVersion, parents); + } + + public static Map createTags() throws GroundException { + Map tags = new HashMap<>(); + tags.put("intfield", new Tag(-1, "intfield", 1, GroundType.INTEGER)); + tags.put("strfield", new Tag(-1, "strfield", "1", GroundType.STRING)); + tags.put("boolfield", new Tag(-1, "boolfield", true, GroundType.BOOLEAN)); + + return tags; + } + + public static long createTwoNodesAndEdge() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = DaoTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = DaoTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = DaoTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = DaoTest.createNodeVersion(secondTestNodeId).getId(); + + String edgeName = "testEdge"; + long edgeId = DaoTest.createEdge(edgeName, firstTestNode, secondTestNode).getId(); + + long edgeVersionId = DaoTest.createEdgeVersion(edgeId, firstNodeVersionId, + secondNodeVersionId).getId(); + + return edgeVersionId; + } + + protected static void runScript(String scriptFile, Consumer executor) { + final String SQL_COMMENT_START = "--"; + + try (Stream lines = Files.lines(Paths.get(scriptFile))) { + String data = lines.filter(line -> !line.startsWith(SQL_COMMENT_START)) + .collect(Collectors.joining()); + Arrays.stream(data.split(";")) + .map(chunk -> chunk + ";") + .forEach(statement -> executor.accept(statement)); + } catch (IOException e) { + throw new RuntimeException("Unable to read script file: " + scriptFile); + } + } + +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDaoTest.java new file mode 100644 index 00000000..9757a9f6 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDaoTest.java @@ -0,0 +1,131 @@ +package edu.berkeley.ground.cassandra.dao.core; + +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Edge; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.junit.Test; + +public class CassandraEdgeDaoTest extends CassandraTest { + + public CassandraEdgeDaoTest() throws GroundException { + super(); + } + + @Test + public void testEdgeCreation() throws GroundException { + String testName = "test"; + String sourceKey = "testKey"; + + String fromNodeName = "firstTestNode"; + String toNodeName = "secondTestNode"; + long fromNodeId = CassandraTest.createNode(fromNodeName).getId(); + long toNodeId = CassandraTest.createNode(toNodeName).getId(); + + CassandraTest.edgeDao.create(new Edge(0L, testName, sourceKey, fromNodeId, toNodeId, new HashMap<>())); + + Edge edge = CassandraTest.edgeDao.retrieveFromDatabase(sourceKey); + + assertEquals(testName, edge.getName()); + assertEquals(fromNodeId, edge.getFromNodeId()); + assertEquals(toNodeId, edge.getToNodeId()); + assertEquals(sourceKey, edge.getSourceKey()); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadEdge() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.edgeDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateEdge() throws GroundException { + String edgeName = "edgeName"; + String edgeKey = "edgeKey"; + String fromNode = "fromNode"; + String toNode = "toNode"; + + long fromNodeId = -1; + long toNodeId = -1; + + try { + fromNodeId = CassandraTest.createNode(fromNode).getId(); + toNodeId = CassandraTest.createNode(toNode).getId(); + + CassandraTest.edgeDao + .create(new Edge(0L, edgeName, edgeKey, fromNodeId, toNodeId, new HashMap<>())); + } catch (GroundException e) { + fail(e.getMessage()); + } + + CassandraTest.edgeDao + .create(new Edge(0L, edgeName, edgeKey, fromNodeId, toNodeId, new HashMap<>())); + } + + @Test + public void testTruncation() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String edgeName = "testEdge"; + long edgeId = CassandraTest.createEdge(edgeName, firstTestNode, secondTestNode).getId(); + + long edgeVersionId = CassandraTest.createEdgeVersion(edgeId, firstNodeVersionId, secondNodeVersionId).getId(); + + // create new node versions in each of the nodes + List parents = new ArrayList<>(); + parents.add(firstNodeVersionId); + long newFirstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId, parents).getId(); + + parents.clear(); + parents.add(secondNodeVersionId); + long newSecondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId, parents).getId(); + + parents.clear(); + parents.add(edgeVersionId); + long newEdgeVersionId = CassandraTest.createEdgeVersion(edgeId, newFirstNodeVersionId, newSecondNodeVersionId, parents).getId(); + + CassandraTest.edgeDao.truncate(edgeId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(edgeId); + + assertEquals(1, dag.getEdgeIds().size()); + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase(dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newEdgeVersionId, successor.getToId()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDaoTest.java new file mode 100644 index 00000000..5782f3a1 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDaoTest.java @@ -0,0 +1,166 @@ +package edu.berkeley.ground.cassandra.dao.core; + +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import static org.junit.Assert.assertEquals; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.EdgeVersion; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraEdgeVersionDaoTest extends CassandraTest { + + public CassandraEdgeVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testEdgeVersionCreation() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String edgeName = "testEdge"; + long edgeId = CassandraTest.createEdge(edgeName, firstTestNode, secondTestNode).getId(); + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + + EdgeVersion edgeVersion = new EdgeVersion(0L, tags, structureVersionId, testReference, + parameters, edgeId, firstNodeVersionId, -1, secondNodeVersionId, -1); + long edgeVersionId = CassandraTest.edgeVersionDao.create(edgeVersion, new ArrayList<>()) + .getId(); + + EdgeVersion retrieved = CassandraTest.edgeVersionDao.retrieveFromDatabase(edgeVersionId); + + assertEquals(edgeId, retrieved.getEdgeId()); + assertEquals(structureVersionId, (long) retrieved.getStructureVersionId()); + assertEquals(testReference, retrieved.getReference()); + assertEquals(firstNodeVersionId, retrieved.getFromNodeVersionStartId()); + assertEquals(secondNodeVersionId, retrieved.getToNodeVersionStartId()); + assertEquals(-1, retrieved.getFromNodeVersionEndId()); + assertEquals(-1, retrieved.getToNodeVersionEndId()); + + //assertEquals(parameters.size(), retrieved.getParameters().size()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedParameters = retrieved.getParameters(); + Map retrievedTags = retrieved.getTags(); + + for (String key : parameters.keySet()) { + assert (retrievedParameters).containsKey(key); + assertEquals(parameters.get(key), retrievedParameters.get(key)); + } + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + } + } + + @Test + public void testCorrectEndVersion() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String edgeName = "testEdge"; + long edgeId = CassandraTest.createEdge(edgeName, firstTestNode, secondTestNode).getId(); + + long edgeVersionId = CassandraTest.createEdgeVersion(edgeId, firstNodeVersionId, secondNodeVersionId).getId(); + + EdgeVersion retrieved = CassandraTest.edgeVersionDao.retrieveFromDatabase(edgeVersionId); + + assertEquals(edgeId, retrieved.getEdgeId()); + assertEquals(-1, (long) retrieved.getStructureVersionId()); + assertEquals(null, retrieved.getReference()); + assertEquals(firstNodeVersionId, retrieved.getFromNodeVersionStartId()); + assertEquals(secondNodeVersionId, retrieved.getToNodeVersionStartId()); + assertEquals(-1, retrieved.getFromNodeVersionEndId()); + assertEquals(-1, retrieved.getToNodeVersionEndId()); + + // create two new node versions in each of the nodes + List parents = new ArrayList<>(); + parents.add(firstNodeVersionId); + long fromEndId = CassandraTest.createNodeVersion(firstTestNodeId, parents).getId(); + + parents.clear(); + parents.add(fromEndId); + long newFirstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId, parents).getId(); + + parents.clear(); + parents.add(secondNodeVersionId); + long toEndId = CassandraTest.createNodeVersion(secondTestNodeId, parents).getNodeId(); + + parents.clear(); + parents.add(toEndId); + long newSecondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId, parents).getId(); + + parents.clear(); + parents.add(edgeVersionId); + long newEdgeVersionId = CassandraTest.createEdgeVersion(edgeId, newFirstNodeVersionId, newSecondNodeVersionId, parents).getId(); + + EdgeVersion parent = CassandraTest.edgeVersionDao.retrieveFromDatabase(edgeVersionId); + EdgeVersion child = CassandraTest.edgeVersionDao.retrieveFromDatabase(newEdgeVersionId); + + assertEquals(edgeId, child.getEdgeId()); + assertEquals(-1, (long) child.getStructureVersionId()); + assertEquals(null, child.getReference()); + assertEquals(newFirstNodeVersionId, child.getFromNodeVersionStartId()); + assertEquals(newSecondNodeVersionId, child.getToNodeVersionStartId()); + assertEquals(-1, child.getFromNodeVersionEndId()); + assertEquals(-1, child.getToNodeVersionEndId()); + + // Make sure that the end versions were set correctly + assertEquals(firstNodeVersionId, parent.getFromNodeVersionStartId()); + assertEquals(secondNodeVersionId, parent.getToNodeVersionStartId()); + assertEquals(fromEndId, parent.getFromNodeVersionEndId()); + assertEquals(toEndId, parent.getToNodeVersionEndId()); + } + + @Test(expected = GroundException.class) + public void testBadEdgeVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.edgeVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDaoTest.java new file mode 100644 index 00000000..ccefb796 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDaoTest.java @@ -0,0 +1,103 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Graph; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.junit.Test; + +public class CassandraGraphDaoTest extends CassandraTest { + + public CassandraGraphDaoTest() throws GroundException { + super(); + } + + + @Test + public void testGraphCreation() throws GroundException { + String testName = "test"; + String sourceKey = "testKey"; + + CassandraTest.graphDao.create(new Graph(0L, testName, sourceKey, new HashMap<>())); + Graph graph = CassandraTest.graphDao.retrieveFromDatabase(sourceKey); + + assertEquals(testName, graph.getName()); + assertEquals(sourceKey, graph.getSourceKey()); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadGraph() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.graphDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateGraph() throws GroundException { + String graphName = "graphName"; + String graphKey = "graphKey"; + + try { + CassandraTest.graphDao.create(new Graph(0L, graphName, graphKey, new HashMap<>())); + } catch (GroundException e) { + fail(e.getMessage()); + } + + CassandraTest.graphDao.create(new Graph(0L, graphName, graphKey, new HashMap<>())); + } + + @Test + public void testTruncate() throws GroundException { + long edgeVersionId = CassandraTest.createTwoNodesAndEdge(); + + List edgeVersionIds = new ArrayList<>(); + edgeVersionIds.add(edgeVersionId); + + String graphName = "testGraph"; + long graphId = CassandraTest.createGraph(graphName).getId(); + + long graphVersionId = CassandraTest.createGraphVersion(graphId, edgeVersionIds).getId(); + + List parents = new ArrayList<>(); + parents.add(graphVersionId); + long newGraphVersionId = CassandraTest.createGraphVersion(graphId, edgeVersionIds, parents).getId(); + + CassandraTest.graphDao.truncate(graphId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(graphId); + + assertEquals(1, dag.getEdgeIds().size()); + + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase(dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newGraphVersionId, successor.getToId()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDaoTest.java new file mode 100644 index 00000000..f77c7087 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDaoTest.java @@ -0,0 +1,118 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.GraphVersion; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraGraphVersionDaoTest extends CassandraTest { + + public CassandraGraphVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testGraphVersionCreation() throws GroundException { + long edgeVersionId = CassandraTest.createTwoNodesAndEdge(); + + List edgeVersionIds = new ArrayList<>(); + edgeVersionIds.add(edgeVersionId); + + String graphName = "testGraph"; + long graphId = CassandraTest.createGraph(graphName).getId(); + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + + GraphVersion graphVersion = new GraphVersion(0L, tags, structureVersionId, testReference, parameters, graphId, edgeVersionIds); + long graphVersionId = CassandraTest.graphVersionDao.create(graphVersion, new ArrayList<>()).getId(); + + GraphVersion retrieved = CassandraTest.graphVersionDao.retrieveFromDatabase(graphVersionId); + + assertEquals(graphId, retrieved.getGraphId()); + assertEquals(structureVersionId, (long) retrieved.getStructureVersionId()); + assertEquals(testReference, retrieved.getReference()); + assertEquals(edgeVersionIds.size(), retrieved.getEdgeVersionIds().size()); + + List retrievedEdgeVersionIds = retrieved.getEdgeVersionIds(); + + for (long id : edgeVersionIds) { + assert (retrievedEdgeVersionIds).contains(id); + } + + assertEquals(parameters.size(), retrieved.getParameters().size()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedParameters = retrieved.getParameters(); + Map retrievedTags = retrieved.getTags(); + + for (String key : parameters.keySet()) { + assert (retrievedParameters).containsKey(key); + assertEquals(parameters.get(key), retrievedParameters.get(key)); + } + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + } + } + + @Test + public void testCreateEmptyGraph() throws GroundException { + String graphName = "testGraph"; + long graphId = CassandraTest.createGraph(graphName).getId(); + + GraphVersion graphVersion = new GraphVersion(0L, new HashMap<>(), -1, null, + new HashMap<>(), graphId, new ArrayList<>()); + long graphVersionId = CassandraTest.graphVersionDao.create(graphVersion, new ArrayList<>()) + .getId(); + + GraphVersion retrieved = CassandraTest.graphVersionDao + .retrieveFromDatabase(graphVersionId); + + assertTrue(retrieved.getEdgeVersionIds().isEmpty()); + } + + @Test(expected = GroundException.class) + public void testBadGraphVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.graphVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDaoTest.java new file mode 100644 index 00000000..237d8c50 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDaoTest.java @@ -0,0 +1,160 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.Test; + +public class CassandraNodeDaoTest extends CassandraTest { + + public CassandraNodeDaoTest() throws GroundException { + super(); + } + + @Test + public void testNodeCreation() throws GroundException { + Map tagsMap = new HashMap<>(); + tagsMap.put("testtag", new Tag(1, "testtag", "tag", GroundType.STRING)); + + String testName = "test"; + String sourceKey = "testKey"; + + CassandraTest.nodeDao.create(new Node(0L, testName, sourceKey, tagsMap)); + + Node node = CassandraTest.nodeDao.retrieveFromDatabase(sourceKey); + assertEquals(testName, node.getName()); + assertEquals(tagsMap, node.getTags()); + assertEquals(sourceKey, node.getSourceKey()); + } + + @Test + public void testLeafRetrieval() throws GroundException { + String sourceKey = "testNode1"; + long nodeId = CassandraTest.createNode(sourceKey).getId(); + + long nodeVersionId = CassandraTest.createNodeVersion(nodeId).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(nodeId).getId(); + + List leaves = CassandraTest.nodeDao.getLeaves(sourceKey); + + assertTrue(leaves.contains(nodeVersionId)); + assertTrue(leaves.contains(secondNodeVersionId)); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadNode() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.nodeDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateNode() throws GroundException { + String nodeName = "nodeName"; + String nodeKey = "nodeKey"; + + try { + CassandraTest.nodeDao.create(new Node(0L, nodeName, nodeKey, new HashMap<>())); + } catch (GroundException e) { + fail(e.getMessage()); + } + + CassandraTest.nodeDao.create(new Node(0L, nodeName, nodeKey, new HashMap<>())); + } + + @Test + public void testTruncation() throws GroundException { + String testNode = "testNode"; + long testNodeId = CassandraTest.createNode(testNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(testNodeId).getId(); + + List parents = new ArrayList<>(); + parents.add(firstNodeVersionId); + long newNodeVersionId = CassandraTest.createNodeVersion(testNodeId, parents).getId(); + + CassandraTest.nodeDao.truncate(testNodeId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao + .retrieveFromDatabase(testNodeId); + assertEquals(1, dag.getEdgeIds().size()); + + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newNodeVersionId, successor.getToId()); + } + + @Test + public void testBranchTruncation() throws GroundException { + String testNode = "testNode"; + long testNodeId = CassandraTest.createNode(testNode).getId(); + long originalId = CassandraTest.createNodeVersion(testNodeId).getId(); + + List parents = new ArrayList<>(); + parents.add(originalId); + long firstParentId = CassandraTest.createNodeVersion(testNodeId, parents).getId(); + long secondParentId = CassandraTest.createNodeVersion(testNodeId, parents).getId(); + + parents.clear(); + parents.add(firstParentId); + parents.add(secondParentId); + long childId = CassandraTest.createNodeVersion(testNodeId, parents).getId(); + + CassandraTest.nodeDao.truncate(testNodeId, 2); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao + .retrieveFromDatabase(testNodeId); + + assertEquals(4, dag.getEdgeIds().size()); + + Set> correctSuccessors = new HashSet<>(); + correctSuccessors.add(Arrays.asList(0L, firstParentId)); + correctSuccessors.add(Arrays.asList(0L, secondParentId)); + correctSuccessors.add(Arrays.asList(firstParentId, childId)); + correctSuccessors.add(Arrays.asList(secondParentId, childId)); + + for (long successorId : dag.getEdgeIds()) { + VersionSuccessor successor = CassandraTest.versionSuccessorDao + .retrieveFromDatabase(successorId); + correctSuccessors.remove(Arrays.asList(successor.getFromId(), successor.getToId())); + } + + assertTrue(correctSuccessors.isEmpty()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDaoTest.java new file mode 100644 index 00000000..bb227b22 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDaoTest.java @@ -0,0 +1,94 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.NodeVersion; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraNodeVersionDaoTest extends CassandraTest { + + public CassandraNodeVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testNodeVersionCreation() throws GroundException { + String nodeName = "testNode"; + long nodeId = CassandraTest.createNode(nodeName).getId(); + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + + NodeVersion nodeVersion = new NodeVersion(0L, tags, structureVersionId, testReference, parameters, nodeId); + long nodeVersionId = CassandraTest.nodeVersionDao.create(nodeVersion, new ArrayList<>()).getId(); + + NodeVersion retrieved = CassandraTest.nodeVersionDao.retrieveFromDatabase(nodeVersionId); + + assertEquals(nodeId, retrieved.getNodeId()); + assertEquals(structureVersionId, (long) retrieved.getStructureVersionId()); + assertEquals(testReference, retrieved.getReference()); + + assertEquals(parameters.size(), retrieved.getParameters().size()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedParameters = retrieved.getParameters(); + Map retrievedTags = retrieved.getTags(); + + for (String key : parameters.keySet()) { + assert (retrievedParameters).containsKey(key); + assertEquals(parameters.get(key), retrievedParameters.get(key)); + } + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + } + + List leaves = CassandraTest.nodeDao.getLeaves(nodeName); + + assertTrue(leaves.contains(nodeVersionId)); + assertTrue(1 == leaves.size()); + } + + @Test(expected = GroundException.class) + public void testBadNodeVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.nodeVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDaoTest.java new file mode 100644 index 00000000..12781e0e --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDaoTest.java @@ -0,0 +1,128 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; + +public class CassandraRichVersionDaoTest extends CassandraTest { + + public CassandraRichVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testReference() throws GroundException { + long id = 1; + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + parameters.put("ftp", "test"); + + RichVersion richVersion = new RichVersion(id, new HashMap(), -1L, testReference, + parameters); + CassandraTest.cassandraRichVersionDao.create(richVersion, new ArrayList<>()); + + RichVersion retrieved = CassandraTest.cassandraRichVersionDao.retrieveFromDatabase(id); + + assertEquals(id, retrieved.getId()); + assertEquals(testReference, retrieved.getReference()); + + Map retrievedParams = retrieved.getParameters(); + for (String key : parameters.keySet()) { + assert (retrievedParams).containsKey(key); + assertEquals(parameters.get(key), retrievedParams.get(key)); + } + } + + @Test + public void testTags() throws GroundException { + long id = 1; + + Map tags = new HashMap<>(); + tags.put("justkey", new Tag(-1, "justkey", null, null)); + tags.put("withintvalue", new Tag(-1, "withintvalue", 1, GroundType.INTEGER)); + tags.put("withstringvalue", new Tag(-1, "withstringvalue", "1", GroundType.STRING)); + tags.put("withboolvalue", new Tag(-1, "withboolvalue", true, GroundType.BOOLEAN)); + + RichVersion richVersion = new RichVersion(id, tags, -1L, null, new HashMap<>()); + CassandraTest.cassandraRichVersionDao.create(richVersion, new ArrayList<>()); + + RichVersion retrieved = CassandraTest.cassandraRichVersionDao.retrieveFromDatabase(id); + + assertEquals(id, retrieved.getId()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedTags = retrieved.getTags(); + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + assertEquals(retrieved.getId(), retrievedTags.get(key).getId()); + } + } + + @Test + public void testStructureVersionConformation() throws GroundException { + long id = 10; + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + RichVersion richVersion = new RichVersion(id, tags, structureVersionId, null, + new HashMap<>()); + CassandraTest.cassandraRichVersionDao.create(richVersion, new ArrayList<>()); + + RichVersion retrieved = CassandraTest.cassandraRichVersionDao.retrieveFromDatabase(id); + assertEquals((long) retrieved.getStructureVersionId(), structureVersionId); + } + + @Test(expected = GroundException.class) + public void testStructureVersionFails() throws GroundException { + long structureVersionId = -1; + long id = 1; + + // none of these operations should fail + try { + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + } catch (GroundException ge) { + fail(ge.getMessage()); + } + + Map tags = new HashMap<>(); + tags.put("intfield", new Tag(-1, "intfield", 1, GroundType.INTEGER)); + tags.put("intfield", new Tag(-1, "strfield", "1", GroundType.STRING)); + tags.put("intfield", new Tag(-1, "boolfield", true, GroundType.BOOLEAN)); + + // this should fail + RichVersion richVersion = new RichVersion(id, tags, structureVersionId, null, + new HashMap<>()); + CassandraTest.cassandraRichVersionDao.create(richVersion, new ArrayList<>()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDaoTest.java new file mode 100644 index 00000000..6aad1acd --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDaoTest.java @@ -0,0 +1,118 @@ +package edu.berkeley.ground.cassandra.dao.core; + +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Structure; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.junit.Test; + +public class CassandraStructureDaoTest extends CassandraTest { + + public CassandraStructureDaoTest() throws GroundException { + super(); + } + + + @Test + public void testStructureCreation() throws GroundException { + String testName = "test"; + String sourceKey = "testKey"; + + Structure insertStructure = new Structure(0L, testName, sourceKey, new HashMap<>()); + + CassandraTest.structureDao.create(insertStructure); + Structure structure = CassandraTest.structureDao.retrieveFromDatabase(sourceKey); + + assertEquals(testName, structure.getName()); + assertEquals(sourceKey, structure.getSourceKey()); + } + + @Test + public void testLeafRetrieval() throws GroundException { + String sourceKey = "testStructure"; + long structureId = CassandraTest.createStructure(sourceKey).getId(); + + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + long secondStructureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + List leaves = CassandraTest.structureDao.getLeaves(sourceKey); + + assertTrue(leaves.contains(structureVersionId)); + assertTrue(leaves.contains(secondStructureVersionId)); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadStructure() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.structureDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateStructure() throws GroundException { + String structureName = "structureName"; + String structureKey = "structureKey"; + + try { + Structure structure = new Structure(0L, structureName, structureKey, new HashMap<>()); + CassandraTest.structureDao.create(structure); + } catch (GroundException e) { + fail(e.getMessage()); + } + + Structure sameStructure = new Structure(0L, structureName, structureKey, new HashMap<>()); + CassandraTest.structureDao.create(sameStructure); + } + + + @Test + public void testTruncate() throws GroundException { + String structureName = "testStructure1"; + long structureId = CassandraTest.createStructure(structureName).getId(); + + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + List parents = new ArrayList<>(); + parents.add(structureVersionId); + long newStructureVersionId = CassandraTest.createStructureVersion(structureId, parents).getId(); + + CassandraTest.structureDao.truncate(structureId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(structureId); + + assertEquals(1, dag.getEdgeIds().size()); + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newStructureVersionId, successor.getToId()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDaoTest.java new file mode 100644 index 00000000..213fb083 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDaoTest.java @@ -0,0 +1,74 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertEquals; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.StructureVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; + +public class CassandraStructureVersionDaoTest extends CassandraTest { + + public CassandraStructureVersionDaoTest() throws GroundException { + super(); + } + + + @Test + public void testStructureVersionCreation() throws GroundException { + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + + Map structureVersionAttributes = new HashMap<>(); + structureVersionAttributes.put("intfield", GroundType.INTEGER); + structureVersionAttributes.put("boolfield", GroundType.BOOLEAN); + structureVersionAttributes.put("strfield", GroundType.STRING); + + StructureVersion structureVersion = new StructureVersion(0L, structureId, + structureVersionAttributes); + long structureVersionId = CassandraTest.structureVersionDao + .create(structureVersion, new ArrayList<>()).getId(); + + StructureVersion retrieved = CassandraTest.structureVersionDao + .retrieveFromDatabase(structureVersionId); + + assertEquals(structureId, retrieved.getStructureId()); + Map retrievedAttributes = retrieved.getAttributes(); + + for (String key : structureVersionAttributes.keySet()) { + assert (retrievedAttributes).containsKey(key); + assertEquals(structureVersionAttributes.get(key), retrievedAttributes.get(key)); + } + } + + @Test(expected = GroundException.class) + public void testBadStructureVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.structureVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraTagDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraTagDaoTest.java new file mode 100644 index 00000000..e5e3b953 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/core/CassandraTagDaoTest.java @@ -0,0 +1,69 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package edu.berkeley.ground.cassandra.dao.core; + +import static org.junit.Assert.assertTrue; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.Node; +import edu.berkeley.ground.common.model.core.NodeVersion; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraTagDaoTest extends CassandraTest { + + public CassandraTagDaoTest() throws GroundException { + super(); + } + + @Test + public void testGetItemIdsByTag() throws GroundException { + Map tagsMap = new HashMap<>(); + tagsMap.put("testtag", new Tag(1, "testtag", "tag", GroundType.STRING)); + + long nodeId1 = CassandraTest.nodeDao.create(new Node(0L, null, "test1", tagsMap)).getId(); + long nodeId2 = CassandraTest.nodeDao.create(new Node(0L, null, "test2", tagsMap)).getId(); + + List ids = CassandraTest.tagDao.getItemIdsByTag("testtag"); + + assertTrue(ids.contains(nodeId1)); + assertTrue(ids.contains(nodeId2)); + } + + @Test + public void testGetVersionIdsByTag() throws GroundException { + Map tagsMap = new HashMap<>(); + tagsMap.put("testtag", new Tag(1, "testtag", "tag", GroundType.STRING)); + + long nodeId = CassandraTest.createNode("testNode").getId(); + + NodeVersion nodeVersion1 = new NodeVersion(0L, tagsMap, -1, null, new HashMap<>(), nodeId); + long nodeVersionId1 = CassandraTest.nodeVersionDao.create(nodeVersion1, new ArrayList<>()) + .getId(); + NodeVersion nodeVersion2 = new NodeVersion(0L, tagsMap, -1, null, new HashMap<>(), nodeId); + long nodeVersionId2 = CassandraTest.nodeVersionDao.create(nodeVersion2, new ArrayList<>()) + .getId(); + + List ids = CassandraTest.tagDao.getVersionIdsByTag("testtag"); + + assertTrue(ids.contains(nodeVersionId1)); + assertTrue(ids.contains(nodeVersionId2)); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDaoTest.java new file mode 100644 index 00000000..d2a06585 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDaoTest.java @@ -0,0 +1,99 @@ +package edu.berkeley.ground.cassandra.dao.usage; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageEdge; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.junit.Test; + +public class CassandraLineageEdgeDaoTest extends CassandraTest { + + public CassandraLineageEdgeDaoTest() throws GroundException { + super(); + } + + @Test + public void testLineageEdgeCreation() throws GroundException { + String testName = "test"; + String sourceKey = "testKey"; + + LineageEdge insertLineageEdge = new LineageEdge(0L, testName, sourceKey, new HashMap<>()); + CassandraTest.lineageEdgeDao.create(insertLineageEdge); + LineageEdge lineageEdge = CassandraTest.lineageEdgeDao.retrieveFromDatabase(sourceKey); + + assertEquals(testName, lineageEdge.getName()); + assertEquals(sourceKey, lineageEdge.getSourceKey()); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadLineageEdge() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.lineageEdgeDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateLineageEdge() throws GroundException { + String lineageEdgeName = "lineageEdgeName"; + String lineageEdgeKey = "lineageEdgeKey"; + + try { + LineageEdge lineageEdge = new LineageEdge(0L, lineageEdgeName, lineageEdgeKey, + new HashMap<>()); + CassandraTest.lineageEdgeDao.create(lineageEdge); + } catch (GroundException e) { + fail(e.getMessage()); + } + + LineageEdge duplicateEdge = new LineageEdge(0L, lineageEdgeName, lineageEdgeKey, + new HashMap<>()); + CassandraTest.lineageEdgeDao.create(duplicateEdge); + } + + @Test + public void testTruncate() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String lineageEdgeName = "testLineageEdge"; + long lineageEdgeId = CassandraTest.createLineageEdge(lineageEdgeName).getId(); + long lineageEdgeVersionId = CassandraTest.createLineageEdgeVersion(lineageEdgeId, + firstNodeVersionId, secondNodeVersionId).getId(); + + List parents = new ArrayList<>(); + parents.add(lineageEdgeVersionId); + long newLineageEdgeVersionId = CassandraTest.createLineageEdgeVersion(lineageEdgeId, + firstNodeVersionId, secondNodeVersionId, parents).getId(); + + CassandraTest.lineageEdgeDao.truncate(lineageEdgeId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao + .retrieveFromDatabase(lineageEdgeId); + + assertEquals(1, dag.getEdgeIds().size()); + + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newLineageEdgeVersionId, successor.getToId()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDaoTest.java new file mode 100644 index 00000000..94e465b0 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDaoTest.java @@ -0,0 +1,88 @@ +package edu.berkeley.ground.cassandra.dao.usage; + +import static org.junit.Assert.assertEquals; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageEdgeVersion; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; + +public class CassandraLineageEdgeVersionDaoTest extends CassandraTest { + + public CassandraLineageEdgeVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testLineageEdgeVersionCreation() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String lineageEdgeName = "testLineageEdge"; + long lineageEdgeId = CassandraTest.createLineageEdge(lineageEdgeName).getId(); + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + + LineageEdgeVersion lineageEdgeVersion = new LineageEdgeVersion(0L, tags, structureVersionId, + testReference, parameters, firstNodeVersionId, + secondNodeVersionId, lineageEdgeId); + + long lineageEdgeVersionId = CassandraTest.lineageEdgeVersionDao + .create(lineageEdgeVersion, new ArrayList<>()).getId(); + + LineageEdgeVersion retrieved = CassandraTest.lineageEdgeVersionDao + .retrieveFromDatabase(lineageEdgeVersionId); + + assertEquals(lineageEdgeId, retrieved.getLineageEdgeId()); + assertEquals(structureVersionId, (long) retrieved.getStructureVersionId()); + assertEquals(testReference, retrieved.getReference()); + assertEquals(retrieved.getFromId(), firstNodeVersionId); + assertEquals(retrieved.getToId(), secondNodeVersionId); + + assertEquals(parameters.size(), retrieved.getParameters().size()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedParameters = retrieved.getParameters(); + Map retrievedTags = retrieved.getTags(); + + for (String key : parameters.keySet()) { + assert (retrievedParameters).containsKey(key); + assertEquals(parameters.get(key), retrievedParameters.get(key)); + } + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + } + } + + @Test(expected = GroundException.class) + public void testBadLineageEdgeVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.lineageEdgeVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDaoTest.java new file mode 100644 index 00000000..0889a84c --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDaoTest.java @@ -0,0 +1,104 @@ +package edu.berkeley.ground.cassandra.dao.usage; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageGraph; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import org.junit.Test; + +public class CassandraLineageGraphDaoTest extends CassandraTest { + + public CassandraLineageGraphDaoTest() throws GroundException { + super(); + } + + @Test + public void testLineageGraphCreation() throws GroundException { + String testName = "test"; + String sourceKey = "testKey"; + + LineageGraph lineageGraph = new LineageGraph(0L, testName, sourceKey, new HashMap<>()); + CassandraTest.lineageGraphDao.create(lineageGraph); + LineageGraph graph = CassandraTest.lineageGraphDao.retrieveFromDatabase(sourceKey); + + assertEquals(testName, graph.getName()); + assertEquals(sourceKey, graph.getSourceKey()); + } + + @Test(expected = GroundException.class) + public void testRetrieveBadLineageGraph() throws GroundException { + String sourceKey = "test"; + + try { + CassandraTest.lineageGraphDao.retrieveFromDatabase(sourceKey); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test(expected = GroundException.class) + public void testCreateDuplicateLineageGraph() throws GroundException { + String lineageGraphName = "lineageGraphName"; + String lineageGraphKey = "lineageGraphKey"; + + try { + LineageGraph lineageGraph = new LineageGraph(0L, lineageGraphName, lineageGraphKey, + new HashMap<>()); + CassandraTest.lineageGraphDao.create(lineageGraph); + } catch (GroundException e) { + fail(e.getMessage()); + } + + LineageGraph duplicateGraph = new LineageGraph(0L, lineageGraphName, lineageGraphKey, + new HashMap<>()); + CassandraTest.lineageGraphDao.create(duplicateGraph); + } + + @Test + public void testTruncate() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String lineageEdgeName = "testLineageEdge"; + long lineageEdgeId = CassandraTest.createLineageEdge(lineageEdgeName).getId(); + long lineageEdgeVersionId = CassandraTest.createLineageEdgeVersion(lineageEdgeId, firstNodeVersionId, secondNodeVersionId).getId(); + + List lineageEdgeVersionIds = new ArrayList<>(); + lineageEdgeVersionIds.add(lineageEdgeVersionId); + + String lineageGraphName = "testLineageGraph"; + long lineageGraphId = CassandraTest.createLineageGraph(lineageGraphName).getId(); + long lineageGraphVersionId = CassandraTest.createLineageGraphVersion(lineageGraphId, lineageEdgeVersionIds).getId(); + + List parents = new ArrayList<>(); + parents.add(lineageGraphVersionId); + long newLineageGraphVersionId = CassandraTest.createLineageGraphVersion(lineageGraphId, lineageEdgeVersionIds, parents).getId(); + + CassandraTest.lineageGraphDao.truncate(lineageGraphId, 1); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao + .retrieveFromDatabase(lineageGraphId); + + assertEquals(1, dag.getEdgeIds().size()); + + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(newLineageGraphVersionId, successor.getToId()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDaoTest.java new file mode 100644 index 00000000..e5c3e838 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDaoTest.java @@ -0,0 +1,116 @@ +package edu.berkeley.ground.cassandra.dao.usage; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.usage.LineageGraphVersion; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraLineageGraphVersionDaoTest extends CassandraTest { + + public CassandraLineageGraphVersionDaoTest() throws GroundException { + super(); + } + + @Test + public void testLineageGraphVersionCreation() throws GroundException { + String firstTestNode = "firstTestNode"; + long firstTestNodeId = CassandraTest.createNode(firstTestNode).getId(); + long firstNodeVersionId = CassandraTest.createNodeVersion(firstTestNodeId).getId(); + + String secondTestNode = "secondTestNode"; + long secondTestNodeId = CassandraTest.createNode(secondTestNode).getId(); + long secondNodeVersionId = CassandraTest.createNodeVersion(secondTestNodeId).getId(); + + String lineageEdgeName = "testLineageEdge"; + long lineageEdgeId = CassandraTest.createLineageEdge(lineageEdgeName).getId(); + + long lineageEdgeVersionId = CassandraTest.createLineageEdgeVersion(lineageEdgeId, + firstNodeVersionId, secondNodeVersionId).getId(); + + List lineageEdgeVersionIds = new ArrayList<>(); + lineageEdgeVersionIds.add(lineageEdgeVersionId); + + String lineageGraphName = "testLineageGraph"; + long lineageGraphId = CassandraTest.createLineageGraph(lineageGraphName).getId(); + + String structureName = "testStructure"; + long structureId = CassandraTest.createStructure(structureName).getId(); + long structureVersionId = CassandraTest.createStructureVersion(structureId).getId(); + + Map tags = CassandraTest.createTags(); + + String testReference = "http://www.google.com"; + Map parameters = new HashMap<>(); + parameters.put("http", "GET"); + + long lineageGraphVersionId = CassandraTest.lineageGraphVersionDao + .create(new LineageGraphVersion(0L, tags, structureVersionId, testReference, parameters, + lineageGraphId, + lineageEdgeVersionIds), new ArrayList<>()).getId(); + + LineageGraphVersion retrieved = CassandraTest.lineageGraphVersionDao + .retrieveFromDatabase(lineageGraphVersionId); + + assertEquals(lineageGraphId, retrieved.getLineageGraphId()); + assertEquals(structureVersionId, (long) retrieved.getStructureVersionId()); + assertEquals(testReference, retrieved.getReference()); + assertEquals(lineageEdgeVersionIds.size(), retrieved.getLineageEdgeVersionIds().size()); + + List retrievedLineageEdgeVersionIds = retrieved.getLineageEdgeVersionIds(); + + for (long id : lineageEdgeVersionIds) { + assert (retrievedLineageEdgeVersionIds).contains(id); + } + + assertEquals(parameters.size(), retrieved.getParameters().size()); + assertEquals(tags.size(), retrieved.getTags().size()); + + Map retrievedParameters = retrieved.getParameters(); + Map retrievedTags = retrieved.getTags(); + + for (String key : parameters.keySet()) { + assert (retrievedParameters).containsKey(key); + assertEquals(parameters.get(key), retrievedParameters.get(key)); + } + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + } + } + + @Test(expected = GroundException.class) + public void testBadLineageGraphVersion() throws GroundException { + long id = 1; + + try { + CassandraTest.lineageGraphVersionDao.retrieveFromDatabase(id); + } catch (GroundException e) { + assertEquals(GroundException.class, e.getClass()); + + throw e; + } + } + + @Test + public void testCreateEmptyLineageGraph() throws GroundException { + String lineageGraphName = "testGraph"; + long lineageGraphId = CassandraTest.createLineageGraph(lineageGraphName).getId(); + + long lineageGraphVersionId = CassandraTest.createLineageGraphVersion(lineageGraphId, + new ArrayList<>()).getId(); + + LineageGraphVersion retrieved = CassandraTest.lineageGraphVersionDao + .retrieveFromDatabase(lineageGraphVersionId); + + assertTrue(retrieved.getLineageEdgeVersionIds().isEmpty()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraItemDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraItemDaoTest.java new file mode 100644 index 00000000..fd712204 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraItemDaoTest.java @@ -0,0 +1,258 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.version; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.version.GroundType; +import edu.berkeley.ground.common.model.version.Item; +import edu.berkeley.ground.common.model.version.Tag; +import edu.berkeley.ground.common.model.version.Version; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class CassandraItemDaoTest extends CassandraTest { + + public CassandraItemDaoTest() throws GroundException { + super(); + } + + @Test + public void testCorrectUpdateWithParent() throws GroundException { + long testId = 1; + + Item item = new Item(testId, new HashMap<>()); + CassandraTest.cassandraItemDao.create(item); + + long fromId = 2; + long toId = 3; + + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(fromId))); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(toId))); + + List parentIds = new ArrayList<>(); + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, fromId, parentIds)); + + parentIds.clear(); + parentIds.add(fromId); + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, toId, parentIds)); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(testId); + + assertEquals(2, dag.getEdgeIds().size()); + assertEquals(toId, (long) dag.getLeaves().get(0)); + + VersionSuccessor successor = null; + for (long id : dag.getEdgeIds()) { + successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase(id); + + if (successor.getFromId() != 0) { + break; + } + } + + if (successor != null) { + assertEquals(fromId, successor.getFromId()); + assertEquals(toId, successor.getToId()); + + return; + } + + fail(); + } + + @Test + public void testCorrectUpdateWithoutParent() throws GroundException { + long testId = 1; + + CassandraTest.cassandraItemDao.create(new Item(testId, new HashMap<>())); + long toId = 2; + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(toId))); + + List parentIds = new ArrayList<>(); + + // No parent is specified, and there is no other version in this Item, we should + // automatically make this a child of EMPTY + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, toId, parentIds)); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(testId); + + assertEquals(1, dag.getEdgeIds().size()); + assertEquals(toId, (long) dag.getLeaves().get(0)); + + VersionSuccessor successor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + assertEquals(0, successor.getFromId()); + assertEquals(toId, successor.getToId()); + } + + @Test + public void testCorrectUpdateWithLinearHistory() throws GroundException { + long testId = 1; + + CassandraTest.cassandraItemDao.create(new Item(testId, new HashMap<>())); + + long fromId = 2; + long toId = 3; + + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(fromId))); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(toId))); + List parentIds = new ArrayList<>(); + + // first, make from a child of EMPTY + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, fromId, parentIds)); + + // then, add to as a child and make sure that it becomes a child of from + parentIds.clear(); + parentIds.add(fromId); + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, toId, parentIds)); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(testId); + + assertEquals(2, dag.getEdgeIds().size()); + assertEquals(toId, (long) dag.getLeaves().get(0)); + + VersionSuccessor fromSuccessor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + VersionSuccessor toSuccessor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(1)); + + if (fromSuccessor.getFromId() != 0) { + VersionSuccessor tmp = fromSuccessor; + fromSuccessor = toSuccessor; + toSuccessor = tmp; + } + + assertEquals(0, fromSuccessor.getFromId()); + assertEquals(fromId, fromSuccessor.getToId()); + + assertEquals(fromId, toSuccessor.getFromId()); + assertEquals(toId, toSuccessor.getToId()); + } + + @Test(expected = GroundException.class) + public void testIncorrectUpdate() throws GroundException { + long testId = 1; + long fromId = 2; + long toId = 3; + + try { + CassandraTest.cassandraItemDao.create(new Item(testId, new HashMap<>())); + + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(toId))); + } catch (GroundException ge) { + fail(ge.getMessage()); + } + + List parentIds = new ArrayList<>(); + parentIds.add(fromId); + + // this should fail because fromId is not a valid version + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, toId, parentIds)); + } + + @Test + public void testMultipleParents() throws GroundException { + long testId = 1; + + CassandraTest.cassandraItemDao.create(new Item(testId, new HashMap<>())); + + long parentOne = 2; + long parentTwo = 3; + long child = 4; + + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(parentOne))); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(parentTwo))); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(child))); + List parentIds = new ArrayList<>(); + + // first, make the parents children of EMPTY) + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, parentOne, parentIds)); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, parentTwo, parentIds)); + + // then, add to as a child and make sure that it becomes a child of from + parentIds.clear(); + parentIds.add(parentOne); + parentIds.add(parentTwo); + CassandraUtils.executeCqlList(dbSource, (CassandraStatements) CassandraTest.cassandraItemDao.update(testId, child, parentIds)); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(testId); + + assertEquals(4, dag.getEdgeIds().size()); + assertEquals(child, (long) dag.getLeaves().get(0)); + + // Retrieve all the version successors and check that they have the correct data. + VersionSuccessor parentOneSuccessor = CassandraTest.versionSuccessorDao + .retrieveFromDatabase( + dag.getEdgeIds().get(0)); + + VersionSuccessor parentTwoSuccessor = CassandraTest.versionSuccessorDao + .retrieveFromDatabase( + dag.getEdgeIds().get(1)); + + VersionSuccessor childOneSuccessor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(2)); + + VersionSuccessor childTwoSuccessor = CassandraTest.versionSuccessorDao.retrieveFromDatabase( + dag.getEdgeIds().get(3)); + + assertEquals(0, parentOneSuccessor.getFromId()); + assertEquals(parentOne, parentOneSuccessor.getToId()); + + assertEquals(0, parentTwoSuccessor.getFromId()); + assertEquals(parentTwo, parentTwoSuccessor.getToId()); + + assertEquals(parentOne, childOneSuccessor.getFromId()); + assertEquals(child, childOneSuccessor.getToId()); + + assertEquals(parentTwo, childTwoSuccessor.getFromId()); + assertEquals(child, childTwoSuccessor.getToId()); + assertEquals(child, childTwoSuccessor.getToId()); + } + + @Test + public void testTags() throws GroundException { + long testId = 1; + Map tags = new HashMap<>(); + tags.put("justkey", new Tag(testId, "justkey", null, null)); + tags.put("withintvalue", new Tag(testId, "withintvalue", 1, GroundType.INTEGER)); + tags.put("withstringvalue", new Tag(testId, "withstringvalue", "1", GroundType.STRING)); + tags.put("withboolvalue", new Tag(testId, "withboolvalue", true, GroundType.BOOLEAN)); + + long itemId = CassandraTest.cassandraItemDao.create(new Item(testId, tags)).getId(); + + Map retrievedTags = CassandraTest.tagDao.retrieveFromDatabaseByItemId(itemId); + + assertEquals(tags.size(), retrievedTags.size()); + + for (String key : tags.keySet()) { + assert (retrievedTags).containsKey(key); + assertEquals(tags.get(key), retrievedTags.get(key)); + assertEquals(itemId, retrievedTags.get(key).getId()); + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDaoTest.java new file mode 100644 index 00000000..e2f25560 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDaoTest.java @@ -0,0 +1,39 @@ +package edu.berkeley.ground.cassandra.dao.version; + +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import static org.junit.Assert.assertEquals; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.version.VersionHistoryDag; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import org.junit.Test; + +public class CassandraVersionHistoryDagDaoTest extends CassandraTest { + + public CassandraVersionHistoryDagDaoTest() throws GroundException { + super(); + } + + @Test + public void testVersionHistoryDAGCreation() throws GroundException { + long testId = 1; + CassandraTest.versionHistoryDagDao.create(testId); + + VersionHistoryDag dag = CassandraTest.versionHistoryDagDao.retrieveFromDatabase(testId); + + assertEquals(0, dag.getEdgeIds().size()); + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java new file mode 100644 index 00000000..5b025cd2 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java @@ -0,0 +1,89 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package edu.berkeley.ground.cassandra.dao.version; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.version.Version; +import edu.berkeley.ground.common.model.version.VersionSuccessor; +import edu.berkeley.ground.cassandra.dao.CassandraTest; +import edu.berkeley.ground.cassandra.util.CassandraStatements; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import org.junit.Test; +import play.Logger; // Andre - unnecessary + +public class CassandraVersionSuccessorDaoTest extends CassandraTest { + + public CassandraVersionSuccessorDaoTest() throws GroundException { + super(); + } + + @Test + public void testVersionSuccessorCreation() throws GroundException { + long fromId = 1; + long toId = 2; + + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(fromId))); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.cassandraVersionDao.insert(new Version(toId))); + + VersionSuccessor successor = ((CassandraVersionSuccessorDao) CassandraTest.versionSuccessorDao).instantiateVersionSuccessor(fromId, toId); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.versionSuccessorDao.insert(successor)); + + VersionSuccessor retrieved = CassandraTest.versionSuccessorDao.retrieveFromDatabase(successor.getId()); + + assertEquals(fromId, retrieved.getFromId()); + assertEquals(toId, retrieved.getToId()); + } + + @Test(expected = GroundException.class) + public void testBadVersionSuccessorCreation() throws GroundException { + Logger.debug("\n\n\nBEGINNING TEST\n"); + + long fromId = 123; + long toId = 456; + + Logger.debug("A"); + // Catch exceptions for these two lines because they should not fal + try { + // the main difference is that we're not creating a Version for the toId + CassandraTest.cassandraVersionDao.insert(new Version(fromId)); + } catch (GroundException ge) { + fail(ge.getMessage()); + } + Logger.debug("B"); + + // This statement should cause a GroundException because toId is not in the database + VersionSuccessor successor = ((CassandraVersionSuccessorDao) CassandraTest.versionSuccessorDao).instantiateVersionSuccessor(fromId, toId); + Logger.debug("C"); + CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.versionSuccessorDao.insert(successor)); + Logger.debug("D"); + } + + @Test(expected = GroundException.class) + public void testBadVersionSuccessorRetrieval() throws GroundException { + try { + CassandraTest.versionSuccessorDao.retrieveFromDatabase(10); + } catch (GroundException e) { + + if (!e.getMessage().contains("Version Successor with id 10 does not exist.")) { + fail(); + } + + throw e; + } + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraItemDao.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraItemDao.java new file mode 100644 index 00000000..fe759d29 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraItemDao.java @@ -0,0 +1,40 @@ +package edu.berkeley.ground.cassandra.dao.version.mock; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.exception.GroundException.ExceptionType; +import edu.berkeley.ground.common.model.version.Item; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; +import edu.berkeley.ground.cassandra.dao.version.CassandraTagDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +// import play.db.Database; + +public class TestCassandraItemDao extends CassandraItemDao { + + public TestCassandraItemDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public Class getType() { + return Item.class; + } + + @Override + public Item retrieveFromDatabase(long id) throws GroundException { + return new Item(id, new CassandraTagDao(dbSource).retrieveFromDatabaseByItemId(id)); + } + + @Override + public Item retrieveFromDatabase(String sourceKey) throws GroundException { + throw new GroundException(ExceptionType.OTHER, "This method should never be called."); + } + + @Override + public Item create(Item item) throws GroundException { + CassandraUtils.executeCqlList(this.dbSource, this.insert(new Item(item.getId(), item.getTags()))); + + return item; + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraRichVersionDao.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraRichVersionDao.java new file mode 100644 index 00000000..ac8085a2 --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraRichVersionDao.java @@ -0,0 +1,29 @@ +package edu.berkeley.ground.cassandra.dao.version.mock; + +import edu.berkeley.ground.common.exception.GroundException; +import edu.berkeley.ground.common.model.core.RichVersion; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.core.CassandraRichVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.List; +// import play.db.Database; + +public class TestCassandraRichVersionDao extends CassandraRichVersionDao { + + public TestCassandraRichVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + @Override + public RichVersion create(RichVersion richVersion, List parents) throws GroundException { + CassandraUtils.executeCqlList(this.dbSource, super.insert(richVersion)); + + return richVersion; + } + + @Override + public Class getType() { + return RichVersion.class; + } +} diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraVersionDao.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraVersionDao.java new file mode 100644 index 00000000..c80da51b --- /dev/null +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/mock/TestCassandraVersionDao.java @@ -0,0 +1,23 @@ +package edu.berkeley.ground.cassandra.dao.version.mock; + +import edu.berkeley.ground.common.model.version.Version; +import edu.berkeley.ground.common.util.IdGenerator; +import edu.berkeley.ground.cassandra.dao.version.CassandraVersionDao; +import edu.berkeley.ground.cassandra.util.CassandraDatabase; +// import play.db.Database; + +public class TestCassandraVersionDao extends CassandraVersionDao { + + public TestCassandraVersionDao(CassandraDatabase dbSource, IdGenerator idGenerator) { + super(dbSource, idGenerator); + } + + public Class getType() { + return Version.class; + } + + @Override + public Version retrieveFromDatabase(long id) { + return new Version(id); + } +} diff --git a/resources/scripts/cassandra/cassandra.cql b/resources/scripts/cassandra/cassandra.cql index a5448811..4a80153f 100644 --- a/resources/scripts/cassandra/cassandra.cql +++ b/resources/scripts/cassandra/cassandra.cql @@ -115,10 +115,10 @@ CREATE TABLE IF NOT EXISTS node_version ( CREATE TABLE IF NOT EXISTS edge_version ( id bigint PRIMARY KEY, edge_id bigint, - from_node_start_id bigint, - from_node_end_id bigint, - to_node_start_id bigint, - to_node_end_id bigint + from_node_version_start_id bigint, + from_node_version_end_id bigint, + to_node_version_start_id bigint, + to_node_version_end_id bigint ); CREATE TABLE IF NOT EXISTS graph_version ( From c754ff0c2c77509ab21fc9e7fb9f6d4e53ec2f1e Mon Sep 17 00:00:00 2001 From: Andre Askari Date: Wed, 16 Aug 2017 13:49:45 -0700 Subject: [PATCH 2/5] All tests should be passing --- .../cassandra/controllers/EdgeController.java | 1 - .../controllers/GraphController.java | 1 - .../controllers/LineageEdgeController.java | 1 - .../controllers/LineageGraphController.java | 1 - .../cassandra/controllers/NodeController.java | 1 - .../controllers/StructureController.java | 1 - .../ground/cassandra/dao/CqlConstants2.java | 89 ------------------- .../cassandra/dao/core/CassandraEdgeDao.java | 2 +- .../dao/core/CassandraEdgeVersionDao.java | 12 +-- .../cassandra/dao/core/CassandraGraphDao.java | 3 +- .../dao/core/CassandraGraphVersionDao.java | 8 +- .../cassandra/dao/core/CassandraNodeDao.java | 5 +- .../dao/core/CassandraNodeVersionDao.java | 13 ++- .../dao/core/CassandraRichVersionDao.java | 68 ++------------ .../dao/core/CassandraStructureDao.java | 5 +- .../core/CassandraStructureVersionDao.java | 11 ++- .../dao/usage/CassandraLineageEdgeDao.java | 2 +- .../usage/CassandraLineageEdgeVersionDao.java | 2 +- .../dao/usage/CassandraLineageGraphDao.java | 2 +- .../CassandraLineageGraphVersionDao.java | 2 +- .../dao/version/CassandraItemDao.java | 8 +- .../dao/version/CassandraTagDao.java | 88 +++--------------- .../dao/version/CassandraVersionDao.java | 1 - .../CassandraVersionHistoryDagDao.java | 32 ------- .../version/CassandraVersionSuccessorDao.java | 37 ++------ .../cassandra/util/CassandraStatements.java | 13 --- .../ground/cassandra/util/CassandraUtils.java | 84 +---------------- .../ground/cassandra/util/GroundUtils.java | 1 - .../ground/cassandra/dao/DaoTest.java | 6 +- .../CassandraVersionSuccessorDaoTest.java | 8 -- 30 files changed, 59 insertions(+), 449 deletions(-) delete mode 100644 modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java index d3dc3e29..61933b7f 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/EdgeController.java @@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java index 88544e2e..c241b3c0 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/GraphController.java @@ -29,7 +29,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java index e0244b69..02659a37 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageEdgeController.java @@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java index d61dbc15..df5e5e97 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/LineageGraphController.java @@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java index 58a50600..eb17e0af 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/NodeController.java @@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java index fecfb3ef..9f0cea8c 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/controllers/StructureController.java @@ -29,7 +29,6 @@ import java.util.concurrent.CompletionStage; import javax.inject.Inject; import play.cache.CacheApi; -// import play.db.Database; import play.libs.Json; import play.mvc.BodyParser; import play.mvc.Controller; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java deleted file mode 100644 index d9e74bba..00000000 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants2.java +++ /dev/null @@ -1,89 +0,0 @@ -package edu.berkeley.ground.cassandra.dao; - -public class CqlConstants2 { - - /* General insert statements */ - public static final String INSERT_GENERIC_ITEM_WITH_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; - public static final String INSERT_GENERIC_ITEM_WITHOUT_NAME = "INSERT INTO %s (item_id, source_key, name) VALUES (%d, \'%s\', null) ALLOW FILTERING;"; - - /* General select statements */ - public static final String SELECT_STAR_BY_SOURCE_KEY = "SELECT * FROM %s WHERE source_key = \'%s\' ALLOW FILTERING;"; - public static final String SELECT_STAR_ITEM_BY_ID = "SELECT * FROM %s WHERE item_id = %d ALLOW FILTERING;"; - public static final String SELECT_STAR_BY_ID = "SELECT * FROM %s WHERE id = %d ALLOW FILTERING;"; - public static final String DELETE_BY_ID = "DELETE FROM %s WHERE id = %d ALLOW FILTERING;"; - - /* Version-specific statements */ - public static final String INSERT_VERSION = "INSERT INTO version (id) VALUES (%d) ALLOW FILTERING;"; - - /* Version Successor-specific statements */ - public static final String INSERT_VERSION_SUCCESSOR = "INSERT INTO version_successor (id, from_version_id, to_version_id) VALUES (%d, %d, %d) ALLOW FILTERING;"; - public static final String SELECT_VERSION_SUCCESSOR = "SELECT * FROM version_successor where id = %d ALLOW FILTERING;"; - public static final String SELECT_VERSION_SUCCESSOR_BY_ENDPOINT = "SELECT * FROM version_successor WHERE to_version_id = %d ALLOW FILTERING;"; - public static final String DELETE_VERSION_SUCCESSOR = "DELETE FROM version_successor WHERE id = %d ALLOW FILTERING;"; - - /* Version History DAG-specific statements */ - public static final String INSERT_VERSION_HISTORY_DAG_EDGE = "INSERT INTO version_history_dag (item_id, version_successor_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String SELECT_VERSION_HISTORY_DAG = "SELECT * FROM version_history_dag WHERE item_id = %d ALLOW FILTERING;"; - public static final String DELETE_SUCCESSOR_FROM_DAG = "DELETE FROM version_history_dag WHERE version_successor_id = %d ALLOW FILTERING;"; - - /* Item-specific statements */ - public static final String INSERT_ITEM = "INSERT INTO ITEM (id) VALUES (%d) ALLOW FILTERING;"; - public static final String INSERT_ITEM_TAG_WITH_VALUE = - "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, " + "\'%s\', \'%s\', \'%s\') ALLOW FILTERING;"; - public static final String INSERT_ITEM_TAG_NO_VALUE = "INSERT INTO item_tag (item_id, key, value, type) VALUES (%d, \'%s\', null, null) ALLOW FILTERING;"; - public static final String SELECT_ITEM_TAGS = "SELECT * FROM item_tag WHERE item_id = %d ALLOW FILTERING;"; - public static final String SELECT_ITEM_TAGS_BY_KEY = "SELECT * FROM item_tag WHERE key = \'%s\' ALLOW FILTERING;"; - - /* Edge-specific statements */ - public static final String INSERT_EDGE_WITH_NAME = - "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, \'%s\') ALLOW FILTERING;"; - public static final String INSERT_EDGE_WITHOUT_NAME = - "INSERT INTO edge (item_id, source_key, from_node_id, to_node_id, name) VALUES (%d, \'%s\', %d, %d, null) ALLOW FILTERING;"; - public static final String INSERT_EDGE_VERSION = "INSERT INTO edge_version (id, edge_id, from_node_version_start_id, from_node_version_end_id, " - + "to_node_version_start_id, to_node_version_end_id) VALUES (%d, %d, %d, %d, %d, %d) ALLOW FILTERING;"; - public static final String UPDATE_EDGE_VERSION = "UPDATE edge_version SET from_node_version_end_id = %d, to_node_version_end_id = %d WHERE id = " - + "%d ALLOW FILTERING;"; - - /* Graph-specific statements */ - public static final String INSERT_GRAPH_VERSION = "INSERT INTO graph_version (id, graph_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String INSERT_GRAPH_VERSION_EDGE = "INSERT INTO graph_version_edge (graph_version_id, edge_version_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String SELECT_GRAPH_VERSION_EDGES = "SELECT * FROM graph_version_edge WHERE graph_version_id = %d ALLOW FILTERING;"; - public static final String DELETE_ALL_GRAPH_VERSION_EDGES = "DELETE FROM %s WHERE %s_version_id = %d ALLOW FILTERING;"; - - /* Node-specific statements */ - public static final String INSERT_NODE_VERSION = "INSERT INTO node_version (id, node_id) VALUES (%d, %d) ALLOW FILTERING;"; - - /* Rich Version-specific statements */ - public static final String INSERT_RICH_VERSION_WITH_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " - + "\'%s\') ALLOW FILTERING;"; - public static final String INSERT_RICH_VERSION_WITHOUT_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " - + "null) ALLOW FILTERING;"; - public static final String INSERT_RICH_VERSION_TAG_WITH_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " - + "\'%s\', \'%s\', \'%s\') ALLOW FILTERING;"; - public static final String INSERT_RICH_VERSION_TAG_NO_VALUE = "INSERT INTO rich_version_tag (rich_version_id, key, value, type) VALUES (%d, " - + "\'%s\', null, null) ALLOW FILTERING;"; - public static final String INSERT_RICH_VERSION_EXTERNAL_PARAMETER = "INSERT INTO rich_version_external_parameter (rich_version_id, key, value) " - + "VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; - public static final String SELECT_RICH_VERSION_EXTERNAL_PARAMETERS = "SELECT * FROM rich_version_external_parameter WHERE rich_version_id = %d ALLOW FILTERING;"; - public static final String SELECT_RICH_VERSION_TAGS = "SELECT * FROM rich_version_tag WHERE rich_version_id = %d ALLOW FILTERING;"; - public static final String SELECT_RICH_VERSION_TAGS_BY_KEY = "SELECT * FROM rich_version_tag WHERE key = \'%s\' ALLOW FILTERING;"; - public static final String DELETE_RICH_VERSION_TAGS = "DELETE FROM rich_version_tag WHERE rich_version_id = %d ALLOW FILTERING;"; - public static final String DELETE_RICH_EXTERNAL_PARAMETERS = "DELETE FROM rich_version_external_parameter WHERE rich_version_id = %d"; - - /* Structure-specific statements */ - public static final String INSERT_STRUCTURE_VERSION = "INSERT INTO structure_version (id, structure_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String INSERT_STRUCTURE_VERSION_ATTRIBUTE = "INSERT INTO structure_version_attribute (structure_version_id, key, type) " - + "VALUES (%d, \'%s\', \'%s\') ALLOW FILTERING;"; - public static final String SELECT_STRUCTURE_VERSION_ATTRIBUTES = "SELECT * FROM structure_version_attribute WHERE structure_version_id = %d ALLOW FILTERING;"; - public static final String DELETE_STRUCTURE_VERSION_ATTRIBUTES = "DELETE FROM structure_version_attribute WHERE structure_version_id = %d"; - - /* Lineage Edge-specific statements */ - public static final String INSERT_LINEAGE_EDGE_VERSION = "INSERT INTO lineage_edge_version (id, lineage_edge_id, from_rich_version_id, " - + "to_rich_version_id, principal_id) VALUES (%d, %d, %d, %d, %d) ALLOW FILTERING;"; - - /* Lineage Graph-specific statements */ - public static final String INSERT_LINEAGE_GRAPH_VERSION = "INSERT INTO lineage_graph_version (id, lineage_graph_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String INSERT_LINEAGE_GRAPH_VERSION_EDGE = "INSERT INTO lineage_graph_version_edge (lineage_graph_version_id, " - + "lineage_edge_version_id) VALUES (%d, %d) ALLOW FILTERING;"; - public static final String SELECT_LINEAGE_GRAPH_VERSION_EDGES = "SELECT * FROM lineage_graph_version_edge WHERE lineage_graph_version_id = %d ALLOW FILTERING;"; -} diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java index 482145fd..d8a6bc18 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java @@ -50,7 +50,7 @@ public Edge create(Edge edge) throws GroundException { String name = edge.getName(); - if (name != null) { // Andre - Again CQL + if (name != null) { statements.append(String.format(CqlConstants.INSERT_EDGE_WITH_NAME, uniqueId, edge.getSourceKey(), edge.getFromNodeId(), edge.getToNodeId(), name)); } else { diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java index 016a784c..20abd8c7 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeVersionDao.java @@ -15,9 +15,9 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; import play.libs.Json; + public class CassandraEdgeVersionDao extends CassandraRichVersionDao implements EdgeVersionDao { private CassandraEdgeDao cassandraEdgeDao; @@ -54,11 +54,11 @@ public EdgeVersion create(final EdgeVersion edgeVersion, List parentIds) t } statements.append(String.format(CqlConstants.INSERT_EDGE_VERSION, uniqueId, edgeVersion.getEdgeId(), edgeVersion.getFromNodeVersionStartId(), - fromEndId, edgeVersion.getToNodeVersionStartId(), toEndId)); // Andre - CQL + fromEndId, edgeVersion.getToNodeVersionStartId(), toEndId)); statements.merge(updateVersionList); - CassandraUtils.executeCqlList(dbSource, statements); // Andre - Make into executeCqlList() - BATCH + CassandraUtils.executeCqlList(dbSource, statements); } catch (Exception e) { throw new GroundException(e); } @@ -69,7 +69,7 @@ public EdgeVersion create(final EdgeVersion edgeVersion, List parentIds) t @Override public CassandraStatements delete(long id) { CassandraStatements statements = new CassandraStatements(); - statements.append(String.format(CqlConstants.DELETE_BY_ID, "edge_version", id)); // Andre - CQL + statements.append(String.format(CqlConstants.DELETE_BY_ID, "edge_version", id)); CassandraStatements superStatements = super.delete(id); superStatements.merge(statements); @@ -120,8 +120,8 @@ private CassandraStatements updatePreviousVersion(EdgeVersion currentVersion, lo @Override public EdgeVersion retrieveFromDatabase(long id) throws GroundException { - String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "edge_version", id); // Andre - CQL - JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); // Andre - executeCqlList + String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "edge_version", id); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); if (json.size() == 0) { throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java index a520fa76..180241da 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java @@ -21,7 +21,6 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; public class CassandraGraphDao extends CassandraItemDao implements GraphDao { @@ -47,7 +46,7 @@ public Graph create(Graph graph) throws GroundException { statements = super.insert(newGraph); String name = graph.getName(); - if (name != null) { // Andre - CQL u know it + if (name != null) { statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "graph", uniqueId, graph.getSourceKey(), name)); } else { statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "graph", uniqueId, graph.getSourceKey())); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java index 8c59ac34..a53f8ce1 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphVersionDao.java @@ -13,9 +13,9 @@ import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.ArrayList; import java.util.List; -//import play.db.Database; import play.libs.Json; + public class CassandraGraphVersionDao extends CassandraRichVersionDao implements GraphVersionDao { private CassandraGraphDao cassandraGraphDao; @@ -36,14 +36,14 @@ public GraphVersion create(final GraphVersion graphVersion, List parentIds try { CassandraStatements statements = super.insert(newGraphVersion); - statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION, uniqueId, graphVersion.getGraphId())); // Andre - CQL its lit + statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION, uniqueId, graphVersion.getGraphId())); statements.merge(updateVersionList); for (Long id : newGraphVersion.getEdgeVersionIds()) { - statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION_EDGE, newGraphVersion.getId(), id)); // Andre - CQL + statements.append(String.format(CqlConstants.INSERT_GRAPH_VERSION_EDGE, newGraphVersion.getId(), id)); } - CassandraUtils.executeCqlList(dbSource, statements); // Andre - executeCqlList + CassandraUtils.executeCqlList(dbSource, statements); } catch (Exception e) { throw new GroundException(e); } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java index 5af7e15c..4f1023f2 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java @@ -4,13 +4,12 @@ import edu.berkeley.ground.common.exception.GroundException; import edu.berkeley.ground.common.model.core.Node; import edu.berkeley.ground.common.util.IdGenerator; -import edu.berkeley.ground.cassandra.dao.CqlConstants; // Andre - What is this - CQL needed +import edu.berkeley.ground.cassandra.dao.CqlConstants; import edu.berkeley.ground.cassandra.dao.version.CassandraItemDao; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -//import play.db.Database; public class CassandraNodeDao extends CassandraItemDao implements NodeDao { @@ -37,7 +36,6 @@ public Node create(Node node) throws GroundException { String name = node.getName(); - // Andre -- SQL to CQL if (name != null) { statements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "node", uniqueId, node.getSourceKey(), name)); } else { @@ -47,7 +45,6 @@ public Node create(Node node) throws GroundException { throw new GroundException(e); } - // Andre -- SQL to CQL CassandraUtils.executeCqlList(dbSource, statements); return newNode; } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java index 58b7b4cf..764ced08 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java @@ -7,12 +7,11 @@ import edu.berkeley.ground.common.model.core.NodeVersion; import edu.berkeley.ground.common.model.core.RichVersion; import edu.berkeley.ground.common.util.IdGenerator; -import edu.berkeley.ground.cassandra.dao.CqlConstants; // Andre - SQL to CQL +import edu.berkeley.ground.cassandra.dao.CqlConstants; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -//import play.db.Database; import play.libs.Json; public class CassandraNodeVersionDao extends CassandraRichVersionDao implements NodeVersionDao { @@ -31,14 +30,14 @@ public NodeVersion create(final NodeVersion nodeVersion, List parentIds) final long uniqueId = idGenerator.generateVersionId(); NodeVersion newNodeVersion = new NodeVersion(uniqueId, nodeVersion); - CassandraStatements updateVersionList = this.cassandraNodeDao.update(newNodeVersion.getNodeId(), newNodeVersion.getId(), parentIds); // Andre - Problem line + CassandraStatements updateVersionList = this.cassandraNodeDao.update(newNodeVersion.getNodeId(), newNodeVersion.getId(), parentIds); try { - CassandraStatements statements = super.insert(newNodeVersion); // Andre - SQL to CQL + CassandraStatements statements = super.insert(newNodeVersion); statements.append(String.format(CqlConstants.INSERT_NODE_VERSION, uniqueId, nodeVersion.getNodeId())); statements.merge(updateVersionList); - CassandraUtils.executeCqlList(dbSource, statements); // Andre - SQL to CQL + CassandraUtils.executeCqlList(dbSource, statements); } catch (Exception e) { e.printStackTrace(); throw new GroundException(e); @@ -47,7 +46,7 @@ public NodeVersion create(final NodeVersion nodeVersion, List parentIds) } @Override - public CassandraStatements delete(long id) { // Andre - Modify CassandraStatements? + public CassandraStatements delete(long id) { CassandraStatements statements = new CassandraStatements(); statements.append(String.format(CqlConstants.DELETE_BY_ID, "node_version", id)); @@ -57,7 +56,7 @@ public CassandraStatements delete(long id) { // Andre - Modify CassandraStatemen } @Override - public NodeVersion retrieveFromDatabase(long id) throws GroundException { // Andre - refresh on Cassandra queries + public NodeVersion retrieveFromDatabase(long id) throws GroundException { String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "node_version", id); JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java index ef72647c..6a9ca2c6 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraRichVersionDao.java @@ -24,21 +24,14 @@ import edu.berkeley.ground.cassandra.dao.version.CassandraVersionDao; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.QueryExecutionException; - -// import java.sql.Connection; // Andre - what to do here -// import java.sql.ResultSet; -// import java.sql.SQLException; -// import java.sql.Statement; import java.util.HashMap; import java.util.Map; -import play.Logger; // Not necessary -// import play.db.Database; + public abstract class CassandraRichVersionDao extends CassandraVersionDao implements RichVersionDao { @@ -86,7 +79,7 @@ public CassandraStatements insert(final T richVersion) throws GroundException { } } - return statements; // Andre - What happens to these statements that are returned? + return statements; } @Override @@ -107,13 +100,9 @@ public CassandraStatements delete(long id) { public RichVersion retrieveFromDatabase(long id) throws GroundException { String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "rich_version", id); - // ResultSet resultSet; String reference; long structureVersionId; - // Cluster cluster = this.dbSource.getCluster(); - // Session session = this.dbSource.getSession(cluster); - Session session = this.dbSource.getSession(); @@ -126,37 +115,13 @@ public RichVersion retrieveFromDatabase(long id) throws GroundException { Row nextRow = resultSet.one(); - // Logger.debug("Andre: nextRow: " + nextRow.getColumnDefinitions().size()); - // for (int i = 0; i < nextRow.getColumnDefinitions().size(); i++) { - // Logger.debug("Andre: nextRow: " + nextRow.getColumnDefinitions().getName(i)); - // } - - reference = nextRow.getString("reference"); // Andre - Modified index - structureVersionId = nextRow.getLong("structure_version_id"); // Andre - Modified index + reference = nextRow.getString("reference"); + structureVersionId = nextRow.getLong("structure_version_id"); } catch (QueryExecutionException e) { throw new GroundException(e); } - // session.close(); - // cluster.close(); - - // try (Connection con = dbSource.getConnection()) { - // Statement stmt = con.createStatement(); - // resultSet = stmt.executeQuery(cql); - - // if (!resultSet.next()) { - // throw new GroundException(ExceptionType.VERSION_NOT_FOUND, RichVersion.class.getSimpleName(), String.format("%d", id)); - // } - - // reference = resultSet.getString(3); - // structureVersionId = resultSet.getLong(2); - // stmt.close(); - // con.close(); - // } catch (SQLException e) { // Andre - WTF DO I DO HERE! CQLException???? - // throw new GroundException(e); - // } - Map tags = this.cassandraTagDao.retrieveFromDatabaseByVersionId(id); Map referenceParams = getReferenceParameters(id); structureVersionId = structureVersionId == 0 ? -1 : structureVersionId; @@ -168,40 +133,17 @@ private Map getReferenceParameters(long id) throws GroundExcepti String cql = String.format(CqlConstants.SELECT_RICH_VERSION_EXTERNAL_PARAMETERS, id); Map referenceParameters = new HashMap<>(); - // Cluster cluster = this.dbSource.getCluster(); - // Session session = this.dbSource.getSession(cluster); - Session session = this.dbSource.getSession(); ResultSet parameterSet = session.execute(cql); - // Row nextRow = parameterSet.one(); if (parameterSet.isExhausted()) { return referenceParameters; } - // referenceParameters.put(nextRow.getString("key"), nextRow.getString("value")); // Andre - Modified index for (Row row: parameterSet.all()) { - referenceParameters.put(row.getString("key"), row.getString("value")); // Andre - Modified index + referenceParameters.put(row.getString("key"), row.getString("value")); } - // session.close(); - // cluster.close(); - - // try (Connection con = dbSource.getConnection()) { - // Statement stmt = con.createStatement(); - // ResultSet parameterSet = stmt.executeQuery(cql); - // if (!parameterSet.next()) { - // return referenceParameters; - // } - // do { - // referenceParameters.put(parameterSet.getString(2), parameterSet.getString(3)); - // } while (parameterSet.next()); - - // stmt.close(); - // con.close(); - // } catch (Exception e) { - // throw new GroundException(e); - // } return referenceParameters; } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java index 0d75aac2..e89eadfd 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java @@ -21,7 +21,6 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; public class CassandraStructureDao extends CassandraItemDao implements StructureDao { @@ -49,7 +48,7 @@ public Structure create(Structure structure) throws GroundException { String name = structure.getName(); - if (name != null) { // Andre - Make into CQL statements + if (name != null) { cassandraStatements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITH_NAME, "structure", uniqueId, structure.getSourceKey(), name)); } else { cassandraStatements.append(String.format(CqlConstants.INSERT_GENERIC_ITEM_WITHOUT_NAME, "structure", uniqueId, structure.getSourceKey())); @@ -60,7 +59,7 @@ public Structure create(Structure structure) throws GroundException { throw new GroundException(e); } - CassandraUtils.executeCqlList(dbSource, cassandraStatements); // Andre - Batch CQL? + CassandraUtils.executeCqlList(dbSource, cassandraStatements); return newStructure; } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java index 8fa1e95c..55a6addf 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureVersionDao.java @@ -26,7 +26,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -//import play.db.Database; import play.libs.Json; public class CassandraStructureVersionDao extends CassandraVersionDao implements StructureVersionDao { @@ -47,14 +46,14 @@ public final StructureVersion create(final StructureVersion structureVersion, Li .update(newStructureVersion.getStructureId(), newStructureVersion.getId(), parentIds); try { - CassandraStatements statements = super.insert(newStructureVersion); // Andre - Get statements from insertion? + CassandraStatements statements = super.insert(newStructureVersion); statements.append(String.format(CqlConstants.INSERT_STRUCTURE_VERSION, uniqueId, structureVersion.getStructureId())); - for (Map.Entry attribute : structureVersion.getAttributes().entrySet()) { // Andre - Change to CQL + for (Map.Entry attribute : structureVersion.getAttributes().entrySet()) { statements.append(String.format(CqlConstants.INSERT_STRUCTURE_VERSION_ATTRIBUTE, uniqueId, attribute.getKey(), attribute.getValue())); } - statements.merge(updateVersionList); // Andre - Update some type of lineage tree of versions? + statements.merge(updateVersionList); CassandraUtils.executeCqlList(dbSource, statements); } catch (Exception e) { @@ -67,7 +66,7 @@ public final StructureVersion create(final StructureVersion structureVersion, Li @Override public CassandraStatements delete(long id) { CassandraStatements statements = new CassandraStatements(); - statements.append(String.format(CqlConstants.DELETE_STRUCTURE_VERSION_ATTRIBUTES, id)); // Andre - CQL + statements.append(String.format(CqlConstants.DELETE_STRUCTURE_VERSION_ATTRIBUTES, id)); statements.append(String.format(CqlConstants.DELETE_BY_ID, "structure_version", id)); CassandraStatements superStatements = super.delete(id); @@ -80,7 +79,7 @@ public StructureVersion retrieveFromDatabase(final long id) throws GroundExcepti HashMap attributes; try { String resultQuery = String.format(CqlConstants.SELECT_STAR_BY_ID, "structure_version", id); - JsonNode resultJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, resultQuery)); // Andre - Async call? May be blocking/waiting? + JsonNode resultJson = Json.parse(CassandraUtils.executeQueryToJson(dbSource, resultQuery)); if (resultJson.size() == 0) { throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java index f6a03006..f61bed6e 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java @@ -21,7 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; + public class CassandraLineageEdgeDao extends CassandraItemDao implements LineageEdgeDao { diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java index b6b6ae6d..fda425ec 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeVersionDao.java @@ -24,9 +24,9 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; import play.libs.Json; + public class CassandraLineageEdgeVersionDao extends CassandraRichVersionDao implements LineageEdgeVersionDao { private CassandraLineageEdgeDao cassandraLineageEdgeDao; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java index 33a517db..10efaaa4 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java @@ -21,7 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; -// import play.db.Database; + public class CassandraLineageGraphDao extends CassandraItemDao implements LineageGraphDao { diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java index 24b9d7f6..8c5b2f06 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphVersionDao.java @@ -25,9 +25,9 @@ import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.ArrayList; import java.util.List; -// import play.db.Database; import play.libs.Json; + public class CassandraLineageGraphVersionDao extends CassandraRichVersionDao implements LineageGraphVersionDao { private CassandraLineageGraphDao cassandraLineageGraphDao; diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java index 1d210aa4..cf751634 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java @@ -28,9 +28,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -//import play.db.Database; import play.libs.Json; -import play.Logger; // Andre + public abstract class CassandraItemDao implements ItemDao { @@ -113,12 +112,7 @@ public CassandraStatements update(long itemId, long childId, List parentId VersionHistoryDag dag = this.cassandraVersionHistoryDagDao.retrieveFromDatabase(itemId); CassandraStatements statements = new CassandraStatements(); - for (String s: statements.getAllStatements()) { - Logger.debug("Andre statement: " + s); - } - for (long parentId : parentIds) { - Logger.debug("Andre: PARENTID: " + parentId); if (parentId != 0L && !dag.checkItemInDag(parentId)) { throw new GroundException(ExceptionType.OTHER, String.format("Parent %d is not in Item %d.", parentId, itemId)); } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java index e61e4835..ca4c926b 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraTagDao.java @@ -19,24 +19,15 @@ import edu.berkeley.ground.cassandra.dao.CqlConstants; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.QueryExecutionException; - -// import java.sql.Connection; // Andre - what do to here? -// import java.sql.ResultSet; -// import java.sql.SQLException; -// import java.sql.Statement; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -//import play.db.Database; -import play.Logger; // Andre unnecessary public class CassandraTagDao implements TagDao { @@ -85,52 +76,19 @@ public Map retrieveFromDatabaseByItemId(long id) throws GroundExcep private Map retrieveFromDatabaseById(long id, String cql) throws GroundException { Map results = new HashMap<>(); - // Cluster cluster = this.dbSource.getCluster(); - // Session session = this.dbSource.getSession(cluster); - Session session = this.dbSource.getSession(); - // Logger.debug ResultSet resultSet = session.execute(cql); for (Row row: resultSet.all()) { - String key = row.getString("key"); // Andre - Modified index + String key = row.getString("key"); // these methods will return null if the input is null, so there's no need to check - GroundType type = GroundType.fromString(row.getString("type")); // Andre - Modified index - Object value = this.getValue(type, row, "value"); // Andre - Modified index - // Logger.debug("id: " + id); - // Logger.debug("key: " + key); - // Logger.debug("value: " + value); - // Logger.debug("type: " + type); + GroundType type = GroundType.fromString(row.getString("type")); + Object value = this.getValue(type, row, "value"); results.put(key, new Tag(id, key, value, type)); } - // session.close(); - // cluster.close(); - - // try { - // Connection con = this.dbSource.getConnection(); - // Statement stmt = con.createStatement(); - - // ResultSet resultSet = stmt.executeQuery(cql); - - // while (resultSet.next()) { - // String key = resultSet.getString(2); - - // // these methods will return null if the input is null, so there's no need to check - // GroundType type = GroundType.fromString(resultSet.getString(4)); - // Object value = this.getValue(type, resultSet, 3); - - // results.put(key, new Tag(id, key, value, type)); - // } - - // stmt.close(); - // con.close(); - // } catch (SQLException e) { // Andre - CQLException???? - // throw new GroundException(e); - // } - return results; } @@ -149,62 +107,36 @@ public List getItemIdsByTag(String tag) throws GroundException { private List getIdsByTag(String cql, String idColumn) throws GroundException { List result = new ArrayList<>(); - // Cluster cluster = this.dbSource.getCluster(); - // Session session = this.dbSource.getSession(cluster); - Session session = this.dbSource.getSession(); try { ResultSet resultSet = session.execute(cql); for (Row row: resultSet.all()) { - result.add(row.getLong(idColumn)); // Andre - Modified + result.add(row.getLong(idColumn)); } - } catch (QueryExecutionException e) { // Andre - CQLException?? + } catch (QueryExecutionException e) { throw new GroundException(e); } - // session.close(); - // cluster.close(); - - // try { - // Connection con = this.dbSource.getConnection(); - // Statement stmt = con.createStatement(); - // ResultSet resultSet = stmt.executeQuery(cql); - - // while (resultSet.next()) { - // result.add(resultSet.getLong(1)); - // } - - // } catch (SQLException e) { // Andre - CQLException?? - // throw new GroundException(e); - // } - return result; } - // private Object getValue(GroundType type, ResultSet resultSet, String columnName) throws GroundException, SQLException { // Andre - CQLException?? - private Object getValue(GroundType type, Row row, String columnName) throws GroundException { // Andre - CQLException?? + private Object getValue(GroundType type, Row row, String columnName) throws GroundException { if (type == null) { return null; } - Logger.debug(type.toString()); - Logger.debug(row.getString(columnName)); switch (type) { case STRING: - // return row.getString(columnName); - return row.getString(columnName); // Andre + return row.getString(columnName); case INTEGER: - // return row.getInt(columnName); - return Integer.valueOf(row.getString(columnName)); // Andre + return Integer.valueOf(row.getString(columnName)); case LONG: - // return row.getLong(columnName); - return Long.valueOf(row.getString(columnName)); // Andre + return Long.valueOf(row.getString(columnName)); case BOOLEAN: - // return row.getBool(columnName); - return Boolean.valueOf(row.getString(columnName)); // Andre + return Boolean.valueOf(row.getString(columnName)); default: // this should never happen because we've listed all types throw new GroundException(ExceptionType.OTHER, String.format("Unidentified type: %s", type)); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java index b9f8b841..a4aad143 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionDao.java @@ -18,7 +18,6 @@ import edu.berkeley.ground.cassandra.dao.CqlConstants; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; -//import play.db.Database; public abstract class CassandraVersionDao implements VersionDao { diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java index 5b388019..5ba9a9c8 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionHistoryDagDao.java @@ -24,20 +24,14 @@ import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; - -// import java.sql.Connection; // Andre - what do I do here... -// import java.sql.ResultSet; -// import java.sql.Statement; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -// import play.db.Database; public class CassandraVersionHistoryDagDao implements VersionHistoryDagDao { @@ -70,9 +64,6 @@ public VersionHistoryDag retrieveFromDatabase(long itemId) throws GroundExceptio List edges = new ArrayList<>(); - // Cluster cluster = this.dbSource.getCluster(); - // Session session = this.dbSource.getSession(cluster); - Session session = this.dbSource.getSession(); final ResultSet resultSet = session.execute(cql); @@ -86,29 +77,6 @@ public VersionHistoryDag retrieveFromDatabase(long itemId) throws GroundExceptio edges.add(versionSuccessor); } - // session.close(); - // cluster.close(); - - // try (Connection con = dbSource.getConnection()) { - - // Statement stmt = con.createStatement(); - // final ResultSet resultSet = stmt.executeQuery(cql); - - // List successors = new ArrayList<>(); - // while (resultSet.next()) { - // successors.add(resultSet.getLong("version_successor_id")); - // } - - // stmt.close(); - // con.close(); - - // for (Long versionSuccessorId : successors) { - // VersionSuccessor versionSuccessor = cassandraVersionSuccessorDao.retrieveFromDatabase(versionSuccessorId); - // edges.add(versionSuccessor); - // } - // } catch (Exception e) { - // throw new GroundException(e); - // } return new VersionHistoryDag(itemId, edges); } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java index 7cc31309..30ffa231 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDao.java @@ -25,18 +25,15 @@ import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; -// import play.db.Database; -import play.libs.Json; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; -import com.datastax.driver.core.exceptions.QueryExecutionException; // Andre - may want to get rid of +import com.datastax.driver.core.exceptions.QueryExecutionException; +import play.libs.Json; -import play.Logger; // Andre - unnecessary -public class CassandraVersionSuccessorDao implements VersionSuccessorDao { +public class CassandraVersionSuccessorDao { private final IdGenerator idGenerator; private final CassandraDatabase dbSource; @@ -52,11 +49,10 @@ public CassandraVersionSuccessorDao(CassandraDatabase dbSource, IdGenerator idGe * @param successor the successor to insert * @return List of CQL expressions to insert version successor */ - @Override - public CassandraStatements insert(VersionSuccessor successor) { + public CassandraStatements insert(VersionSuccessor successor) throws GroundException { // Check to see if both are valid ids since we don't have foreign key constraints - // verifyVersion(successor.getFromId()); // Andre - not working for now - // verifyVersion(successor.getFromId()); + verifyVersion(successor.getFromId()); + verifyVersion(successor.getFromId()); CassandraStatements statements = new CassandraStatements(); String cql = String.format(CqlConstants.INSERT_VERSION_SUCCESSOR, successor.getId(), successor.getFromId(), successor.getToId()); @@ -73,11 +69,6 @@ public CassandraStatements insert(VersionSuccessor successor) { * @return the created version successor */ VersionSuccessor instantiateVersionSuccessor(long fromId, long toId) throws GroundException { - // Check to see if both are valid ids since we don't have foreign key constraints - // Logger.debug("Andre: checking versions exist"); - // verifyVersion(fromId); // Andre - not working for now - // verifyVersion(toId); - long dbId = idGenerator.generateSuccessorId(); return new VersionSuccessor(dbId, fromId, toId); } @@ -89,7 +80,6 @@ VersionSuccessor instantiateVersionSuccessor(long fromId, long toId) throws Grou * @return the retrieved version successor * @throws GroundException either the successor didn't exist or couldn't be retrieved */ - @Override public VersionSuccessor retrieveFromDatabase(long dbId) throws GroundException { try { String cql = String.format(CqlConstants.SELECT_VERSION_SUCCESSOR, dbId); @@ -115,7 +105,6 @@ public VersionSuccessor retrieveFromDatabase(long dbId) throws GroundException { * @param itemId the id of the item we are deleting from * @throws GroundException an unexpected error while retrieving the version successors to delete */ - @Override public void deleteFromDestination(DbStatements statementsPointer, long toId, long itemId) throws GroundException { CassandraStatements statements = (CassandraStatements) statementsPointer; @@ -126,11 +115,8 @@ public void deleteFromDestination(DbStatements statementsPointer, long toId, lon for (JsonNode result : json) { Long dbId = result.get("id").asLong(); - statements.append(String.format(CqlConstants.DELETE_SUCCESSOR_FROM_DAG, itemId, dbId)); // Andre + statements.append(String.format(CqlConstants.DELETE_SUCCESSOR_FROM_DAG, itemId, dbId)); statements.append(String.format(CqlConstants.DELETE_VERSION_SUCCESSOR, dbId)); - - // statements.append(String.format(CqlConstants.DELETE_SUCCESSOR_FROM_DAG, dbId)); - // statements.append(String.format(CqlConstants.DELETE_VERSION_SUCCESSOR, dbId)); } } catch (Exception e) { throw new GroundException(e); @@ -143,8 +129,6 @@ public void deleteFromDestination(DbStatements statementsPointer, long toId, lon * @param id an idea of a version */ private void verifyVersion(long id) throws GroundException { - // List predicate = new ArrayList<>(); - // predicate.add(new DbDataContainer("id", GroundType.LONG, id)); if (id == 0L ) { return; } @@ -157,12 +141,5 @@ private void verifyVersion(long id) throws GroundException { if (resultSet.isExhausted()) { throw new GroundException(ExceptionType.VERSION_NOT_FOUND, "version", String.valueOf(id)); } - - // ResultSet resultSet = this.dbClient.equalitySelect("version", DbClient.SELECT_STAR, - // predicate); - - // if (resultSet.isEmpty()) { - // throw new GroundException("Version id " + id + " is not valid."); - // } } } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java index 86001989..a8528ebd 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraStatements.java @@ -3,17 +3,13 @@ import edu.berkeley.ground.common.util.DbStatements; import java.util.ArrayList; import java.util.List; -// import java.util.HashSet; // Andre -// import play.Logger; // Andre - unnecessary public class CassandraStatements implements DbStatements { List statements; - // HashSet idsToCreate; // Andre public CassandraStatements() { this.statements = new ArrayList<>(); - // this.idsToCreate = new HashSet(); } public CassandraStatements(List statements) { @@ -22,18 +18,9 @@ public CassandraStatements(List statements) { @Override public void append(String statement) { - // Logger.debug("Andre statement append: " + statement); this.statements.add(statement); } - // public void intendToCreateId(Long id) { // Andre - // this.idsToCreate.add(id); - // } - - // public boolean isIntendingToCreateId(Long id) { // Andre - // return this.idsToCreate.contains(id); - // } - @Override public void merge(DbStatements other) { this.statements.addAll(other.getAllStatements()); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java index 14db02e4..93eb0846 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/CassandraUtils.java @@ -15,27 +15,18 @@ import akka.actor.ActorSystem; import com.google.common.base.CaseFormat; import edu.berkeley.ground.common.exception.GroundException; - -//import java.sql.Connection; // Andre - What to do here? -//import java.sql.ResultSet; -//import java.sql.SQLException; -//import java.sql.Statement; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.QueryExecutionException; - import edu.berkeley.ground.cassandra.util.CassandraDatabase; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import play.Logger; -// import play.db.Database; import play.libs.concurrent.HttpExecution; public final class CassandraUtils { @@ -43,29 +34,23 @@ public final class CassandraUtils { private CassandraUtils() { } - public static Executor getDbSourceHttpContext(final ActorSystem actorSystem) { // Andre - does this change? + public static Executor getDbSourceHttpContext(final ActorSystem actorSystem) { return HttpExecution.fromThread((Executor) actorSystem.dispatchers().lookup("ground.db.context")); } public static String executeQueryToJson(CassandraDatabase dbSource, String cql) throws GroundException { Logger.debug("executeQueryToJson: {}", cql); - // Cluster cluster = dbSource.getCluster(); - // Session session = dbSource.getSession(cluster); - final List> objList = new ArrayList<>(); Session session = dbSource.getSession(); try { - final ResultSet resultSet = session.execute(cql); // Andre - Session conveniently returns a resultSet? + final ResultSet resultSet = session.execute(cql); - // final long columnCount = resultSet.getColumnDefinitions().size(); - for (Row row: resultSet.all()) { final Map rowData = new HashMap<>(); for (int column = 0; column < resultSet.getColumnDefinitions().size(); column++) { - // for (int column = 1; column <= columnCount; column++) { // Andre - Maybe should start from 0? String key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, resultSet.getColumnDefinitions().getName(column)); rowData.put(key, row.getObject(column)); } @@ -76,45 +61,10 @@ public static String executeQueryToJson(CassandraDatabase dbSource, String cql) throw new GroundException(e); } - // session.close(); - // cluster.close(); - - Logger.debug("Andre: Returning JSON"); return GroundUtils.listToJson(objList); - - // try { - // Cluster cluster = dbSource.getCluster(); - // Session session = dbSource.getSession(cluster); - - // final ResultSet resultSet = session.execute(cql); // Andre - Session conveniently returns a resultSet? - // final long columnCount = resultSet.getMetaData().getColumnCount(); - // final List> objList = new ArrayList<>(); - - // while (resultSet.next()) { - // final Map rowData = new HashMap<>(); - - // for (int column = 1; column <= columnCount; column++) { // Andre - Maybe should start from 0? - // String key = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, resultSet.getMetaData().getColumnLabel(column)); - // rowData.put(key, resultSet.getObject(column)); - // } - - // objList.add(rowData); - // } - - // session.close(); - // cluster.close(); - // return GroundUtils.listToJson(objList); - // } catch (SQLException e) { - // Logger.error("ERROR: executeQueryToJson CQL : {} Message: {} Trace: {}", cql, e.getMessage(), e.getStackTrace()); - // throw new GroundException(e); - // } } public static void executeCqlList(final CassandraDatabase dbSource, final CassandraStatements statements) throws GroundException { - - // Cluster cluster = dbSource.getCluster(); - // Session session = dbSource.getSession(cluster); - Session session = dbSource.getSession(); try { @@ -126,35 +76,5 @@ public static void executeCqlList(final CassandraDatabase dbSource, final Cassan Logger.error("error: Message: {} Trace: {}", e.getMessage(), e.getStackTrace()); throw new GroundException(e); } - - // session.close(); - // cluster.close(); - - // try { - // Connection con = dbSource.getConnection(); - // con.setAutoCommit(false); - // Statement stmt = con.createStatement(); - - // for (final String sql : statements.getAllStatements()) { - // Logger.debug("executeSqlList sql : {}", sql); - - // try { - // stmt.execute(sql); - // } catch (final SQLException e) { - // con.rollback(); - // Logger.error("error: Message: {} Trace: {}", e.getMessage(), e.getStackTrace()); - - // throw new GroundException(e); - // } - // } - - // stmt.close(); - // con.commit(); - // con.close(); - // } catch (SQLException e) { - // Logger.error("error: executeSqlList SQL : {} Message: {} Trace: {}", statements.getAllStatements(), e.getMessage(), e.getStackTrace()); - - // throw new GroundException(e); - // } } } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java index 82005442..ed3fdde2 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map; import play.Logger; -// import play.db.Database; import play.libs.Json; import play.mvc.Http.Request; import play.mvc.Result; diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java index 774ffe6c..04970820 100644 --- a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/DaoTest.java @@ -17,7 +17,8 @@ import edu.berkeley.ground.common.dao.version.TagDao; import edu.berkeley.ground.common.dao.version.VersionDao; import edu.berkeley.ground.common.dao.version.VersionHistoryDagDao; -import edu.berkeley.ground.common.dao.version.VersionSuccessorDao; +// import edu.berkeley.ground.common.dao.version.VersionSuccessorDao; +import edu.berkeley.ground.cassandra.dao.version.CassandraVersionSuccessorDao; import edu.berkeley.ground.common.exception.GroundException; import edu.berkeley.ground.common.model.core.Edge; import edu.berkeley.ground.common.model.core.EdgeVersion; @@ -56,7 +57,8 @@ public class DaoTest { protected static CassandraDatabase dbSource; protected static IdGenerator idGenerator; - protected static VersionSuccessorDao versionSuccessorDao; + // protected static VersionSuccessorDao versionSuccessorDao; + protected static CassandraVersionSuccessorDao versionSuccessorDao; protected static VersionHistoryDagDao versionHistoryDagDao; protected static TagDao tagDao; protected static EdgeDao edgeDao; diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java index 5b025cd2..71f7c662 100644 --- a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/version/CassandraVersionSuccessorDaoTest.java @@ -24,7 +24,6 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import org.junit.Test; -import play.Logger; // Andre - unnecessary public class CassandraVersionSuccessorDaoTest extends CassandraTest { @@ -51,26 +50,19 @@ public void testVersionSuccessorCreation() throws GroundException { @Test(expected = GroundException.class) public void testBadVersionSuccessorCreation() throws GroundException { - Logger.debug("\n\n\nBEGINNING TEST\n"); - long fromId = 123; long toId = 456; - Logger.debug("A"); - // Catch exceptions for these two lines because they should not fal try { // the main difference is that we're not creating a Version for the toId CassandraTest.cassandraVersionDao.insert(new Version(fromId)); } catch (GroundException ge) { fail(ge.getMessage()); } - Logger.debug("B"); // This statement should cause a GroundException because toId is not in the database VersionSuccessor successor = ((CassandraVersionSuccessorDao) CassandraTest.versionSuccessorDao).instantiateVersionSuccessor(fromId, toId); - Logger.debug("C"); CassandraUtils.executeCqlList(CassandraTest.dbSource, (CassandraStatements) CassandraTest.versionSuccessorDao.insert(successor)); - Logger.debug("D"); } @Test(expected = GroundException.class) From e3cebe6952bee2cb67037b10a08ac73ea97a0b4c Mon Sep 17 00:00:00 2001 From: Andre Askari Date: Wed, 16 Aug 2017 13:54:47 -0700 Subject: [PATCH 3/5] cleanup comments --- .../dao/version/CassandraItemDao.java | 1 - .../ground/cassandra/util/GroundUtils.java | 1 - .../ground/cassandra/dao/CassandraTest.java | 49 +------------------ 3 files changed, 1 insertion(+), 50 deletions(-) diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java index cf751634..5a06134e 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java @@ -54,7 +54,6 @@ public CassandraStatements insert(final T item) throws GroundException { final Map tags = item.getTags(); CassandraStatements statements = new CassandraStatements(cqlList); - // statements.intendToCreateId(id); // Andre - added for modified statements if (tags != null) { for (String key : tags.keySet()) { diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java index ed3fdde2..6cd61c06 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/util/GroundUtils.java @@ -73,7 +73,6 @@ private static ObjectNode getClientError(final Request request, final Throwable static String listToJson(final List> objList) { try { - Logger.debug("Andre: " + new ObjectMapper().writeValueAsString(objList)); return new ObjectMapper().writeValueAsString(objList); } catch (IOException e) { throw new RuntimeException("ERROR : listToJson Converting List to JSON." + e.getMessage(), e); diff --git a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/CassandraTest.java b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/CassandraTest.java index d3732fc6..8f092a7a 100644 --- a/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/CassandraTest.java +++ b/modules/cassandra/test/edu/berkeley/ground/cassandra/dao/CassandraTest.java @@ -24,22 +24,13 @@ import edu.berkeley.ground.cassandra.util.CassandraDatabase; import java.io.IOException; import java.util.function.Function; - import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; - import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; - -// import java.sql.Connection; -// import java.sql.SQLException; -// import java.sql.Statement; import org.junit.After; import org.junit.Before; -// import play.db.Database; -// import play.db.Databases; -import play.Logger; public class CassandraTest extends DaoTest { @@ -47,7 +38,7 @@ public class CassandraTest extends DaoTest { private static final String TRUNCATE_SCRIPT = "../../resources/scripts/cassandra/truncate.cql"; private static final String CREATE_SCHEMA_SCRIPT = "../../resources/scripts/cassandra/cassandra.cql"; private static final Function CREATE_KEYSPACE_CQL = keyspace->"create keyspace IF NOT EXISTS " + - keyspace + " with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };"; // Andre - will this be used? + keyspace + " with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };"; public CassandraTest() throws GroundException { @@ -102,42 +93,4 @@ private static void runScript(String script) { Session session = dbSource.getSession(); DaoTest.runScript(script, session::execute); } - - // private static void runScript(String script) { // Andre - What the heck is happening here - // try { - // boolean autoCommitState = dbSource.getConnection().getAutoCommit(); - // dbSource.getConnection().setAutoCommit(false); - // StatementExecutor exec = new StatementExecutor(dbSource.getConnection()); - // CassandraTest.runScript(script, exec::execute); - // dbSource.getConnection().setAutoCommit(autoCommitState); - // } catch (SQLException ex) { - // throw new RuntimeException(ex); - // } - // } - - // private static class StatementExecutor { - - // private final Connection conn; - - // StatementExecutor(Connection conn) { - // this.conn = conn; - // } - - // void execute(String statement) { - // try { - // Statement sqlStatement = conn.createStatement(); - // sqlStatement.execute(statement); - // } catch (SQLException e) { - // String message = e.getMessage(); - // if (message.contains("already exists") || message - // .contains("current transaction is aborted")) { - // System.out.println("Warn: statement [" + statement + "] causes: " + e.getMessage()); - // // ignore errors caused by type already existing - // } else { - // throw new RuntimeException(e); - // } - // } - // } - // } - } From 2ba9e22639bd32eaa50e7800387c3bf3b7577a6e Mon Sep 17 00:00:00 2001 From: andreaskari Date: Tue, 5 Sep 2017 12:30:18 -0700 Subject: [PATCH 4/5] Cassandra setup files added --- .../scripts/cassandra/cassandra_setup.py | 29 +++ .../scripts/cassandra/drop_cassandra.cql | 38 ++++ resources/scripts/cassandra/truncate.cql | 40 ++++ resources/scripts/format-code.sh | 11 ++ resources/scripts/postgres/drop_postgres.sql | 37 ++++ resources/scripts/postgres/postgres.sql | 177 ++++++++++++++++++ resources/scripts/postgres/postgres_setup.py | 28 +++ 7 files changed, 360 insertions(+) create mode 100644 resources/scripts/cassandra/cassandra_setup.py create mode 100644 resources/scripts/cassandra/drop_cassandra.cql create mode 100644 resources/scripts/cassandra/truncate.cql create mode 100755 resources/scripts/format-code.sh create mode 100644 resources/scripts/postgres/drop_postgres.sql create mode 100644 resources/scripts/postgres/postgres.sql create mode 100644 resources/scripts/postgres/postgres_setup.py diff --git a/resources/scripts/cassandra/cassandra_setup.py b/resources/scripts/cassandra/cassandra_setup.py new file mode 100644 index 00000000..1414abe1 --- /dev/null +++ b/resources/scripts/cassandra/cassandra_setup.py @@ -0,0 +1,29 @@ +''' +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +import sys, os + +assert (len(sys.argv) >= 2) +dbname = sys.argv[1] + +drop = len(sys.argv) == 3 + +if drop: + command_string = "cqlsh -k " + str(dbname) + " -f drop_cassandra.cql" + os.system(command_string) + +command_string = "cqlsh -k " + str(dbname) + " -f cassandra.cql" +os.system(command_string) + +print "Successfully reset Cassandra." diff --git a/resources/scripts/cassandra/drop_cassandra.cql b/resources/scripts/cassandra/drop_cassandra.cql new file mode 100644 index 00000000..4d273e0d --- /dev/null +++ b/resources/scripts/cassandra/drop_cassandra.cql @@ -0,0 +1,38 @@ +/** + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +DROP TABLE lineage_graph_version_edge; +DROP TABLE lineage_graph_version; +DROP TABLE lineage_graph; +DROP TABLE lineage_edge_version; +DROP TABLE lineage_edge; +DROP TABLE principal; +DROP TABLE graph_version_edge; +DROP TABLE graph_version; +DROP TABLE edge_version; +DROP TABLE node_version; +DROP TABLE graph; +DROP TABLE node; +DROP TABLE edge; +DROP TABLE rich_version_tag; +DROP TABLE rich_version_external_parameter; +DROP TABLE rich_version; +DROP TABLE structure_version_attribute; +DROP TABLE structure_version; +DROP TABLE structure; +DROP TABLE version_history_dag; +DROP TABLE item_tag; +DROP TABLE item; +DROP TABLE version_successor; +DROP TABLE version; diff --git a/resources/scripts/cassandra/truncate.cql b/resources/scripts/cassandra/truncate.cql new file mode 100644 index 00000000..4c175ce1 --- /dev/null +++ b/resources/scripts/cassandra/truncate.cql @@ -0,0 +1,40 @@ + +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + + +TRUNCATE lineage_graph_version_edge; +TRUNCATE lineage_graph_version; +TRUNCATE lineage_graph; +TRUNCATE lineage_edge_version; +TRUNCATE lineage_edge; +TRUNCATE principal; +TRUNCATE graph_version_edge; +TRUNCATE graph_version; +TRUNCATE edge_version; +TRUNCATE node_version; +TRUNCATE graph; +TRUNCATE node; +TRUNCATE edge; +TRUNCATE rich_version_tag; +TRUNCATE rich_version_external_parameter; +TRUNCATE rich_version; +TRUNCATE structure_version_attribute; +TRUNCATE structure_version; +TRUNCATE structure; +TRUNCATE version_history_dag; +TRUNCATE item_tag; +TRUNCATE item; +TRUNCATE version_successor; +TRUNCATE version; + +INSERT into version(id) values (0); diff --git a/resources/scripts/format-code.sh b/resources/scripts/format-code.sh new file mode 100755 index 00000000..e9a502a9 --- /dev/null +++ b/resources/scripts/format-code.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Auto format changed java files using google-java-format. +# TODO: make this a pre commit hook, putting it in $repo/.git/hooks + +cd `git rev-parse --show-toplevel` + +java -jar resources/scripts/google-java-format-1.3-all-deps.jar --replace `find . -name "*.java" -type f -printf " %p"` + + + + diff --git a/resources/scripts/postgres/drop_postgres.sql b/resources/scripts/postgres/drop_postgres.sql new file mode 100644 index 00000000..932e8c72 --- /dev/null +++ b/resources/scripts/postgres/drop_postgres.sql @@ -0,0 +1,37 @@ +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +DROP TABLE lineage_graph_version_edge; +DROP TABLE lineage_graph_version; +DROP TABLE lineage_graph; +DROP TABLE lineage_edge_version; +DROP TABLE lineage_edge; +DROP TABLE principal; +DROP TABLE graph_version_edge; +DROP TABLE graph_version; +DROP TABLE edge_version; +DROP TABLE node_version; +DROP TABLE graph; +DROP TABLE edge; +DROP TABLE node; +DROP TABLE rich_version_tag; +DROP TABLE rich_version_external_parameter; +DROP TABLE rich_version; +DROP TABLE structure_version_attribute; +DROP TABLE structure_version; +DROP TABLE structure; +DROP TABLE version_history_dag; +DROP TABLE item_tag; +DROP TABLE item; +DROP TABLE version_successor; +DROP TABLE version; +DROP TYPE data_type; diff --git a/resources/scripts/postgres/postgres.sql b/resources/scripts/postgres/postgres.sql new file mode 100644 index 00000000..85447a9f --- /dev/null +++ b/resources/scripts/postgres/postgres.sql @@ -0,0 +1,177 @@ +-- noinspection SqlDialectInspectionForFile + +-- noinspection SqlNoDataSourceInspectionForFile + +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- VERSIONS +CREATE TYPE data_type as enum ('integer', 'string', 'boolean'); + +CREATE TABLE IF NOT EXISTS version ( + id bigint NOT NULL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS version_successor ( + id bigint NOT NULL PRIMARY KEY, + from_version_id bigint NOT NULL REFERENCES version(id), + to_version_id bigint NOT NULL REFERENCES version(id), + CONSTRAINT version_successor_unique_endpoints UNIQUE (from_version_id, to_version_id) +); + +CREATE TABLE IF NOT EXISTS item ( + id bigint NOT NULL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS item_tag ( + item_id bigint NOT NULL REFERENCES item(id), + key varchar NOT NULL, + value varchar, + type data_type, + CONSTRAINT item_tag_pkey PRIMARY KEY (item_id, key) +); + +CREATE TABLE IF NOT EXISTS version_history_dag ( + item_id bigint NOT NULL REFERENCES item(id), + version_successor_id bigint NOT NULL REFERENCES version_successor(id), + CONSTRAINT version_history_dag_pkey PRIMARY KEY (item_id, version_successor_id) +); + +-- MODELS + +CREATE TABLE IF NOT EXISTS structure ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS structure_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES version(id), + structure_id bigint NOT NULL REFERENCES structure(item_id) +); + +CREATE TABLE IF NOT EXISTS structure_version_attribute ( + structure_version_id bigint NOT NULL REFERENCES structure_version(id), + key varchar NOT NULL, + type varchar NOT NULL, + CONSTRAINT structure_version_attribute_pkey PRIMARY KEY(structure_version_id, key) +); + +CREATE TABLE IF NOT EXISTS rich_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES version(id), + structure_version_id bigint REFERENCES structure_version(id), + reference varchar +); + +CREATE TABLE IF NOT EXISTS rich_version_external_parameter ( + rich_version_id bigint NOT NULL REFERENCES rich_version(id), + key varchar NOT NULL, + value varchar NOT NULL, + CONSTRAINT rich_version_external_parameter_pkey PRIMARY KEY (rich_version_id, key) +); + +CREATE TABLE IF NOT EXISTS rich_version_tag ( + rich_version_id bigint REFERENCES rich_version(id), + key varchar NOT NULL, + value varchar, + type data_type, + CONSTRAINT rich_version_tag_pkey PRIMARY KEY (rich_version_id, key) +); + +CREATE TABLE IF NOT EXISTS node ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS edge ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + from_node_id bigint NOT NULL REFERENCES node(item_id), + to_node_id bigint NOT NULL REFERENCES node(item_id), + name varchar +); + + +CREATE TABLE IF NOT EXISTS graph ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS node_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES rich_version(id), + node_id bigint NOT NULL REFERENCES node(item_id) +); + +CREATE TABLE IF NOT EXISTS edge_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES rich_version(id), + edge_id bigint NOT NULL REFERENCES edge(item_id), + from_node_version_start_id bigint NOT NULL REFERENCES node_version(id), + from_node_version_end_id bigint REFERENCES node_version(id), + to_node_version_start_id bigint NOT NULL REFERENCES node_version(id), + to_node_version_end_id bigint REFERENCES node_version(id) +); + +CREATE TABLE IF NOT EXISTS graph_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES rich_version(id), + graph_id bigint NOT NULL REFERENCES graph(item_id) +); + +CREATE TABLE IF NOT EXISTS graph_version_edge ( + graph_version_id bigint NOT NULL REFERENCES graph_version(id), + edge_version_id bigint NOT NULL REFERENCES edge_version(id), + CONSTRAINT graph_version_edge_pkey PRIMARY KEY (graph_version_id, edge_version_id) +); + +-- USAGE + +CREATE TABLE IF NOT EXISTS principal ( + node_id bigint NOT NULL PRIMARY KEY REFERENCES node(item_id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS lineage_edge ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS lineage_edge_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES rich_version(id), + lineage_edge_id bigint NOT NULL REFERENCES lineage_edge(item_id), + from_rich_version_id bigint NOT NULL REFERENCES rich_version(id), + to_rich_version_id bigint NOT NULL REFERENCES rich_version(id), + principal_id bigint REFERENCES node_version(id) +); + +CREATE TABLE IF NOT EXISTS lineage_graph ( + item_id bigint NOT NULL PRIMARY KEY REFERENCES item(id), + source_key varchar UNIQUE, + name varchar +); + +CREATE TABLE IF NOT EXISTS lineage_graph_version ( + id bigint NOT NULL PRIMARY KEY REFERENCES rich_version(id), + lineage_graph_id bigint NOT NULL REFERENCES lineage_graph(item_id) +); + +CREATE TABLE IF NOT EXISTS lineage_graph_version_edge ( + lineage_graph_version_id bigint NOT NULL REFERENCES lineage_graph_version(id), + lineage_edge_version_id bigint NOT NULL REFERENCES lineage_edge_version(id), + CONSTRAINT lineage_graph_version_edge_pkey PRIMARY KEY (lineage_graph_version_id, lineage_edge_version_id) +); + +-- CREATE EMPTY VERSION + +INSERT INTO version(id) values (0); diff --git a/resources/scripts/postgres/postgres_setup.py b/resources/scripts/postgres/postgres_setup.py new file mode 100644 index 00000000..1bd03df9 --- /dev/null +++ b/resources/scripts/postgres/postgres_setup.py @@ -0,0 +1,28 @@ +''' +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +''' + +import os, sys + +assert (len(sys.argv) >= 3) +user = sys.argv[1] +dbname = sys.argv[2] + +drop = len(sys.argv) == 4 + +if drop: + delete_string = "psql -U " + str(user) + " -d " + str(dbname) + " -f drop_postgres.sql" + os.system(delete_string) + +create_string = "psql -U " + str(user) + " -d " + str(dbname) + " -f postgres.sql" +os.system(create_string) From 767099143aca741b7d2930ae2b17dfb5ca9cf9e6 Mon Sep 17 00:00:00 2001 From: andreaskari Date: Sat, 23 Sep 2017 17:12:16 -0700 Subject: [PATCH 5/5] All tests now passing --- .../ground/cassandra/dao/CqlConstants.java | 1 + .../cassandra/dao/core/CassandraEdgeDao.java | 7 +++++++ .../cassandra/dao/core/CassandraGraphDao.java | 7 +++++++ .../cassandra/dao/core/CassandraNodeDao.java | 7 +++++++ .../dao/core/CassandraNodeVersionDao.java | 16 ++++++++++++++-- .../dao/core/CassandraStructureDao.java | 7 +++++++ .../dao/usage/CassandraLineageEdgeDao.java | 7 +++++++ .../dao/usage/CassandraLineageGraphDao.java | 7 +++++++ .../cassandra/dao/version/CassandraItemDao.java | 16 ++++++++++++++++ 9 files changed, 73 insertions(+), 2 deletions(-) diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java index c17a1f3c..47f84239 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/CqlConstants.java @@ -52,6 +52,7 @@ public class CqlConstants { /* Node-specific statements */ public static final String INSERT_NODE_VERSION = "INSERT INTO node_version (id, node_id) VALUES (%d, %d);"; + public static final String SELECT_NODE_VERSION_ADJACENT_LINEAGE = "SELECT * FROM lineage_edge_version WHERE from_rich_version_id = %d;"; /* Rich Version-specific statements */ public static final String INSERT_RICH_VERSION_WITH_REFERENCE = "INSERT INTO rich_version (id, structure_version_id, reference) VALUES (%d, %d, " diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java index d8a6bc18..c4a9d14d 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraEdgeDao.java @@ -22,6 +22,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; import edu.berkeley.ground.cassandra.util.CassandraDatabase; import play.libs.Json; @@ -85,6 +86,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(edge.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + Edge edge = retrieveFromDatabase(sourceKey); + return super.getHistory(edge.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java index 180241da..9a6d5568 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraGraphDao.java @@ -21,6 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; public class CassandraGraphDao extends CassandraItemDao implements GraphDao { @@ -65,6 +66,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(graph.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + Graph graph = retrieveFromDatabase(sourceKey); + return super.getHistory(graph.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java index 4f1023f2..f3818d97 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeDao.java @@ -10,6 +10,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; public class CassandraNodeDao extends CassandraItemDao implements NodeDao { @@ -55,6 +56,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(node.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + Node node = retrieveFromDatabase(sourceKey); + return super.getHistory(node.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java index 764ced08..63b1ecfb 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraNodeVersionDao.java @@ -11,6 +11,7 @@ import edu.berkeley.ground.cassandra.util.CassandraDatabase; import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; +import java.util.ArrayList; import java.util.List; import play.libs.Json; @@ -37,7 +38,7 @@ public NodeVersion create(final NodeVersion nodeVersion, List parentIds) statements.append(String.format(CqlConstants.INSERT_NODE_VERSION, uniqueId, nodeVersion.getNodeId())); statements.merge(updateVersionList); - CassandraUtils.executeCqlList(dbSource, statements); + CassandraUtils.executeCqlList(this.dbSource, statements); } catch (Exception e) { e.printStackTrace(); throw new GroundException(e); @@ -58,7 +59,7 @@ public CassandraStatements delete(long id) { @Override public NodeVersion retrieveFromDatabase(long id) throws GroundException { String cql = String.format(CqlConstants.SELECT_STAR_BY_ID, "node_version", id); - JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(dbSource, cql)); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(this.dbSource, cql)); if (json.size() == 0) { throw new GroundException(ExceptionType.VERSION_NOT_FOUND, this.getType().getSimpleName(), String.format("%d", id)); @@ -69,4 +70,15 @@ public NodeVersion retrieveFromDatabase(long id) throws GroundException { return new NodeVersion(id, richVersion, nodeVersion); } + + @Override + public List retrieveAdjacentLineageEdgeVersion(long startId) throws GroundException { + String cql = String.format(CqlConstants.SELECT_NODE_VERSION_ADJACENT_LINEAGE, startId); + JsonNode json = Json.parse(CassandraUtils.executeQueryToJson(this.dbSource, cql)); + + List result = new ArrayList<>(); + json.forEach(x -> result.add(x.get("id").asLong())); + + return result; + } } diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java index e89eadfd..dfb8b516 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/core/CassandraStructureDao.java @@ -21,6 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; public class CassandraStructureDao extends CassandraItemDao implements StructureDao { @@ -69,6 +70,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(structure.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + Structure structure = retrieveFromDatabase(sourceKey); + return super.getHistory(structure.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java index f61bed6e..30d0d0d4 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageEdgeDao.java @@ -21,6 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; public class CassandraLineageEdgeDao extends CassandraItemDao implements LineageEdgeDao { @@ -66,6 +67,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(lineageEdge.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + LineageEdge lineageEdge = retrieveFromDatabase(sourceKey); + return super.getHistory(lineageEdge.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java index 10efaaa4..5e917359 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/usage/CassandraLineageGraphDao.java @@ -21,6 +21,7 @@ import edu.berkeley.ground.cassandra.util.CassandraStatements; import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.util.List; +import java.util.Map; public class CassandraLineageGraphDao extends CassandraItemDao implements LineageGraphDao { @@ -66,6 +67,12 @@ public List getLeaves(String sourceKey) throws GroundException { return super.getLeaves(lineageGraph.getId()); } + @Override + public Map getHistory(String sourceKey) throws GroundException { + LineageGraph lineageGraph = retrieveFromDatabase(sourceKey); + return super.getHistory(lineageGraph.getId()); + } + @Override public void truncate(long itemId, int numLevels) throws GroundException { super.truncate(itemId, numLevels); diff --git a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java index 5a06134e..1b1a906a 100644 --- a/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java +++ b/modules/cassandra/app/edu/berkeley/ground/cassandra/dao/version/CassandraItemDao.java @@ -26,6 +26,7 @@ import edu.berkeley.ground.cassandra.util.CassandraUtils; import java.lang.reflect.Constructor; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import play.libs.Json; @@ -92,6 +93,21 @@ public List getLeaves(long itemId) throws GroundException { } } + @Override + public Map getHistory(long itemId) throws GroundException { + try { + VersionHistoryDag dag = this.cassandraVersionHistoryDagDao.retrieveFromDatabase(itemId); + + return dag.getParentChildPairs(); + } catch (GroundException e) { + if (!e.getMessage().contains("No results found for query:")) { + throw e; + } + + return new HashMap<>(); + } + } + /** * Add a new Version to this Item. The provided parentIds will be the parents of this particular * version. What's provided in the default case varies based on which database we are writing