Skip to content

Commit

Permalink
Crossbuild sbt 1.0 and 0.13
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Michel committed Oct 9, 2017
1 parent 20af76b commit 492645a
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 64 deletions.
9 changes: 7 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
language: scala
jdk: oraclejdk8
services:
- cassandra
scala:
- 2.10.6
matrix:
include:
- env: SBT_VERSION="0.13.16"
scala: 2.10.6
- env: SBT_VERSION="1.0.2"
scala: 2.12.3
script:
- sbt test scripted
34 changes: 18 additions & 16 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ version := "2.1.2"

licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.html"))

scalaVersion := "2.10.6"
sbtVersion in Global := "1.0.2"

scalacOptions += "-target:jvm-1.7"
crossSbtVersions := Seq("1.0.2", "0.13.16")

scalacOptions += "-target:jvm-1.8"

libraryDependencies ++= Seq(
"de.kaufhof" %% "pillar" % "3.0.0",
"com.datastax.cassandra" % "cassandra-driver-core" % "3.0.0"
"de.kaufhof" %% "pillar" % "4.1.1",
"com.datastax.cassandra" % "cassandra-driver-core" % "3.3.0"
)

// Maven publishing info
Expand All @@ -27,19 +29,19 @@ publishTo := {
if (version.value.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

pomExtra := (
<url>https://github.com/inoio/sbt-pillar-plugin</url>
<scm>
<url>git@github.com:inoio/sbt-pillar-plugin.git</url>
<connection>scm:git:git@github.com:inoio/sbt-pillar-plugin.git</connection>
</scm>
<developers>
<developer>
<id>martin.grotzke</id>
<name>Martin Grotzke</name>
<url>https://github.com/magro</url>
</developer>
</developers>)
<scm>
<url>git@github.com:inoio/sbt-pillar-plugin.git</url>
<connection>scm:git:git@github.com:inoio/sbt-pillar-plugin.git</connection>
</scm>
<developers>
<developer>
<id>martin.grotzke</id>
<name>Martin Grotzke</name>
<url>https://github.com/magro</url>
</developer>
</developers>)
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.13.11
sbt.version=1.0.2
2 changes: 1 addition & 1 deletion project/scripted.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
libraryDependencies += { "org.scala-sbt" % "scripted-plugin" % sbtVersion.value }
libraryDependencies += { "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value }
1 change: 0 additions & 1 deletion scripted.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
ScriptedPlugin.scriptedSettings

scriptedLaunchOpts := { scriptedLaunchOpts.value ++
Seq("-Xmx1024M", "-XX:MaxPermSize=256M", "-Dplugin.version=" + version.value)
Expand Down
95 changes: 54 additions & 41 deletions src/main/scala/io/ino/sbtpillar/Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import com.datastax.driver.core.{ConsistencyLevel, QueryOptions}
import sbt.Keys._
import sbt._

import scala.collection.JavaConverters._
import scala.util.Try

object Plugin extends sbt.Plugin {
object Plugin extends sbt.AutoPlugin {

object PillarKeys {
val createKeyspace = taskKey[Unit]("Create keyspace.")
Expand All @@ -21,62 +22,71 @@ object Plugin extends sbt.Plugin {
val pillarDefaultConsistencyLevelConfigKey = settingKey[String]("Configuration key storing the consistency level for the session")
val pillarReplicationStrategyConfigKey = settingKey[String]("Configuration key storing the replication strategy to create keyspaces with")
val pillarReplicationFactorConfigKey = settingKey[String]("Configuration key storing the replication factor to create keyspaces with")
val pillarDatacenterNamesConfigKey = settingKey[String]("Configuration key storing a list of datacenter names required when using NetworkTopologyStrategy")
val pillarMigrationsDir = settingKey[File]("Path to the directory holding migration files")
val pillarExtraMigrationsDirs = settingKey[Seq[File]]("List of paths to directories holding extra migration files, applied after files from `pillarMigrationsDir`")
}

import Pillar.{withCassandraUrl, withSession}
import PillarKeys._
import com.datastax.driver.core.Session
import io.ino.sbtpillar.Plugin.Pillar.{withCassandraUrl, withSession}
import io.ino.sbtpillar.Plugin.PillarKeys._

private def taskSettings: Seq[sbt.Def.Setting[_]] = Seq(
createKeyspace := {
val log = streams.value.log
withCassandraUrl(pillarConfigFile.value, pillarConfigKey.value,
pillarReplicationStrategyConfigKey.value, pillarReplicationFactorConfigKey.value,
pillarDefaultConsistencyLevelConfigKey.value,
streams.value.log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel) =>
streams.value.log.info(s"Creating keyspace ${url.keyspace} at ${url.hosts(0)}:${url.port}")
Pillar.initialize(replicationStrategy, replicationFactor, url, streams.value.log)
pillarDatacenterNamesConfigKey.value,
log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel, datacenterNames) =>
log.info(s"Creating keyspace ${url.keyspace} at ${url.hosts.head}:${url.port}")
Pillar.initialize(replicationStrategy, replicationFactor, url, datacenterNames, log)
}
},
dropKeyspace := {
val log = streams.value.log
withCassandraUrl(pillarConfigFile.value, pillarConfigKey.value,
pillarReplicationStrategyConfigKey.value, pillarReplicationFactorConfigKey.value,
pillarDefaultConsistencyLevelConfigKey.value,
streams.value.log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel) =>
streams.value.log.info(s"Dropping keyspace ${url.keyspace} at ${url.hosts(0)}:${url.port}")
Pillar.destroy(url, streams.value.log)
pillarDatacenterNamesConfigKey.value,
log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel, datacenterNames) =>
log.info(s"Dropping keyspace ${url.keyspace} at ${url.hosts.head}:${url.port}")
Pillar.destroy(url, log)
}
},
migrate := {
val log = streams.value.log
withCassandraUrl(pillarConfigFile.value, pillarConfigKey.value,
pillarReplicationStrategyConfigKey.value, pillarReplicationFactorConfigKey.value,
pillarDefaultConsistencyLevelConfigKey.value,
streams.value.log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel) =>
pillarDatacenterNamesConfigKey.value,
log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel, datacenterNames) =>
val migrationsDirs = pillarMigrationsDir.value +: pillarExtraMigrationsDirs.value
streams.value.log.info(
s"Migrating keyspace ${url.keyspace} at ${url.hosts(0)}:${url.port} using migrations in [${migrationsDirs.mkString(",")}] with consistency $defaultConsistencyLevel")
Pillar.migrate(migrationsDirs, url, defaultConsistencyLevel, streams.value.log)
log.info(
s"Migrating keyspace ${url.keyspace} at ${url.hosts.head}:${url.port} using migrations in [${migrationsDirs.mkString(",")}] with consistency $defaultConsistencyLevel")
Pillar.migrate(migrationsDirs, url, defaultConsistencyLevel, log)
}
},
cleanMigrate := {
val log = streams.value.log
withCassandraUrl(pillarConfigFile.value, pillarConfigKey.value,
pillarReplicationStrategyConfigKey.value, pillarReplicationFactorConfigKey.value,
pillarDefaultConsistencyLevelConfigKey.value,
streams.value.log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel) =>
val host = url.hosts(0)
pillarDatacenterNamesConfigKey.value,
log) { (url, replicationStrategy, replicationFactor, defaultConsistencyLevel, datacenterNames) =>
val host = url.hosts.head

withSession(url, Some(defaultConsistencyLevel), streams.value.log) { (url, session) =>
streams.value.log.info(s"Dropping keyspace ${url.keyspace} at $host:${url.port}")
withSession(url, Some(defaultConsistencyLevel), log) { (url, session) =>
log.info(s"Dropping keyspace ${url.keyspace} at $host:${url.port}")
session.execute(s"DROP KEYSPACE IF EXISTS ${url.keyspace}")

Pillar.checkPeerSchemaVersions(session, streams.value.log)
Pillar.checkPeerSchemaVersions(session, log)

streams.value.log.info(s"Creating keyspace ${url.keyspace} at $host:${url.port}")
Pillar.initialize(session, replicationStrategy, replicationFactor, url)
log.info(s"Creating keyspace ${url.keyspace} at $host:${url.port}")
Pillar.initialize(session, replicationStrategy, replicationFactor, url, datacenterNames)

val dirs = pillarMigrationsDir.value +: pillarExtraMigrationsDirs.value
streams.value.log.info(
log.info(
s"Migrating keyspace ${url.keyspace} at $host:${url.port} using migrations in [${dirs.mkString(",")}] with consistency $defaultConsistencyLevel")
Pillar.migrate(session, dirs, url)
}
Expand All @@ -87,6 +97,7 @@ object Plugin extends sbt.Plugin {
pillarReplicationStrategyConfigKey := "cassandra.replicationStrategy",
pillarReplicationFactorConfigKey := "cassandra.replicationFactor",
pillarDefaultConsistencyLevelConfigKey := "cassandra.defaultConsistencyLevel",
pillarDatacenterNamesConfigKey := "cassandra.datacenters",
pillarConfigFile := file("conf/application.conf"),
pillarMigrationsDir := file("conf/migrations"),
pillarExtraMigrationsDirs := Seq()
Expand All @@ -102,9 +113,9 @@ object Plugin extends sbt.Plugin {

import java.nio.file.Files

import de.kaufhof.pillar._
import com.datastax.driver.core.Cluster
import com.typesafe.config.ConfigFactory
import de.kaufhof.pillar._

import scala.util.control.NonFatal

Expand All @@ -117,7 +128,8 @@ object Plugin extends sbt.Plugin {
repStrategyConfigKey: String,
repFactorConfigKey: String,
defaultConsistencyLevelConfigKey: String,
logger: Logger)(block: (CassandraUrl, String, Int, ConsistencyLevel) => Unit): Unit = {
pillarDatacenterNamesConfigKey: String,
logger: Logger)(block: (CassandraUrl, String, Int, ConsistencyLevel, List[String]) => Unit): Unit = {
val configFileMod = file(sys.env.getOrElse("PILLAR_CONFIG_FILE", configFile.getAbsolutePath))
logger.info(s"Reading config from ${configFileMod.getAbsolutePath}")
val config = ConfigFactory.parseFile(configFileMod).resolve()
Expand All @@ -127,8 +139,9 @@ object Plugin extends sbt.Plugin {
val defaultConsistencyLevel = Try(ConsistencyLevel.valueOf(config.getString(defaultConsistencyLevelConfigKey))).getOrElse(DEFAULT_DEFAULT_CONSISTENCY_LEVEL)
val replicationStrategy = Try(config.getString(repStrategyConfigKey)).getOrElse(DEFAULT_REPLICATION_STRATEGY)
val replicationFactor = Try(config.getInt(repFactorConfigKey)).getOrElse(DEFAULT_REPLICATION_FACTOR)
val datacenterNames = Try(config.getStringList(pillarDatacenterNamesConfigKey).asScala).getOrElse(List.empty).to[List]
try {
block(url, replicationStrategy, replicationFactor, defaultConsistencyLevel)
block(url, replicationStrategy, replicationFactor, defaultConsistencyLevel, datacenterNames)
} catch {
case NonFatal(e) =>
logger.error(s"An error occurred while performing task: $e")
Expand All @@ -140,7 +153,7 @@ object Plugin extends sbt.Plugin {
def withSession(url: CassandraUrl, defaultConsistencyLevel: Option[ConsistencyLevel], logger: Logger)
(block: (CassandraUrl, Session) => Unit): Unit = {

implicit val iLog = logger
implicit val iLog: sbt.Logger = logger

val queryOptions = new QueryOptions()
defaultConsistencyLevel.foreach(queryOptions.setConsistencyLevel)
Expand All @@ -166,19 +179,23 @@ object Plugin extends sbt.Plugin {
}
}

def initialize(replicationStrategy: String, replicationFactor: Int, url: CassandraUrl, logger: Logger): Unit = {
def initialize(replicationStrategy: String, replicationFactor: Int, url: CassandraUrl, datacenterNames: List[String], logger: Logger): Unit = {
withSession(url, None, logger) { (url, session) =>
initialize(session, replicationStrategy, replicationFactor, url)
initialize(session, replicationStrategy, replicationFactor, url, datacenterNames)
}
}

def initialize(session: Session, replicationStrategy: String, replicationFactor: Int, url: CassandraUrl) {
Migrator(Registry(Seq.empty)).initialize(session, url.keyspace, replicationOptionsWith(replicationStrategy, replicationFactor))
def initialize(session: Session, replicationStrategy: String, replicationFactor: Int, url: CassandraUrl, datacenterNames: List[String]) {
val replStrategy = replicationStrategy match {
case "SimpleStrategy" => SimpleStrategy(replicationFactor = replicationFactor)
case "NetworkTopologyStrategy" => NetworkTopologyStrategy(datacenterNames.map(CassandraDataCenter(_, replicationFactor)))
}
Migrator(Registry(Seq.empty), CassandraMigrator.appliedMigrationsTableNameDefault).initialize(session, url.keyspace, replStrategy)
}

def destroy(url: CassandraUrl, logger: Logger): Unit = {
withSession(url, None, logger) { (url, session) =>
Migrator(Registry(Seq.empty)).destroy(session, url.keyspace)
Migrator(Registry(Seq.empty), CassandraMigrator.appliedMigrationsTableNameDefault).destroy(session, url.keyspace)
}
}

Expand All @@ -191,17 +208,17 @@ object Plugin extends sbt.Plugin {
def migrate(session: Session, migrationsDirs: Seq[File], url: CassandraUrl): Unit = {
val registry = Registry(migrationsDirs.flatMap(loadMigrations))
session.execute(s"USE ${url.keyspace}")
Migrator(registry).migrate(session)
Migrator(registry, CassandraMigrator.appliedMigrationsTableNameDefault).migrate(session)
}

def checkPeerSchemaVersions(session: Session, logger: Logger): Unit = {
import scala.collection.JavaConversions._
val schemaByPeer = session.execute(select("peer", "schema_version").from("system", "peers")).all().map { row =>
import scala.collection.JavaConverters._
val schemaByPeer = session.execute(select("peer", "schema_version").from("system", "peers")).all().asScala.map { row =>
(row.getInet("peer"), row.getUUID("schema_version"))
}.toMap

if(schemaByPeer.values.toSet.size > 1) {
val peerSchemaVersions = schemaByPeer.map{ case (peer, schemaVersion) => s"peer: $peer, schema_version: $schemaVersion" }.mkString("\n")
if (schemaByPeer.values.toSet.size > 1) {
val peerSchemaVersions = schemaByPeer.map { case (peer, schemaVersion) => s"peer: $peer, schema_version: $schemaVersion" }.mkString("\n")
logger.warn(s"There are peers with different schema versions:\n$peerSchemaVersions")
}
}
Expand All @@ -222,7 +239,7 @@ object Plugin extends sbt.Plugin {
val parser = de.kaufhof.pillar.Parser()
val files = Path.allSubpaths(migrationsDir).map(_._1).filterNot(f => f.isDirectory || f.getName.head == '.').toSeq
if (files.nonEmpty) {
files.map {file =>
files.map { file =>
val in = Files.newInputStream(file.toPath)
try {
parser.parse(in)
Expand All @@ -235,10 +252,6 @@ object Plugin extends sbt.Plugin {
}
}

private def replicationOptionsWith(replicationStrategy: String, replicationFactor: Int): ReplicationOptions =
new ReplicationOptions(Map("class" -> replicationStrategy, "replication_factor" -> replicationFactor))


private implicit class RichClusterBuilder(builder: Cluster.Builder) {

/** Add contact points ignoring errors for single contact points.
Expand All @@ -258,7 +271,7 @@ object Plugin extends sbt.Plugin {
}
}

if(exceptions.length == addresses.length) {
if (exceptions.length == addresses.length) {
logger.error(s"All contact points failed on addContactPoint, rethrowing exception for last contact point.")
throw exceptions.head
}
Expand Down
4 changes: 2 additions & 2 deletions src/sbt-test/sbtpillar/simple/build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import io.ino._
import io.ino.sbtpillar.Plugin.PillarKeys._
import _root_.io.ino._
import _root_.io.ino.sbtpillar.Plugin.PillarKeys._

lazy val root = (project in file("."))
.settings(
Expand Down

0 comments on commit 492645a

Please sign in to comment.