From ff3689a762d8f693db9b469a98d0b3c389d86cf2 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Thu, 16 Nov 2023 08:59:27 +0100 Subject: [PATCH 01/13] Cross-compile for Scala 3 --- .github/workflows/ci.yml | 5 +- .gitignore | 8 +- build.sbt | 109 +++++++++++------- project/Dependencies.scala | 26 +++-- .../AuthenticationConfigImplicits.scala | 8 ++ .../LoadBalancingConfigImplicits.scala | 8 ++ .../scassandra/QueryConfigImplicits.scala | 12 ++ .../ReconnectionConfigImplicits.scala | 8 ++ .../ReplicationStrategyConfigImplicits.scala | 9 ++ .../scassandra/SocketConfigImplicits.scala | 8 ++ .../SpeculativeConfigImplicits.scala | 8 ++ .../AuthenticationConfigImplicits.scala | 8 ++ .../LoadBalancingConfigImplicits.scala | 8 ++ .../scassandra/QueryConfigImplicits.scala | 12 ++ .../ReconnectionConfigImplicits.scala | 8 ++ .../ReplicationStrategyConfigImplicits.scala | 9 ++ .../scassandra/SocketConfigImplicits.scala | 8 ++ .../SpeculativeConfigImplicits.scala | 8 ++ .../com/evolutiongaming/util/ToJava.scala | 15 +++ .../com/evolutiongaming/util/ToScala.scala | 13 +++ .../scassandra/AuthenticationConfig.scala | 7 +- .../scassandra/CassandraConfig.scala | 2 +- .../scassandra/EncodeByIdx.scala | 2 +- .../scassandra/EncodeByName.scala | 2 +- .../scassandra/LoadBalancingConfig.scala | 8 +- .../scassandra/PoolingConfig.scala | 2 +- .../scassandra/QueryConfig.scala | 10 +- .../scassandra/ReconnectionConfig.scala | 7 +- .../ReplicationStrategyConfig.scala | 9 +- .../scassandra/SocketConfig.scala | 8 +- .../SpeculativeExecutionConfig.scala | 9 +- .../evolutiongaming/scassandra/syntax.scala | 4 +- .../util/ConfigReaderFromEnum.scala | 2 +- .../evolutiongaming/scassandra/DataMock.scala | 50 ++++---- 34 files changed, 289 insertions(+), 131 deletions(-) create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala create mode 100644 scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/util/ToJava.scala create mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/util/ToScala.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 551e6ca..b89cfd8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,8 +10,9 @@ jobs: strategy: matrix: scala: - - 2.13.8 - - 2.12.17 + - 2.13.12 + - 2.12.18 + - 3.3.1 steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index 116e2ff..3e0beff 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,10 @@ project/plugins/project/ *.ipr # Mac -.DS_Store \ No newline at end of file +.DS_Store + +# Metals/Bloop/Vscode specific +.metals +metals.sbt +.bloop +.vscode \ No newline at end of file diff --git a/build.sbt b/build.sbt index 8c78cfd..dc37a69 100644 --- a/build.sbt +++ b/build.sbt @@ -1,56 +1,85 @@ import Dependencies._ +def crossSettings[T](scalaVersion: String, if3: List[T], if2: List[T]) = + CrossVersion.partialVersion(scalaVersion) match { + case Some((3, _)) => if3 + case Some((2, 12 | 13)) => if2 + case _ => Nil + } + lazy val commonSettings = Seq( organization := "com.evolutiongaming", homepage := Some(new URL("http://github.com/evolution-gaming/scassandra")), startYear := Some(2018), organizationName := "Evolution", organizationHomepage := Some(url("http://evolution.com")), - scalaVersion := crossScalaVersions.value.head, - crossScalaVersions := Seq("2.13.8", "2.12.17"), + // scalaVersion := crossScalaVersions.value.head, + scalaVersion := "3.3.1", + crossScalaVersions := Seq("2.13.12", "3.3.1", "2.12.18"), Compile / doc / scalacOptions ++= Seq("-groups", "-implicits", "-no-link-warnings"), publishTo := Some(Resolver.evolutionReleases), licenses := Seq(("MIT", url("https://opensource.org/licenses/MIT"))), releaseCrossBuild := true, - scalacOptsFailOnWarn := Some(false)) + scalacOptsFailOnWarn := Some(false), + scalacOptions ++= crossSettings( + scalaVersion.value, + if3 = List("-Ykind-projector", "-language:implicitConversions", "-explain", "-deprecation"), + if2 = List("-Xsource:3"), + )) -lazy val root = (project in file(".") - settings (name := "scassandra") - settings commonSettings - settings ( +lazy val root = (project in file(".")) + .settings(name := "scassandra") + .settings(commonSettings) + .settings( publish / skip := true, - skip / publishArtifact := true) - aggregate(scassandra, tests)) + skip / publishArtifact := true + ) + .aggregate(scassandra, tests) -lazy val scassandra = (project in file("scassandra") - settings (name := "scassandra") - settings commonSettings - settings (libraryDependencies ++= Seq( - Cats.core, - Cats.effect, - `config-tools`, - `cats-helper`, - sstream, - scalatest % Test, - nel, - `cassandra-driver`, - `executor-tools`, - Pureconfig.pureconfig, - Pureconfig.cats))) +lazy val scassandra = (project in file("scassandra")) + .settings(name := "scassandra") + .settings(commonSettings) + .settings( + libraryDependencies ++= Seq( + Cats.core, + Cats.effect, + `config-tools`, + `cats-helper`, + sstream, + scalatest % Test, + nel, + `cassandra-driver`, + `executor-tools`, + Pureconfig.cats + ) + ) + .settings( + libraryDependencies ++= crossSettings( + scalaVersion.value, + if3 = List(Pureconfig.core), + if2 = List(Pureconfig.pureconfig), + ) + ) -lazy val tests = (project in file("tests") - settings (name := "tests") - settings commonSettings - settings Seq( - publish / skip := true, - skip / publishArtifact := true, - Test / fork := true, - Test / parallelExecution := false) - dependsOn scassandra % "test->test;compile->compile" - settings (libraryDependencies ++= Seq( - `cassandra-launcher` % Test, - Slf4j.api % Test, - Slf4j.`log4j-over-slf4j` % Test, - Logback.core % Test, - Logback.classic % Test, - scalatest % Test))) +lazy val tests = (project in file("tests")) + .settings(name := "tests") + .settings(commonSettings) + .settings( + Seq( + publish / skip := true, + skip / publishArtifact := true, + Test / fork := true, + Test / parallelExecution := false + ) + ) + .dependsOn(scassandra % "test->test;compile->compile") + .settings( + libraryDependencies ++= Seq( + `testcontainers-cassandra` % Test, + Slf4j.api % Test, + Slf4j.`log4j-over-slf4j` % Test, + Logback.core % Test, + Logback.classic % Test, + scalatest % Test + ) + ) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8cd4487..9a58881 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,34 +2,36 @@ import sbt._ object Dependencies { - val `cassandra-driver` = "com.datastax.cassandra" % "cassandra-driver-core" % "3.11.3" - val scalatest = "org.scalatest" %% "scalatest" % "3.2.17" - val `executor-tools` = "com.evolutiongaming" %% "executor-tools" % "1.0.3" - val `config-tools` = "com.evolutiongaming" %% "config-tools" % "1.0.4" - val nel = "com.evolutiongaming" %% "nel" % "1.3.4" - val `cassandra-launcher` = "com.evolutiongaming" %% "cassandra-launcher" % "0.0.4" - val `cats-helper` = "com.evolutiongaming" %% "cats-helper" % "3.2.0" - val sstream = "com.evolutiongaming" %% "sstream" % "1.0.1" + val `cassandra-driver` = "com.datastax.cassandra" % "cassandra-driver-core" % "3.11.3" + val scalatest = "org.scalatest" %% "scalatest" % "3.2.17" + val `executor-tools` = "com.evolutiongaming" %% "executor-tools" % "1.0.4" + val `config-tools` = "com.evolutiongaming" %% "config-tools" % "1.0.5" + val nel = "com.evolutiongaming" %% "nel" % "1.3.5" + val `testcontainers-cassandra` = "com.dimafeng" %% "testcontainers-scala-cassandra" % "0.40.17" + val `cats-helper` = "com.evolutiongaming" %% "cats-helper" % "3.9.0" + val sstream = "com.evolutiongaming" %% "sstream" % "1.0.2" object Logback { - private val version = "1.4.3" + private val version = "1.4.11" val core = "ch.qos.logback" % "logback-core" % version val classic = "ch.qos.logback" % "logback-classic" % version } object Slf4j { - private val version = "1.7.36" + private val version = "2.0.9" val api = "org.slf4j" % "slf4j-api" % version val `log4j-over-slf4j` = "org.slf4j" % "log4j-over-slf4j" % version } object Cats { - val core = "org.typelevel" %% "cats-core" % "2.8.0" + val core = "org.typelevel" %% "cats-core" % "2.10.0" val effect = "org.typelevel" %% "cats-effect" % "3.4.8" } object Pureconfig { - private val version = "0.17.3" + private val version = "0.17.4" + + val core = "com.github.pureconfig" %% "pureconfig-core" % version val pureconfig = "com.github.pureconfig" %% "pureconfig" % version val cats = "com.github.pureconfig" %% "pureconfig-cats" % version } diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala new file mode 100644 index 0000000..133e22e --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait AuthenticationConfigImplicits { + implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = deriveReader +} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala new file mode 100644 index 0000000..4885c50 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait LoadBalancingConfigImplicits { + implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = deriveReader +} \ No newline at end of file diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala new file mode 100644 index 0000000..3c1a9d7 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala @@ -0,0 +1,12 @@ +package com.evolutiongaming.scassandra + +import com.datastax.driver.core.ConsistencyLevel +import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait QueryConfigImplicits { + implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) + + implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = deriveReader +} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala new file mode 100644 index 0000000..dd62906 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait ReconnectionConfigImplicits { + implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = deriveReader +} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala new file mode 100644 index 0000000..15805b4 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala @@ -0,0 +1,9 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader +import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* + +trait ReplicationStrategyConfigImplicits { + implicit val configReaderSimple: ConfigReader[Simple] = deriveReader +} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala new file mode 100644 index 0000000..56d2a28 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait SocketConfigImplicits { + implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = deriveReader +} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala new file mode 100644 index 0000000..a80c869 --- /dev/null +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.semiauto.deriveReader + +trait SpeculativeConfigImplicits { + implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = deriveReader +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala new file mode 100644 index 0000000..8697ebf --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait AuthenticationConfigImplicits { + implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala new file mode 100644 index 0000000..5650a09 --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait LoadBalancingConfigImplicits { + implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = ConfigReader.derived +} \ No newline at end of file diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala new file mode 100644 index 0000000..7836881 --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala @@ -0,0 +1,12 @@ +package com.evolutiongaming.scassandra + +import com.datastax.driver.core.ConsistencyLevel +import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait QueryConfigImplicits { + implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) + + implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala new file mode 100644 index 0000000..e04555c --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait ReconnectionConfigImplicits { + implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala new file mode 100644 index 0000000..e1ec112 --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala @@ -0,0 +1,9 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* +import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* + +trait ReplicationStrategyConfigImplicits { + implicit val configReaderSimple: ConfigReader[Simple] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala new file mode 100644 index 0000000..8decdbb --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait SocketConfigImplicits { + implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala new file mode 100644 index 0000000..7fc225f --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala @@ -0,0 +1,8 @@ +package com.evolutiongaming.scassandra + +import pureconfig.ConfigReader +import pureconfig.generic.derivation.default.* + +trait SpeculativeConfigImplicits { + implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = ConfigReader.derived +} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/util/ToJava.scala b/scassandra/src/main/scala-3/com/evolutiongaming/util/ToJava.scala new file mode 100644 index 0000000..f709c50 --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/util/ToJava.scala @@ -0,0 +1,15 @@ +package com.evolutiongaming.util + +import scala.jdk.CollectionConverters._ + +object ToJava { + + def from[T](collection: List[T]): java.util.Collection[T] = + collection.asJavaCollection + + def from[T](set: Set[T]): java.util.Set[T] = + set.asJava + + def from[A, B](map: Map[A, B]): java.util.Map[A, B] = + map.asJava +} \ No newline at end of file diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/util/ToScala.scala b/scassandra/src/main/scala-3/com/evolutiongaming/util/ToScala.scala new file mode 100644 index 0000000..33e2dad --- /dev/null +++ b/scassandra/src/main/scala-3/com/evolutiongaming/util/ToScala.scala @@ -0,0 +1,13 @@ +package com.evolutiongaming.util + +import scala.collection.mutable +import scala.jdk.CollectionConverters._ + +object ToScala { + + def from[T](collection: java.util.Collection[T]): Iterable[T] = + collection.asScala + + def from[A, B](map: java.util.Map[A, B]): mutable.Map[A, B] = + map.asScala +} \ No newline at end of file diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfig.scala index a314304..7cd888d 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfig.scala @@ -1,17 +1,14 @@ package com.evolutiongaming.scassandra import com.typesafe.config.Config -import pureconfig.{ConfigReader, ConfigSource} -import pureconfig.generic.semiauto.deriveReader +import pureconfig.ConfigSource /** * See [[https://docs.datastax.com/en/developer/java-driver/3.5/manual/auth/]] */ final case class AuthenticationConfig(username: String, password: Masked[String]) -object AuthenticationConfig { - - implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = deriveReader +object AuthenticationConfig extends AuthenticationConfigImplicits { def apply(username: String, password: String): AuthenticationConfig = { AuthenticationConfig(username, Masked(password)) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/CassandraConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/CassandraConfig.scala index ac6dc75..9421b3f 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/CassandraConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/CassandraConfig.scala @@ -80,7 +80,7 @@ object CassandraConfig { implicit val configReaderProtocolVersion: ConfigReader[ProtocolVersion] = ConfigReaderFromEnum(ProtocolVersion.values()) implicit val configReaderCassandraConfig: ConfigReader[CassandraConfig] = { - cursor: ConfigCursor => { + (cursor: ConfigCursor) => { for { cursor <- cursor.asObjectCursor } yield { diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByIdx.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByIdx.scala index f3b1a31..2abde4a 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByIdx.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByIdx.scala @@ -112,7 +112,7 @@ object EncodeByIdx { } implicit val localDateJEncodeByIdx: EncodeByIdx[LocalDateJ] = { - EncodeByIdx[LocalDate].contramap { a: LocalDateJ => + EncodeByIdx[LocalDate].contramap { (a: LocalDateJ) => LocalDate.fromDaysSinceEpoch(a.toEpochDay.toInt) } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByName.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByName.scala index 5961bd9..ac8c429 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByName.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/EncodeByName.scala @@ -125,7 +125,7 @@ object EncodeByName { } implicit val localDateJEncodeByName: EncodeByName[LocalDateJ] = { - EncodeByName[LocalDate].contramap { a: LocalDateJ => + EncodeByName[LocalDate].contramap { (a: LocalDateJ) => LocalDate.fromDaysSinceEpoch(a.toEpochDay.toInt) } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfig.scala index bcfad65..ecb2141 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfig.scala @@ -2,8 +2,7 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.policies.{DCAwareRoundRobinPolicy, LoadBalancingPolicy, TokenAwarePolicy} import com.typesafe.config.Config -import pureconfig.{ConfigReader, ConfigSource} -import pureconfig.generic.semiauto.deriveReader +import pureconfig.ConfigSource /** * See [[https://docs.datastax.com/en/developer/java-driver/3.5/manual/load_balancing/]] @@ -25,13 +24,10 @@ final case class LoadBalancingConfig( } } -object LoadBalancingConfig { +object LoadBalancingConfig extends LoadBalancingConfigImplicits { val Default: LoadBalancingConfig = LoadBalancingConfig() - implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = deriveReader - - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): LoadBalancingConfig = apply(config, Default) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/PoolingConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/PoolingConfig.scala index 7505a04..9f299f4 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/PoolingConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/PoolingConfig.scala @@ -35,7 +35,7 @@ object PoolingConfig { val Default: PoolingConfig = PoolingConfig() implicit val configReaderPoolingConfig: ConfigReader[PoolingConfig] = { - cursor: ConfigCursor => { + (cursor: ConfigCursor) => { for { cursor <- cursor.asObjectCursor } yield { diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfig.scala index 73f6100..4507212 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfig.scala @@ -1,10 +1,8 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.{ConsistencyLevel, QueryOptions} -import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum import com.typesafe.config.Config -import pureconfig.generic.semiauto.deriveReader -import pureconfig.{ConfigReader, ConfigSource} +import pureconfig.ConfigSource import scala.concurrent.duration._ @@ -44,14 +42,10 @@ final case class QueryConfig( } } -object QueryConfig { +object QueryConfig extends QueryConfigImplicits { val Default: QueryConfig = QueryConfig() - implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) - - implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = deriveReader - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): QueryConfig = apply(config, Default) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfig.scala index b9f512f..fce33a9 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfig.scala @@ -2,8 +2,7 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.policies.{ExponentialReconnectionPolicy, ReconnectionPolicy} import com.typesafe.config.Config -import pureconfig.{ConfigReader, ConfigSource} -import pureconfig.generic.semiauto.deriveReader +import pureconfig.ConfigSource import scala.concurrent.duration._ @@ -19,12 +18,10 @@ final case class ReconnectionConfig( } } -object ReconnectionConfig { +object ReconnectionConfig extends ReconnectionConfigImplicits { val Default: ReconnectionConfig = ReconnectionConfig() - implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = deriveReader - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): ReconnectionConfig = apply(config, Default) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala index 50a376a..93bb498 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala @@ -4,7 +4,6 @@ import com.evolutiongaming.config.ConfigHelper._ import com.evolutiongaming.nel.Nel import com.evolutiongaming.scassandra.ConfigHelpers._ import com.typesafe.config.{Config, ConfigException} -import pureconfig.generic.semiauto.deriveReader import pureconfig.{ConfigCursor, ConfigReader, ConfigSource} /** @@ -12,12 +11,12 @@ import pureconfig.{ConfigCursor, ConfigReader, ConfigSource} */ sealed trait ReplicationStrategyConfig -object ReplicationStrategyConfig { +object ReplicationStrategyConfig extends ReplicationStrategyConfigImplicits { val Default: ReplicationStrategyConfig = Simple.Default implicit val configReaderReplicationStrategyConfig: ConfigReader[ReplicationStrategyConfig] = { - cursor: ConfigCursor => { + (cursor: ConfigCursor) => { for { cursor <- cursor.asObjectCursor } yield { @@ -61,8 +60,6 @@ object ReplicationStrategyConfig { val Default: Simple = Simple() - implicit val configReaderSimple: ConfigReader[Simple] = deriveReader - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): Simple = apply(config, Default) @@ -84,7 +81,7 @@ object ReplicationStrategyConfig { val Default: NetworkTopology = NetworkTopology() implicit val configReaderNetworkTopology: ConfigReader[NetworkTopology] = { - cursor: ConfigCursor => { + (cursor: ConfigCursor) => { for { cursor <- cursor.asObjectCursor } yield { diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfig.scala index 28787ba..bf9af16 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfig.scala @@ -2,8 +2,7 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.SocketOptions import com.typesafe.config.Config -import pureconfig.{ConfigReader, ConfigSource} -import pureconfig.generic.semiauto.deriveReader +import pureconfig.ConfigSource import scala.concurrent.duration._ @@ -36,13 +35,10 @@ final case class SocketConfig( } } -object SocketConfig { +object SocketConfig extends SocketConfigImplicits { val Default: SocketConfig = SocketConfig() - implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = deriveReader - - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): SocketConfig = fromConfig(config, Default) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeExecutionConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeExecutionConfig.scala index a3074dc..423ddc9 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeExecutionConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeExecutionConfig.scala @@ -2,8 +2,7 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.policies.{ConstantSpeculativeExecutionPolicy, SpeculativeExecutionPolicy} import com.typesafe.config.Config -import pureconfig.generic.semiauto.deriveReader -import pureconfig.{ConfigReader, ConfigSource} +import pureconfig.ConfigSource import scala.concurrent.duration._ @@ -19,13 +18,10 @@ final case class SpeculativeExecutionConfig( } } -object SpeculativeExecutionConfig { +object SpeculativeExecutionConfig extends SpeculativeConfigImplicits { val Default: SpeculativeExecutionConfig = SpeculativeExecutionConfig() - implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = deriveReader - - @deprecated("use ConfigReader instead", "1.1.5") def apply(config: Config): SpeculativeExecutionConfig = fromConfig(config, Default) @@ -34,7 +30,6 @@ object SpeculativeExecutionConfig { fromConfig(config, default) } - def fromConfig(config: Config, default: => SpeculativeExecutionConfig): SpeculativeExecutionConfig = { ConfigSource.fromConfig(config).load[SpeculativeExecutionConfig] getOrElse default } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/syntax.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/syntax.scala index e4d2b8e..965b891 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/syntax.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/syntax.scala @@ -8,8 +8,6 @@ import com.evolutiongaming.scassandra.util.FromGFuture import com.evolutiongaming.sstream.FoldWhile._ import com.evolutiongaming.sstream.Stream -import scala.language.implicitConversions - object syntax { implicit class ResultSetOps(val self: ResultSet) extends AnyVal { @@ -100,7 +98,7 @@ object syntax { } - implicit def toCqlOps[A](a: A) = new ToCql.Ops.IdOps(a) + implicit def toCqlOps[A](a: A): ToCql.Ops.IdOps[A] = new ToCql.Ops.IdOps(a) implicit class ScassandraStatementOps(val self: Statement) extends AnyVal { diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/ConfigReaderFromEnum.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/ConfigReaderFromEnum.scala index 005fdbb..69670ce 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/ConfigReaderFromEnum.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/ConfigReaderFromEnum.scala @@ -30,7 +30,7 @@ object ConfigReaderFromEnum { * @param tag [[ClassTag]] needed to report a class name on failure. */ def apply[A <: Enum[A]](values: Array[A])(implicit tag: ClassTag[A]): ConfigReader[A] = { - cursor: ConfigCursor => { + (cursor: ConfigCursor) => { def fromString(str: String) = { values diff --git a/scassandra/src/test/scala/com/evolutiongaming/scassandra/DataMock.scala b/scassandra/src/test/scala/com/evolutiongaming/scassandra/DataMock.scala index 8528638..1c8db2e 100644 --- a/scassandra/src/test/scala/com/evolutiongaming/scassandra/DataMock.scala +++ b/scassandra/src/test/scala/com/evolutiongaming/scassandra/DataMock.scala @@ -32,11 +32,11 @@ case class DataMock( def setUUID(i: Int, v: UUID) = copy(byIdx = byIdx.updated(i, v)) def setInet(i: Int, v: InetAddress) = copy(byIdx = byIdx.updated(i, v)) def setList[E](i: Int, v: ListJ[E]) = copy(byIdx = byIdx.updated(i, v)) - def setList[E](i: Int, v: ListJ[E], elementsClass: Class[E]) = notSupported() - def setList[E](i: Int, v: ListJ[E], elementsType: TypeToken[E]) = notSupported() + def setList[E](i: Int, v: ListJ[E], elementsClass: Class[E]): DataMock = notSupported() + def setList[E](i: Int, v: ListJ[E], elementsType: TypeToken[E]): DataMock = notSupported() def setMap[K, V](i: Int, v: MapJ[K, V]) = copy(byIdx = byIdx.updated(i, v)) - def setMap[K, V](i: Int, v: MapJ[K, V], keysClass: Class[K], valuesClass: Class[V]) = notSupported() - def setMap[K, V](i: Int, v: MapJ[K, V], keysType: TypeToken[K], valuesType: TypeToken[V]) = notSupported() + def setMap[K, V](i: Int, v: MapJ[K, V], keysClass: Class[K], valuesClass: Class[V]): DataMock = notSupported() + def setMap[K, V](i: Int, v: MapJ[K, V], keysType: TypeToken[K], valuesType: TypeToken[V]): DataMock = notSupported() def setSet[E](i: Int, v: SetJ[E]) = copy(byIdx = byIdx.updated(i, v)) def setSet[E](i: Int, v: SetJ[E], elementsClass: Class[E]) = copy(byIdx = byIdx.updated(i, v)) def setSet[E](i: Int, v: SetJ[E], elementsType: TypeToken[E]) = copy(byIdx = byIdx.updated(i, v)) @@ -98,18 +98,18 @@ case class DataMock( def getDecimal(name: String) = byName.getOrElse(name, null).asInstanceOf[BigDecimalJ] def getUUID(name: String) = byName.getOrElse(name, null).asInstanceOf[UUID] def getInet(name: String) = byName.getOrElse(name, null).asInstanceOf[InetAddress] - def getList[T](name: String, elementsClass: Class[T]) = notSupported() - def getList[T](name: String, elementsType: TypeToken[T]) = notSupported() + def getList[T](name: String, elementsClass: Class[T]): ListJ[T] = notSupported() + def getList[T](name: String, elementsType: TypeToken[T]): ListJ[T] = notSupported() def getSet[T](name: String, elementsClass: Class[T]) = byName.getOrElse(name, null).asInstanceOf[SetJ[T]] - def getSet[T](name: String, elementsType: TypeToken[T]) = notSupported() - def getMap[K, V](name: String, keysClass: Class[K], valuesClass: Class[V]) = notSupported() - def getMap[K, V](name: String, keysType: TypeToken[K], valuesType: TypeToken[V]) = notSupported() - def getUDTValue(name: String) = notSupported() - def getTupleValue(name: String) = notSupported() - def getObject(name: String) = notSupported() - def get[T](name: String, targetClass: Class[T]) = notSupported() - def get[T](name: String, targetType: TypeToken[T]) = notSupported() - def get[T](name: String, codec: TypeCodec[T]) = byName.getOrElse(name, null).asInstanceOf[T] + def getSet[T](name: String, elementsType: TypeToken[T]): SetJ[T] = notSupported() + def getMap[K, V](name: String, keysClass: Class[K], valuesClass: Class[V]): MapJ[K, V] = notSupported() + def getMap[K, V](name: String, keysType: TypeToken[K], valuesType: TypeToken[V]): MapJ[K, V] = notSupported() + def getUDTValue(name: String): UDTValue = notSupported() + def getTupleValue(name: String): TupleValue = notSupported() + def getObject(name: String): Object = notSupported() + def get[T](name: String, targetClass: Class[T]): T = notSupported() + def get[T](name: String, targetType: TypeToken[T]): T = notSupported() + def get[T](name: String, codec: TypeCodec[T]): T = byName.getOrElse(name, null).asInstanceOf[T] def isNull(i: Int) = !byIdx.contains(i) def getBool(i: Int) = byIdx.getOrElse(i, null).asInstanceOf[Boolean] @@ -129,16 +129,16 @@ case class DataMock( def getDecimal(i: Int) = byIdx.getOrElse(i, null).asInstanceOf[BigDecimalJ] def getUUID(i: Int) = byIdx.getOrElse(i, null).asInstanceOf[UUID] def getInet(i: Int) = byIdx.getOrElse(i, null).asInstanceOf[InetAddress] - def getList[T](i: Int, elementsClass: Class[T]) = notSupported() - def getList[T](i: Int, elementsType: TypeToken[T]) = notSupported() + def getList[T](i: Int, elementsClass: Class[T]): ListJ[T] = notSupported() + def getList[T](i: Int, elementsType: TypeToken[T]): ListJ[T] = notSupported() def getSet[T](i: Int, elementsClass: Class[T]) = byIdx.getOrElse(i, null).asInstanceOf[SetJ[T]] def getSet[T](i: Int, elementsType: TypeToken[T]) = byIdx.getOrElse(i, null).asInstanceOf[SetJ[T]] - def getMap[K, V](i: Int, keysClass: Class[K], valuesClass: Class[V]) = notSupported() - def getMap[K, V](i: Int, keysType: TypeToken[K], valuesType: TypeToken[V]) = notSupported() - def getUDTValue(i: Int) = notSupported() - def getTupleValue(i: Int) = notSupported() - def getObject(i: Int) = notSupported() - def get[T](i: Int, targetClass: Class[T]) = notSupported() - def get[T](i: Int, targetType: TypeToken[T]) = notSupported() - def get[T](i: Int, codec: TypeCodec[T]) = byIdx.getOrElse(i, null).asInstanceOf[T] + def getMap[K, V](i: Int, keysClass: Class[K], valuesClass: Class[V]): MapJ[K, V] = notSupported() + def getMap[K, V](i: Int, keysType: TypeToken[K], valuesType: TypeToken[V]): MapJ[K, V] = notSupported() + def getUDTValue(i: Int): UDTValue = notSupported() + def getTupleValue(i: Int): TupleValue = notSupported() + def getObject(i: Int): Object = notSupported() + def get[T](i: Int, targetClass: Class[T]): T = notSupported() + def get[T](i: Int, targetType: TypeToken[T]): T = notSupported() + def get[T](i: Int, codec: TypeCodec[T]): T = byIdx.getOrElse(i, null).asInstanceOf[T] } From 519fbbaaf0b9607b79694883a23b26ab141d6624 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Thu, 16 Nov 2023 10:42:18 +0100 Subject: [PATCH 02/13] Use testcontainers instead of cassandra-launcher --- build.sbt | 3 +-- .../SpeculativeConfigImplicits.scala | 2 +- .../scassandra/CassandraSpec.scala | 25 +++++++++++-------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/build.sbt b/build.sbt index dc37a69..f899688 100644 --- a/build.sbt +++ b/build.sbt @@ -13,8 +13,7 @@ lazy val commonSettings = Seq( startYear := Some(2018), organizationName := "Evolution", organizationHomepage := Some(url("http://evolution.com")), - // scalaVersion := crossScalaVersions.value.head, - scalaVersion := "3.3.1", + scalaVersion := crossScalaVersions.value.head, crossScalaVersions := Seq("2.13.12", "3.3.1", "2.12.18"), Compile / doc / scalacOptions ++= Seq("-groups", "-implicits", "-no-link-warnings"), publishTo := Some(Resolver.evolutionReleases), diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala index a80c869..ea2f1a4 100644 --- a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala +++ b/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala @@ -4,5 +4,5 @@ import pureconfig.ConfigReader import pureconfig.generic.semiauto.deriveReader trait SpeculativeConfigImplicits { - implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = deriveReader + implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = deriveReader } diff --git a/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala b/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala index bb2512d..496acb3 100644 --- a/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala +++ b/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala @@ -5,13 +5,15 @@ import cats.effect.unsafe.implicits import cats.effect.{IO, Resource} import cats.implicits._ import com.datastax.driver.core.{Duration, Row} -import com.evolutiongaming.cassandra.StartCassandra +import com.dimafeng.testcontainers.CassandraContainer +import org.testcontainers.utility.DockerImageName import com.evolutiongaming.catshelper.CatsHelper._ import com.evolutiongaming.catshelper.ToTry import com.evolutiongaming.scassandra.IOSuite._ import com.evolutiongaming.scassandra.syntax._ import org.scalatest.BeforeAndAfterAll import com.evolutiongaming.sstream.Stream._ +import com.evolutiongaming.nel.Nel import scala.util.Try import org.scalatest.matchers.should.Matchers @@ -20,9 +22,18 @@ import org.scalatest.wordspec.AnyWordSpec class CassandraSpec extends AnyWordSpec with BeforeAndAfterAll with Matchers { - private val config = CassandraConfig.Default + private lazy val config = + CassandraConfig.Default.copy( + contactPoints = Nel(cassandraContainer.containerIpAddress), + port = cassandraContainer.mappedPort(9042), + ) - private lazy val shutdownCassandra = StartCassandra() + private lazy val cassandraContainer = CassandraContainer( + dockerImageNameOverride = DockerImageName.parse("cassandra:3.11.7"), + ) + + // due to test structure we need to start the container before the test suite + cassandraContainer.start() implicit val toTry: ToTry[IO] = ToTry.ioToTry(implicits.global) @@ -40,14 +51,8 @@ class CassandraSpec extends AnyWordSpec with BeforeAndAfterAll with Matchers { private lazy val (session, sessionRelease) = cluster.connect.allocated.toTry.get - override def beforeAll() = { - super.beforeAll() - shutdownCassandra - () - } - override def afterAll() = { - shutdownCassandra() + cassandraContainer.stop() super.afterAll() } From 664bc3ea19ea5a4b61f8d6a2642d7bfe71545e00 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Tue, 12 Dec 2023 15:48:33 +0100 Subject: [PATCH 03/13] Remove Scala 3 pureconfig compat --- build.sbt | 11 ++++++----- project/Dependencies.scala | 2 +- .../scassandra/AuthenticationConfigImplicits.scala | 8 -------- .../scassandra/LoadBalancingConfigImplicits.scala | 8 -------- .../scassandra/QueryConfigImplicits.scala | 12 ------------ .../scassandra/ReconnectionConfigImplicits.scala | 8 -------- .../ReplicationStrategyConfigImplicits.scala | 9 --------- .../scassandra/SocketConfigImplicits.scala | 8 -------- .../scassandra/SpeculativeConfigImplicits.scala | 8 -------- .../scassandra/AuthenticationConfigImplicits.scala | 0 .../scassandra/LoadBalancingConfigImplicits.scala | 0 .../scassandra/QueryConfigImplicits.scala | 0 .../scassandra/ReconnectionConfigImplicits.scala | 0 .../ReplicationStrategyConfigImplicits.scala | 0 .../scassandra/SocketConfigImplicits.scala | 0 .../scassandra/SpeculativeConfigImplicits.scala | 0 16 files changed, 7 insertions(+), 67 deletions(-) delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala delete mode 100644 scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/QueryConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/SocketConfigImplicits.scala (100%) rename scassandra/src/main/{scala-2 => scala}/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala (100%) diff --git a/build.sbt b/build.sbt index f899688..302600c 100644 --- a/build.sbt +++ b/build.sbt @@ -53,11 +53,12 @@ lazy val scassandra = (project in file("scassandra")) ) ) .settings( - libraryDependencies ++= crossSettings( - scalaVersion.value, - if3 = List(Pureconfig.core), - if2 = List(Pureconfig.pureconfig), - ) + libraryDependencies ++= List(Pureconfig.pureconfig) + // libraryDependencies ++= crossSettings( + // scalaVersion.value, + // if3 = List(Pureconfig.core), + // if2 = List(Pureconfig.pureconfig), + // ) ) lazy val tests = (project in file("tests")) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9a58881..f94fc96 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -29,7 +29,7 @@ object Dependencies { } object Pureconfig { - private val version = "0.17.4" + private val version = "0.17.5-SNAPSHOT" val core = "com.github.pureconfig" %% "pureconfig-core" % version val pureconfig = "com.github.pureconfig" %% "pureconfig" % version diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala deleted file mode 100644 index 8697ebf..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait AuthenticationConfigImplicits { - implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala deleted file mode 100644 index 5650a09..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait LoadBalancingConfigImplicits { - implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = ConfigReader.derived -} \ No newline at end of file diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala deleted file mode 100644 index 7836881..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/QueryConfigImplicits.scala +++ /dev/null @@ -1,12 +0,0 @@ -package com.evolutiongaming.scassandra - -import com.datastax.driver.core.ConsistencyLevel -import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait QueryConfigImplicits { - implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) - - implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala deleted file mode 100644 index e04555c..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait ReconnectionConfigImplicits { - implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala deleted file mode 100644 index e1ec112..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala +++ /dev/null @@ -1,9 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* -import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* - -trait ReplicationStrategyConfigImplicits { - implicit val configReaderSimple: ConfigReader[Simple] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala deleted file mode 100644 index 8decdbb..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SocketConfigImplicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait SocketConfigImplicits { - implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala deleted file mode 100644 index 7fc225f..0000000 --- a/scassandra/src/main/scala-3/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala +++ /dev/null @@ -1,8 +0,0 @@ -package com.evolutiongaming.scassandra - -import pureconfig.ConfigReader -import pureconfig.generic.derivation.default.* - -trait SpeculativeConfigImplicits { - implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = ConfigReader.derived -} diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/QueryConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SocketConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala diff --git a/scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala similarity index 100% rename from scassandra/src/main/scala-2/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala From c9725483e89fd19d221508f6e9d7e399f033e1cf Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 6 Mar 2024 16:06:11 +0100 Subject: [PATCH 04/13] Remove pureconfig derivation --- build.sbt | 12 ++--- .../AuthenticationConfigImplicits.scala | 4 +- .../LoadBalancingConfigImplicits.scala | 12 ++++- .../scassandra/QueryConfigImplicits.scala | 54 ++++++++++++++++++- .../ReconnectionConfigImplicits.scala | 13 ++++- .../ReplicationStrategyConfigImplicits.scala | 8 ++- .../scassandra/SocketConfigImplicits.scala | 37 ++++++++++++- .../SpeculativeConfigImplicits.scala | 13 ++++- 8 files changed, 133 insertions(+), 20 deletions(-) diff --git a/build.sbt b/build.sbt index 302600c..87ba701 100644 --- a/build.sbt +++ b/build.sbt @@ -53,12 +53,12 @@ lazy val scassandra = (project in file("scassandra")) ) ) .settings( - libraryDependencies ++= List(Pureconfig.pureconfig) - // libraryDependencies ++= crossSettings( - // scalaVersion.value, - // if3 = List(Pureconfig.core), - // if2 = List(Pureconfig.pureconfig), - // ) + libraryDependencies ++= List(Pureconfig.pureconfig), + libraryDependencies ++= crossSettings( + scalaVersion.value, + if3 = List(Pureconfig.core), + if2 = List(Pureconfig.pureconfig), + ) ) lazy val tests = (project in file("tests")) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala index 133e22e..cd398bd 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala @@ -1,8 +1,8 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader trait AuthenticationConfigImplicits { - implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = deriveReader + implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = + ConfigReader.forProduct2[AuthenticationConfig, String, Masked[String]]("username", "password")(AuthenticationConfig.apply) } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala index 4885c50..29103f4 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala @@ -1,8 +1,16 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader trait LoadBalancingConfigImplicits { - implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = deriveReader + implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = + ConfigReader.forProduct2[LoadBalancingConfig, Option[String], Option[Boolean]]("local-dc", "allow-remote-dcs-for-local-consistency-level") { + (localDc, allowRemoteDcsForLocalConsistencyLevel) => + val defaultConfig = LoadBalancingConfig() + + LoadBalancingConfig( + localDc.getOrElse(defaultConfig.localDc), + allowRemoteDcsForLocalConsistencyLevel.getOrElse(defaultConfig.allowRemoteDcsForLocalConsistencyLevel) + ) + } } \ No newline at end of file diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala index 3c1a9d7..d6aad8d 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala @@ -3,10 +3,60 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.ConsistencyLevel import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader + +import scala.concurrent.duration._ trait QueryConfigImplicits { implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) - implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = deriveReader + implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = + ConfigReader.forProduct13[ + QueryConfig, + Option[ConsistencyLevel], + Option[ConsistencyLevel], + Option[Int], + Option[Boolean], + Option[Int], + Option[Int], + Option[Int], + Option[FiniteDuration], + Option[FiniteDuration], + Option[FiniteDuration], + Option[Boolean], + Option[Boolean], + Option[Boolean] + ]( + "consistency", + "serial-consistency", + "fetch-size", + "default-idempotence", + "max-pending-refresh-node-list-requests", + "max-pending-refresh-node-requests", + "max-pending-refresh-schema-requests", + "refresh-node-list-interval", + "refresh-node-interval", + "refresh-schema-interval", + "metadata", + "re-prepare-on-up", + "prepare-on-all-hosts" + ) { (consistency, serialConsistency, fetchSize, defaultIdempotence, maxPendingRefreshNodeListRequests, maxPendingRefreshNodeRequests, maxPendingRefreshSchemaRequests, refreshNodeListInterval, refreshNodeInterval, refreshSchemaInterval, metadata, rePrepareOnUp, prepareOnAllHosts) => + val defaultConfig = QueryConfig() + + QueryConfig( + consistency.getOrElse(defaultConfig.consistency), + serialConsistency.getOrElse(defaultConfig.serialConsistency), + fetchSize.getOrElse(defaultConfig.fetchSize), + defaultIdempotence.getOrElse(defaultConfig.defaultIdempotence), + maxPendingRefreshNodeListRequests.getOrElse(defaultConfig.maxPendingRefreshNodeListRequests), + maxPendingRefreshNodeRequests.getOrElse(defaultConfig.maxPendingRefreshNodeRequests), + maxPendingRefreshSchemaRequests.getOrElse(defaultConfig.maxPendingRefreshSchemaRequests), + refreshNodeListInterval.getOrElse(defaultConfig.refreshNodeListInterval), + refreshNodeInterval.getOrElse(defaultConfig.refreshNodeInterval), + refreshSchemaInterval.getOrElse(defaultConfig.refreshSchemaInterval), + metadata.getOrElse(defaultConfig.metadata), + rePrepareOnUp.getOrElse(defaultConfig.rePrepareOnUp), + prepareOnAllHosts.getOrElse(defaultConfig.prepareOnAllHosts) + ) + } + } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala index dd62906..48051ec 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala @@ -1,8 +1,17 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader +import scala.concurrent.duration.FiniteDuration trait ReconnectionConfigImplicits { - implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = deriveReader + implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = + ConfigReader.forProduct2[ReconnectionConfig, Option[FiniteDuration], Option[FiniteDuration]]("min-delay", "max-delay") { + (minDelay, maxDelay) => + val defaultConfig = ReconnectionConfig() + + ReconnectionConfig( + minDelay.getOrElse(defaultConfig.minDelay), + maxDelay.getOrElse(defaultConfig.maxDelay) + ) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala index 15805b4..da3fafb 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala @@ -1,9 +1,13 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* trait ReplicationStrategyConfigImplicits { - implicit val configReaderSimple: ConfigReader[Simple] = deriveReader + implicit val configReaderSimple: ConfigReader[Simple] = + ConfigReader.forProduct1[Simple, Option[Int]]("replication-factor") { replicationFactor => + val defaultConfig = Simple() + + Simple(replicationFactor.getOrElse(defaultConfig.replicationFactor)) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala index 56d2a28..8eecf3d 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala @@ -1,8 +1,41 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader +import scala.concurrent.duration.FiniteDuration trait SocketConfigImplicits { - implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = deriveReader + implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = + ConfigReader.forProduct8[ + SocketConfig, + Option[FiniteDuration], + Option[FiniteDuration], + Option[Boolean], + Option[Boolean], + Option[Int], + Option[Boolean], + Option[Int], + Option[Int] + ]( + "connect-timeout", + "read-timeout", + "keep-alive", + "reuse-address", + "so-linger", + "tcp-no-delay", + "receive-buffer-size", + "send-buffer-size", + ) { (connectTimeout, readTimeout, keepAlive, reuseAddress, soLinger, tcpNoDelay, receiveBufferSize, sendBufferSize) => + val defaultConfig = SocketConfig() + + SocketConfig( + connectTimeout.getOrElse(defaultConfig.connectTimeout), + readTimeout.getOrElse(defaultConfig.readTimeout), + keepAlive.orElse(defaultConfig.keepAlive), + reuseAddress.orElse(defaultConfig.reuseAddress), + soLinger.orElse(defaultConfig.soLinger), + tcpNoDelay.orElse(defaultConfig.tcpNoDelay), + receiveBufferSize.orElse(defaultConfig.receiveBufferSize), + sendBufferSize.orElse(defaultConfig.sendBufferSize) + ) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala index ea2f1a4..c9ec18b 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala @@ -1,8 +1,17 @@ package com.evolutiongaming.scassandra import pureconfig.ConfigReader -import pureconfig.generic.semiauto.deriveReader +import scala.concurrent.duration.FiniteDuration trait SpeculativeConfigImplicits { - implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = deriveReader + implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = + ConfigReader.forProduct2[SpeculativeExecutionConfig, Option[FiniteDuration], Option[Int]]("delay", "max-executions") { + (delay, maxExecutions) => + val defaultConfig = SpeculativeExecutionConfig() + + SpeculativeExecutionConfig( + delay.getOrElse(defaultConfig.delay), + maxExecutions.getOrElse(defaultConfig.maxExecutions) + ) + } } From 5ce80861033863cc82706bdfd772183730a44e86 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 6 Mar 2024 16:09:39 +0100 Subject: [PATCH 05/13] Update pureconfig version --- build.sbt | 1 - project/Dependencies.scala | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 87ba701..f899688 100644 --- a/build.sbt +++ b/build.sbt @@ -53,7 +53,6 @@ lazy val scassandra = (project in file("scassandra")) ) ) .settings( - libraryDependencies ++= List(Pureconfig.pureconfig), libraryDependencies ++= crossSettings( scalaVersion.value, if3 = List(Pureconfig.core), diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f94fc96..2ddd149 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -29,7 +29,7 @@ object Dependencies { } object Pureconfig { - private val version = "0.17.5-SNAPSHOT" + private val version = "0.17.6" val core = "com.github.pureconfig" %% "pureconfig-core" % version val pureconfig = "com.github.pureconfig" %% "pureconfig" % version From 479b8c8c161300c37897ad10b2299c74e2cf4fca Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 6 Mar 2024 16:27:11 +0100 Subject: [PATCH 06/13] Upgrade cross scala versions --- .github/workflows/ci.yml | 6 +++--- build.sbt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b89cfd8..de733f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,9 +10,9 @@ jobs: strategy: matrix: scala: - - 2.13.12 - - 2.12.18 - - 3.3.1 + - 2.13.13 + - 2.12.19 + - 3.3.3 steps: - uses: actions/checkout@v3 diff --git a/build.sbt b/build.sbt index f899688..7197317 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,7 @@ lazy val commonSettings = Seq( organizationName := "Evolution", organizationHomepage := Some(url("http://evolution.com")), scalaVersion := crossScalaVersions.value.head, - crossScalaVersions := Seq("2.13.12", "3.3.1", "2.12.18"), + crossScalaVersions := Seq("2.13.13", "3.3.3", "2.12.19"), Compile / doc / scalacOptions ++= Seq("-groups", "-implicits", "-no-link-warnings"), publishTo := Some(Resolver.evolutionReleases), licenses := Seq(("MIT", url("https://opensource.org/licenses/MIT"))), From ef9f673b9b0032069ba287c9b4bb65ba546aea54 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 6 Mar 2024 16:33:08 +0100 Subject: [PATCH 07/13] Update sbt-scoverage --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 1803115..5601feb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.11") addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.3.11") From ac400f3827a413bbacb4c252ac75d8142cd06fe3 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Thu, 7 Mar 2024 20:12:05 +0100 Subject: [PATCH 08/13] Use cursor ConfigReaders --- .../AuthenticationConfigImplicits.scala | 12 ++- .../LoadBalancingConfigImplicits.scala | 22 +++-- .../scassandra/QueryConfigImplicits.scala | 85 ++++++++----------- .../ReconnectionConfigImplicits.scala | 23 +++-- .../ReplicationStrategyConfigImplicits.scala | 17 ++-- .../scassandra/SocketConfigImplicits.scala | 63 ++++++-------- .../SpeculativeConfigImplicits.scala | 23 ++--- .../scassandra/util/PureconfigUtils.scala | 14 +++ 8 files changed, 139 insertions(+), 120 deletions(-) create mode 100644 scassandra/src/main/scala/com/evolutiongaming/scassandra/util/PureconfigUtils.scala diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala index cd398bd..3c112ef 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/AuthenticationConfigImplicits.scala @@ -1,8 +1,18 @@ package com.evolutiongaming.scassandra +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ import pureconfig.ConfigReader trait AuthenticationConfigImplicits { implicit val configReaderAuthenticationConfig: ConfigReader[AuthenticationConfig] = - ConfigReader.forProduct2[AuthenticationConfig, String, Masked[String]]("username", "password")(AuthenticationConfig.apply) + ConfigReader.fromCursor[AuthenticationConfig] { cursor => + for { + objCur <- cursor.asObjectCursor + username <- objCur.getAt[String]("username") + password <- objCur.getAt[String]("password") + } yield AuthenticationConfig( + username = username, + password = password + ) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala index 29103f4..a081ab2 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/LoadBalancingConfigImplicits.scala @@ -1,16 +1,20 @@ package com.evolutiongaming.scassandra +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ import pureconfig.ConfigReader trait LoadBalancingConfigImplicits { - implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = - ConfigReader.forProduct2[LoadBalancingConfig, Option[String], Option[Boolean]]("local-dc", "allow-remote-dcs-for-local-consistency-level") { - (localDc, allowRemoteDcsForLocalConsistencyLevel) => - val defaultConfig = LoadBalancingConfig() + implicit val configReaderLoadBalancingConfig: ConfigReader[LoadBalancingConfig] = ConfigReader.fromCursor[LoadBalancingConfig] { cursor => + val defaultConfig = LoadBalancingConfig() + + for { + objCur <- cursor.asObjectCursor + localDc <- objCur.getAtOpt[String]("local-dc").map(_.getOrElse(defaultConfig.localDc)) + allowRemoteDcsForLocalConsistencyLevel <- objCur.getAtOpt[Boolean]("allow-remote-dcs-for-local-consistency-level").map(_.getOrElse(defaultConfig.allowRemoteDcsForLocalConsistencyLevel)) + } yield LoadBalancingConfig( + localDc = localDc, + allowRemoteDcsForLocalConsistencyLevel = allowRemoteDcsForLocalConsistencyLevel + ) + } - LoadBalancingConfig( - localDc.getOrElse(defaultConfig.localDc), - allowRemoteDcsForLocalConsistencyLevel.getOrElse(defaultConfig.allowRemoteDcsForLocalConsistencyLevel) - ) - } } \ No newline at end of file diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala index d6aad8d..efa7107 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/QueryConfigImplicits.scala @@ -2,6 +2,7 @@ package com.evolutiongaming.scassandra import com.datastax.driver.core.ConsistencyLevel import com.evolutiongaming.scassandra.util.ConfigReaderFromEnum +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ import pureconfig.ConfigReader import scala.concurrent.duration._ @@ -9,54 +10,40 @@ import scala.concurrent.duration._ trait QueryConfigImplicits { implicit val configReaderConsistencyLevel: ConfigReader[ConsistencyLevel] = ConfigReaderFromEnum(ConsistencyLevel.values()) - implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = - ConfigReader.forProduct13[ - QueryConfig, - Option[ConsistencyLevel], - Option[ConsistencyLevel], - Option[Int], - Option[Boolean], - Option[Int], - Option[Int], - Option[Int], - Option[FiniteDuration], - Option[FiniteDuration], - Option[FiniteDuration], - Option[Boolean], - Option[Boolean], - Option[Boolean] - ]( - "consistency", - "serial-consistency", - "fetch-size", - "default-idempotence", - "max-pending-refresh-node-list-requests", - "max-pending-refresh-node-requests", - "max-pending-refresh-schema-requests", - "refresh-node-list-interval", - "refresh-node-interval", - "refresh-schema-interval", - "metadata", - "re-prepare-on-up", - "prepare-on-all-hosts" - ) { (consistency, serialConsistency, fetchSize, defaultIdempotence, maxPendingRefreshNodeListRequests, maxPendingRefreshNodeRequests, maxPendingRefreshSchemaRequests, refreshNodeListInterval, refreshNodeInterval, refreshSchemaInterval, metadata, rePrepareOnUp, prepareOnAllHosts) => - val defaultConfig = QueryConfig() + implicit val configReaderQueryConfig: ConfigReader[QueryConfig] = ConfigReader.fromCursor[QueryConfig] { cursor => + val defaultConfig = QueryConfig() - QueryConfig( - consistency.getOrElse(defaultConfig.consistency), - serialConsistency.getOrElse(defaultConfig.serialConsistency), - fetchSize.getOrElse(defaultConfig.fetchSize), - defaultIdempotence.getOrElse(defaultConfig.defaultIdempotence), - maxPendingRefreshNodeListRequests.getOrElse(defaultConfig.maxPendingRefreshNodeListRequests), - maxPendingRefreshNodeRequests.getOrElse(defaultConfig.maxPendingRefreshNodeRequests), - maxPendingRefreshSchemaRequests.getOrElse(defaultConfig.maxPendingRefreshSchemaRequests), - refreshNodeListInterval.getOrElse(defaultConfig.refreshNodeListInterval), - refreshNodeInterval.getOrElse(defaultConfig.refreshNodeInterval), - refreshSchemaInterval.getOrElse(defaultConfig.refreshSchemaInterval), - metadata.getOrElse(defaultConfig.metadata), - rePrepareOnUp.getOrElse(defaultConfig.rePrepareOnUp), - prepareOnAllHosts.getOrElse(defaultConfig.prepareOnAllHosts) - ) - } + for { + objCur <- cursor.asObjectCursor + consistency <- objCur.getAtOpt[ConsistencyLevel]("consistency").map(_.getOrElse(defaultConfig.consistency)) + serialConsistency <- objCur.getAtOpt[ConsistencyLevel]("serial-consistency").map(_.getOrElse(defaultConfig.serialConsistency)) + fetchSize <- objCur.getAtOpt[Int]("fetch-size").map(_.getOrElse(defaultConfig.fetchSize)) + defaultIdempotence <- objCur.getAtOpt[Boolean]("default-idempotence").map(_.getOrElse(defaultConfig.defaultIdempotence)) + maxPendingRefreshNodeListRequests <- objCur.getAtOpt[Int]("max-pending-refresh-node-list-requests").map(_.getOrElse(defaultConfig.maxPendingRefreshNodeListRequests)) + maxPendingRefreshNodeRequests <- objCur.getAtOpt[Int]("max-pending-refresh-node-requests").map(_.getOrElse(defaultConfig.maxPendingRefreshNodeRequests)) + maxPendingRefreshSchemaRequests <- objCur.getAtOpt[Int]("max-pending-refresh-schema-requests").map(_.getOrElse(defaultConfig.maxPendingRefreshSchemaRequests)) + refreshNodeListInterval <- objCur.getAtOpt[FiniteDuration]("refresh-node-list-interval").map(_.getOrElse(defaultConfig.refreshNodeListInterval)) + refreshNodeInterval <- objCur.getAtOpt[FiniteDuration]("refresh-node-interval").map(_.getOrElse(defaultConfig.refreshNodeInterval)) + refreshSchemaInterval <- objCur.getAtOpt[FiniteDuration]("refresh-schema-interval").map(_.getOrElse(defaultConfig.refreshSchemaInterval)) + metadata <- objCur.getAtOpt[Boolean]("metadata").map(_.getOrElse(defaultConfig.metadata)) + rePrepareOnUp <- objCur.getAtOpt[Boolean]("re-prepare-on-up").map(_.getOrElse(defaultConfig.rePrepareOnUp)) + prepareOnAllHosts <- objCur.getAtOpt[Boolean]("prepare-on-all-hosts").map(_.getOrElse(defaultConfig.prepareOnAllHosts)) + + } yield QueryConfig( + consistency = consistency, + serialConsistency = serialConsistency, + fetchSize = fetchSize, + defaultIdempotence = defaultIdempotence, + maxPendingRefreshNodeListRequests = maxPendingRefreshNodeListRequests, + maxPendingRefreshNodeRequests = maxPendingRefreshNodeRequests, + maxPendingRefreshSchemaRequests = maxPendingRefreshSchemaRequests, + refreshNodeListInterval = refreshNodeListInterval, + refreshNodeInterval = refreshNodeInterval, + refreshSchemaInterval = refreshSchemaInterval, + metadata = metadata, + rePrepareOnUp = rePrepareOnUp, + prepareOnAllHosts = prepareOnAllHosts + ) + } -} +} \ No newline at end of file diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala index 48051ec..638ade7 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReconnectionConfigImplicits.scala @@ -1,17 +1,22 @@ package com.evolutiongaming.scassandra -import pureconfig.ConfigReader import scala.concurrent.duration.FiniteDuration +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ +import pureconfig.ConfigReader trait ReconnectionConfigImplicits { implicit val configReaderReconnectionConfig: ConfigReader[ReconnectionConfig] = - ConfigReader.forProduct2[ReconnectionConfig, Option[FiniteDuration], Option[FiniteDuration]]("min-delay", "max-delay") { - (minDelay, maxDelay) => - val defaultConfig = ReconnectionConfig() + ConfigReader.fromCursor[ReconnectionConfig] { cursor => + val defaultConfig = ReconnectionConfig() + + for { + objCur <- cursor.asObjectCursor + minDelay <- objCur.getAtOpt[FiniteDuration]("min-delay").map(_.getOrElse(defaultConfig.minDelay)) + maxDelay <- objCur.getAtOpt[FiniteDuration]("max-delay").map(_.getOrElse(defaultConfig.maxDelay)) + } yield ReconnectionConfig( + minDelay = minDelay, + maxDelay = maxDelay + ) + } - ReconnectionConfig( - minDelay.getOrElse(defaultConfig.minDelay), - maxDelay.getOrElse(defaultConfig.maxDelay) - ) - } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala index da3fafb..69675b6 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala @@ -1,13 +1,18 @@ package com.evolutiongaming.scassandra -import pureconfig.ConfigReader import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ +import pureconfig.ConfigReader trait ReplicationStrategyConfigImplicits { - implicit val configReaderSimple: ConfigReader[Simple] = - ConfigReader.forProduct1[Simple, Option[Int]]("replication-factor") { replicationFactor => - val defaultConfig = Simple() + implicit val configReaderSimple: ConfigReader[Simple] = ConfigReader.fromCursor[Simple] { cursor => + val defaultConfig = Simple() - Simple(replicationFactor.getOrElse(defaultConfig.replicationFactor)) - } + for { + objCur <- cursor.asObjectCursor + replicationFactor <- objCur.getAtOpt[Int]("replication-factor").map(_.getOrElse(defaultConfig.replicationFactor)) + } yield Simple( + replicationFactor = replicationFactor + ) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala index 8eecf3d..6d8602a 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SocketConfigImplicits.scala @@ -1,41 +1,32 @@ package com.evolutiongaming.scassandra -import pureconfig.ConfigReader import scala.concurrent.duration.FiniteDuration +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ +import pureconfig.ConfigReader trait SocketConfigImplicits { - implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = - ConfigReader.forProduct8[ - SocketConfig, - Option[FiniteDuration], - Option[FiniteDuration], - Option[Boolean], - Option[Boolean], - Option[Int], - Option[Boolean], - Option[Int], - Option[Int] - ]( - "connect-timeout", - "read-timeout", - "keep-alive", - "reuse-address", - "so-linger", - "tcp-no-delay", - "receive-buffer-size", - "send-buffer-size", - ) { (connectTimeout, readTimeout, keepAlive, reuseAddress, soLinger, tcpNoDelay, receiveBufferSize, sendBufferSize) => - val defaultConfig = SocketConfig() - - SocketConfig( - connectTimeout.getOrElse(defaultConfig.connectTimeout), - readTimeout.getOrElse(defaultConfig.readTimeout), - keepAlive.orElse(defaultConfig.keepAlive), - reuseAddress.orElse(defaultConfig.reuseAddress), - soLinger.orElse(defaultConfig.soLinger), - tcpNoDelay.orElse(defaultConfig.tcpNoDelay), - receiveBufferSize.orElse(defaultConfig.receiveBufferSize), - sendBufferSize.orElse(defaultConfig.sendBufferSize) - ) - } -} + implicit val configReaderSocketConfig: ConfigReader[SocketConfig] = ConfigReader.fromCursor[SocketConfig] { cursor => + val defaultConfig = SocketConfig() + + for { + objCur <- cursor.asObjectCursor + connectTimeout <- objCur.getAtOpt[FiniteDuration]("connect-timeout").map(_.getOrElse(defaultConfig.connectTimeout)) + readTimeout <- objCur.getAtOpt[FiniteDuration]("read-timeout").map(_.getOrElse(defaultConfig.readTimeout)) + keepAlive <- objCur.getAtOpt[Boolean]("keep-alive").map(_.orElse(defaultConfig.keepAlive)) + reuseAddress <- objCur.getAtOpt[Boolean]("reuse-address").map(_.orElse(defaultConfig.reuseAddress)) + soLinger <- objCur.getAtOpt[Int]("so-linger").map(_.orElse(defaultConfig.soLinger)) + tcpNoDelay <- objCur.getAtOpt[Boolean]("tcp-no-delay").map(_.orElse(defaultConfig.tcpNoDelay)) + receiveBufferSize <- objCur.getAtOpt[Int]("receive-buffer-size").map(_.orElse(defaultConfig.receiveBufferSize)) + sendBufferSize <- objCur.getAtOpt[Int]("send-buffer-size").map(_.orElse(defaultConfig.sendBufferSize)) + } yield SocketConfig( + connectTimeout = connectTimeout, + readTimeout = readTimeout, + keepAlive = keepAlive, + reuseAddress = reuseAddress, + soLinger = soLinger, + tcpNoDelay = tcpNoDelay, + receiveBufferSize = receiveBufferSize, + sendBufferSize = sendBufferSize + ) + } +} \ No newline at end of file diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala index c9ec18b..aa043e3 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/SpeculativeConfigImplicits.scala @@ -1,17 +1,20 @@ package com.evolutiongaming.scassandra -import pureconfig.ConfigReader import scala.concurrent.duration.FiniteDuration +import com.evolutiongaming.scassandra.util.PureconfigSyntax._ +import pureconfig.ConfigReader trait SpeculativeConfigImplicits { - implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = - ConfigReader.forProduct2[SpeculativeExecutionConfig, Option[FiniteDuration], Option[Int]]("delay", "max-executions") { - (delay, maxExecutions) => - val defaultConfig = SpeculativeExecutionConfig() + implicit val configReaderSpeculativeExecutionConfig: ConfigReader[SpeculativeExecutionConfig] = ConfigReader.fromCursor[SpeculativeExecutionConfig] { cursor => + val defaultConfig = SpeculativeExecutionConfig() - SpeculativeExecutionConfig( - delay.getOrElse(defaultConfig.delay), - maxExecutions.getOrElse(defaultConfig.maxExecutions) - ) - } + for { + objCur <- cursor.asObjectCursor + delay <- objCur.getAtOpt[FiniteDuration]("delay").map(_.getOrElse(defaultConfig.delay)) + maxExecutions <- objCur.getAtOpt[Int]("max-executions").map(_.getOrElse(defaultConfig.maxExecutions)) + } yield SpeculativeExecutionConfig( + delay = delay, + maxExecutions = maxExecutions + ) + } } diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/PureconfigUtils.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/PureconfigUtils.scala new file mode 100644 index 0000000..c8c4a5a --- /dev/null +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/util/PureconfigUtils.scala @@ -0,0 +1,14 @@ +package com.evolutiongaming.scassandra.util + +import pureconfig.error.ConfigReaderFailures +import pureconfig._ + +private[scassandra] object PureconfigSyntax { + implicit final class ConfigObjectCursorSyntax(val objCur: ConfigObjectCursor) extends AnyVal { + def getAt[A: ConfigReader](key: String): Either[ConfigReaderFailures, A] = + objCur.atKey(key).flatMap(ConfigReader[A].from(_)) + + def getAtOpt[A: ConfigReader](key: String): Either[ConfigReaderFailures, Option[A]] = + ConfigReader[Option[A]].from(objCur.atKeyOrUndefined(key)) + } +} \ No newline at end of file From cc286db7d5d9ffb16ef835a943dbda9a2c873f9e Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Thu, 7 Mar 2024 20:22:08 +0100 Subject: [PATCH 09/13] Move cassandraContainer up --- .../scassandra/ReplicationStrategyConfigImplicits.scala | 2 +- .../com/evolutiongaming/scassandra/CassandraSpec.scala | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala index 69675b6..600da51 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala @@ -1,6 +1,6 @@ package com.evolutiongaming.scassandra -import com.evolutiongaming.scassandra.ReplicationStrategyConfig.* +import com.evolutiongaming.scassandra.ReplicationStrategyConfig._ import com.evolutiongaming.scassandra.util.PureconfigSyntax._ import pureconfig.ConfigReader diff --git a/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala b/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala index 496acb3..4bae091 100644 --- a/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala +++ b/tests/src/test/scala/com/evolutiongaming/scassandra/CassandraSpec.scala @@ -21,6 +21,9 @@ import org.scalatest.wordspec.AnyWordSpec class CassandraSpec extends AnyWordSpec with BeforeAndAfterAll with Matchers { + private lazy val cassandraContainer = CassandraContainer( + dockerImageNameOverride = DockerImageName.parse("cassandra:3.11.7"), + ) private lazy val config = CassandraConfig.Default.copy( @@ -28,10 +31,6 @@ class CassandraSpec extends AnyWordSpec with BeforeAndAfterAll with Matchers { port = cassandraContainer.mappedPort(9042), ) - private lazy val cassandraContainer = CassandraContainer( - dockerImageNameOverride = DockerImageName.parse("cassandra:3.11.7"), - ) - // due to test structure we need to start the container before the test suite cassandraContainer.start() From 368397b51cb72faa8d92d5e8987ae689a15facbf Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Sat, 16 Mar 2024 19:56:02 +0100 Subject: [PATCH 10/13] Unit test empty ConfigReader Simple --- .../scassandra/ReplicationStrategyConfigSpec.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scassandra/src/test/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSpec.scala b/scassandra/src/test/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSpec.scala index cb4377b..214d762 100644 --- a/scassandra/src/test/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSpec.scala +++ b/scassandra/src/test/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSpec.scala @@ -24,6 +24,12 @@ class ReplicationStrategyConfigSpec extends AnyFunSuite with Matchers { ConfigSource.fromConfig(config.getConfig("simple")).load[ReplicationStrategyConfig] shouldEqual expected.asRight } + test("apply from empty simple config") { + val config = ConfigFactory.empty() + val expected = Simple() + ConfigSource.fromConfig(config).load[Simple] shouldEqual expected.asRight + } + test("apply from network topology config") { val config = ConfigFactory.parseURL(getClass.getResource("replication-strategy.conf")) val expected = NetworkTopology(Nel(DcFactor("dc1", 2), DcFactor("dc2", 3))) From 0dd53bd7eaa3e90d7b7aa68e2b31b47603748d19 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Mon, 25 Mar 2024 14:11:19 +0100 Subject: [PATCH 11/13] Set version to 5.0.3-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 5fae3e3..1610499 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "5.0.2-SNAPSHOT" +ThisBuild / version := "5.0.3-SNAPSHOT" From f175a863b920182e7ffb1af6b58b900cfafc45e0 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 27 Mar 2024 16:04:28 +0100 Subject: [PATCH 12/13] Fix ReplicationStrategyConfig#Simple binary incompat --- .../scassandra/ReplicationStrategyConfig.scala | 4 ++-- ...s.scala => ReplicationStrategyConfigSimpleImplicits.scala} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename scassandra/src/main/scala/com/evolutiongaming/scassandra/{ReplicationStrategyConfigImplicits.scala => ReplicationStrategyConfigSimpleImplicits.scala} (92%) diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala index 93bb498..71b8b4f 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfig.scala @@ -11,7 +11,7 @@ import pureconfig.{ConfigCursor, ConfigReader, ConfigSource} */ sealed trait ReplicationStrategyConfig -object ReplicationStrategyConfig extends ReplicationStrategyConfigImplicits { +object ReplicationStrategyConfig { val Default: ReplicationStrategyConfig = Simple.Default @@ -56,7 +56,7 @@ object ReplicationStrategyConfig extends ReplicationStrategyConfigImplicits { final case class Simple(replicationFactor: Int = 1) extends ReplicationStrategyConfig - object Simple { + object Simple extends ReplicationStrategyConfigSimpleImplicits { val Default: Simple = Simple() diff --git a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSimpleImplicits.scala similarity index 92% rename from scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala rename to scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSimpleImplicits.scala index 600da51..3085316 100644 --- a/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigImplicits.scala +++ b/scassandra/src/main/scala/com/evolutiongaming/scassandra/ReplicationStrategyConfigSimpleImplicits.scala @@ -4,7 +4,7 @@ import com.evolutiongaming.scassandra.ReplicationStrategyConfig._ import com.evolutiongaming.scassandra.util.PureconfigSyntax._ import pureconfig.ConfigReader -trait ReplicationStrategyConfigImplicits { +trait ReplicationStrategyConfigSimpleImplicits { implicit val configReaderSimple: ConfigReader[Simple] = ConfigReader.fromCursor[Simple] { cursor => val defaultConfig = Simple() From abb4597792bb254b18123d0a3714784d1fe83864 Mon Sep 17 00:00:00 2001 From: Grzegorz Bielski Date: Wed, 27 Mar 2024 19:53:32 +0100 Subject: [PATCH 13/13] Set version to 5.1.0-SNAPSHOT --- version.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.sbt b/version.sbt index 1610499..e302093 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -ThisBuild / version := "5.0.3-SNAPSHOT" +ThisBuild / version := "5.1.0-SNAPSHOT"