diff --git a/build.sbt b/build.sbt index b7cde42056..e7b99caba7 100644 --- a/build.sbt +++ b/build.sbt @@ -133,7 +133,13 @@ lazy val webapi: Project = Project(id = "webapi", base = file("webapi")) Test / exportJars := true ) .settings( - scalacOptions ++= Seq("-feature", "-unchecked", "-deprecation", "-Yresolve-term-conflict:package"), + scalacOptions ++= Seq( + "-feature", + "-unchecked", + "-deprecation", + "-Yresolve-term-conflict:package", + "-Ymacro-annotations" + ), logLevel := Level.Info, run / javaOptions := webapiJavaRunOptions, javaAgents += Dependencies.aspectjweaver, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 44c3ffc680..5cd66fc9c1 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -20,17 +20,18 @@ object Dependencies { val jenaVersion = "4.4.0" val metricsVersion = "4.0.1" val scalaVersion = "2.13.8" - val ZioVersion = "2.0.0-RC5" + val ZioVersion = "2.0.0-RC6" val ZioHttpVersion = "2.0.0-RC4" val ZioJsonVersion = "0.3.0-RC3" - val ZioConfigVersion = "3.0.0-RC8" + val ZioConfigVersion = "3.0.0-RC9" val ZioSchemaVersion = "0.2.0-RC5" - val ZioLoggingVersion = "2.0.0-RC8" + val ZioLoggingVersion = "2.0.0-RC9" val ZioZmxVersion = "2.0.0-RC4" val ZioPreludeVersion = "1.0.0-RC13" // ZIO - all Scala 3 compatible val zio = "dev.zio" %% "zio" % ZioVersion + val zioMacros = "dev.zio" %% "zio-macros" % ZioVersion val zioHttp = "io.d11" %% "zhttp" % ZioHttpVersion val zioJson = "dev.zio" %% "zio-json" % ZioJsonVersion val zioPrelude = "dev.zio" %% "zio-prelude" % ZioPreludeVersion @@ -145,13 +146,15 @@ object Dependencies { zioHttp, zioJson, zioLogging, + zioMacros, zioPrelude, zioTest % Test, zioTestSbt % Test ) val dspApiMainLibraryDependencies = Seq( - zio + zio, + zioMacros ) val schemaApiLibraryDependencies = Seq( diff --git a/webapi/src/main/scala/org/knora/webapi/app/Main.scala b/webapi/src/main/scala/org/knora/webapi/app/Main.scala index afd81daf5a..d88b5d40ad 100644 --- a/webapi/src/main/scala/org/knora/webapi/app/Main.scala +++ b/webapi/src/main/scala/org/knora/webapi/app/Main.scala @@ -25,8 +25,12 @@ import java.util.concurrent.TimeUnit */ object Main extends scala.App with LiveCore { - // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + /** + * Unsafely creates a `Runtime` from a `ZLayer` whose resources will be + * allocated immediately, and not released until the `Runtime` is shut down or + * the end of the application. + */ + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) // The effect for building a cache service manager, a IIIF service manager, and AppConfig. val managers = for { diff --git a/webapi/src/main/scala/org/knora/webapi/core/Logging.scala b/webapi/src/main/scala/org/knora/webapi/core/Logging.scala index 9425907801..ffc9eb7c65 100644 --- a/webapi/src/main/scala/org/knora/webapi/core/Logging.scala +++ b/webapi/src/main/scala/org/knora/webapi/core/Logging.scala @@ -1,9 +1,9 @@ package org.knora.webapi.core import zio.LogLevel -import zio.RuntimeConfigAspect import zio.logging.LogFormat._ import zio.logging._ +import zio.ZLayer object Logging { val logFormat = "[correlation-id = %s] %s" @@ -12,14 +12,14 @@ object Logging { val textFormat: LogFormat = timestamp.fixed(32).color(LogColor.BLUE) |-| level.highlight.fixed(14) |-| line.highlight - val fromDebug: RuntimeConfigAspect = { + val fromDebug: ZLayer[Any, Nothing, Unit] = { console( logLevel = LogLevel.Debug, format = textFormat ) } - val fromInfo: RuntimeConfigAspect = { + val fromInfo: ZLayer[Any, Nothing, Unit] = { console( logLevel = LogLevel.Info, format = textFormat diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/api/CacheService.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/api/CacheService.scala index 77bbdee7d5..c9a0edc8c6 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/api/CacheService.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/api/CacheService.scala @@ -11,10 +11,12 @@ import org.knora.webapi.messages.admin.responder.usersmessages.UserADM import org.knora.webapi.messages.admin.responder.usersmessages.UserIdentifierADM import org.knora.webapi.messages.store.cacheservicemessages.CacheServiceStatusResponse import zio._ +import zio.macros.accessible /** * Cache Service Interface */ +@accessible trait CacheService { def putUserADM(value: UserADM): Task[Unit] def getUserADM(identifier: UserIdentifierADM): Task[Option[UserADM]] @@ -46,4 +48,3 @@ trait CacheService { * } yield () * }}} */ -object CacheService extends Accessible[CacheService] diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceInMemImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceInMemImpl.scala index 3bd7c92a28..3f66b853d0 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceInMemImpl.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceInMemImpl.scala @@ -157,8 +157,8 @@ case class CacheServiceInMemImpl( val emptyValueError = EmptyValue("The string value is empty. Aborting write to cache.") (for { - key <- if (key.isEmpty()) Task.fail(emptyKeyError) else Task.succeed(key) - value <- if (value.isEmpty()) Task.fail(emptyValueError) else Task.succeed(value) + key <- if (key.isEmpty()) ZIO.fail(emptyKeyError) else ZIO.succeed(key) + value <- if (value.isEmpty()) ZIO.fail(emptyValueError) else ZIO.succeed(value) _ <- lut.put(key, value).commit } yield ()).tap(_ => ZIO.logDebug(s"Wrote key: $key with value: $value to cache.")) } @@ -196,7 +196,7 @@ case class CacheServiceInMemImpl( * Pings the in-memory cache to see if it is available. */ def ping(): Task[CacheServiceStatusResponse] = - Task.succeed(CacheServiceStatusOK) + ZIO.succeed(CacheServiceStatusOK) } /** diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceRedisImpl.scala index d26bb2fa44..a2ec8f9962 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceRedisImpl.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/impl/CacheServiceRedisImpl.scala @@ -147,7 +147,7 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { * @param key the key. * @param value the value. */ - def putStringValue(key: String, value: String): Task[Unit] = Task.attempt { + def putStringValue(key: String, value: String): Task[Unit] = ZIO.attempt { if (key.isEmpty) throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.") @@ -176,18 +176,18 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { conn <- ZIO.attempt(pool.getResource) value <- ZIO.attemptBlocking(conn.get(key)) res <- - if (value == "nil".getBytes) Task.succeed(None) - else Task.succeed(Some(value)) + if (value == "nil".getBytes) ZIO.succeed(None) + else ZIO.succeed(Some(value)) _ = conn.close() } yield res - }.catchAll(ex => ZIO.logError(s"Reading string from Redis failed: ${ex.getMessage}") *> Task.succeed(None)) + }.catchAll(ex => ZIO.logError(s"Reading string from Redis failed: ${ex.getMessage}") *> ZIO.succeed(None)) /** * Removes values for the provided keys. Any invalid keys are ignored. * * @param keys the keys. */ - def removeValues(keys: Set[String]): Task[Unit] = Task.attemptBlocking { + def removeValues(keys: Set[String]): Task[Unit] = ZIO.attemptBlocking { // del takes a vararg so I nee to convert the set to a swq and then to vararg val conn: Jedis = pool.getResource @@ -206,7 +206,7 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { * @param key the key. * @param value the value. */ - private def putBytesValue(key: String, value: Array[Byte]): Task[Unit] = Task.attemptBlocking { + private def putBytesValue(key: String, value: Array[Byte]): Task[Unit] = ZIO.attemptBlocking { if (key.isEmpty) throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.") @@ -236,15 +236,15 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { conn <- ZIO.attempt(pool.getResource).onError(ZIO.logErrorCause(_)).orDie value <- ZIO.attemptBlocking(conn.get(key.getBytes)) res <- - if (value == "nil".getBytes) Task.succeed(None) - else Task.succeed(Some(value)) + if (value == "nil".getBytes) ZIO.succeed(None) + else ZIO.succeed(Some(value)) _ = conn.close() } yield res /** * Flushes (removes) all stored content from the Redis store. */ - def flushDB(requestingUser: UserADM): Task[Unit] = Task.attemptBlocking { + def flushDB(requestingUser: UserADM): Task[Unit] = ZIO.attemptBlocking { if (!requestingUser.isSystemUser) { throw ForbiddenException("Only the system user is allowed to perform this operation.") @@ -265,7 +265,7 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { /** * Pings the Redis store to see if it is available. */ - def ping(): Task[CacheServiceStatusResponse] = Task.attemptBlocking { + def ping(): Task[CacheServiceStatusResponse] = ZIO.attemptBlocking { val conn: Jedis = pool.getResource try { @@ -274,7 +274,7 @@ case class CacheServiceRedisImpl(pool: JedisPool) extends CacheService { } finally { conn.close() } - }.catchAll(ex => ZIO.logError(s"Ping failed: ${ex.getMessage}") *> Task.succeed(CacheServiceStatusNOK)) + }.catchAll(ex => ZIO.logError(s"Ping failed: ${ex.getMessage}") *> ZIO.succeed(CacheServiceStatusNOK)) } object CacheServiceRedisImpl { diff --git a/webapi/src/main/scala/org/knora/webapi/store/iiif/api/IIIFService.scala b/webapi/src/main/scala/org/knora/webapi/store/iiif/api/IIIFService.scala index a42f1fbd88..7475033114 100644 --- a/webapi/src/main/scala/org/knora/webapi/store/iiif/api/IIIFService.scala +++ b/webapi/src/main/scala/org/knora/webapi/store/iiif/api/IIIFService.scala @@ -9,7 +9,9 @@ import org.knora.webapi.messages.store.sipimessages.SipiGetTextFileRequest import org.knora.webapi.messages.store.sipimessages.SipiGetTextFileResponse import org.knora.webapi.messages.v2.responder.SuccessResponseV2 import zio._ +import zio.macros.accessible +@accessible trait IIIFService { /** @@ -50,5 +52,3 @@ trait IIIFService { */ def getStatus(): Task[IIIFServiceStatusResponse] } - -object IIIFService extends Accessible[IIIFService] diff --git a/webapi/src/main/scala/org/knora/webapi/util/ActorUtil.scala b/webapi/src/main/scala/org/knora/webapi/util/ActorUtil.scala index 5ffd380673..12be970f84 100644 --- a/webapi/src/main/scala/org/knora/webapi/util/ActorUtil.scala +++ b/webapi/src/main/scala/org/knora/webapi/util/ActorUtil.scala @@ -25,6 +25,13 @@ import scala.util.Try object ActorUtil { + /** + * Unsafely creates a `Runtime` from a `ZLayer` whose resources will be + * allocated immediately, and not released until the `Runtime` is shut down or + * the end of the application. + */ + private val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) + /** * Transforms ZIO Task returned to the receive method of an actor to a message. Used mainly during the refactoring * phase, to be able to return ZIO inside an Actor. @@ -37,7 +44,7 @@ object ActorUtil { * Since this is the "edge" of the ZIO world for now, we need to log all errors that ZIO has potentially accumulated */ def zio2Message[A](sender: ActorRef, zioTask: zio.Task[A], log: LoggingAdapter, appConfig: AppConfig): Unit = - Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + runtime .unsafeRunTask( zioTask.foldCauseZIO(cause => handleCause(cause, sender), success => ZIO.succeed(sender ! success)) ) diff --git a/webapi/src/test/scala/org/knora/webapi/AsyncCoreSpec.scala b/webapi/src/test/scala/org/knora/webapi/AsyncCoreSpec.scala index 277b2402a3..08027f4051 100644 --- a/webapi/src/test/scala/org/knora/webapi/AsyncCoreSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/AsyncCoreSpec.scala @@ -52,7 +52,6 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AsyncWordSpecLike import zio.& import zio.Runtime -import zio.RuntimeConfig import zio.ZEnvironment import zio.ZIO import zio.ZLayer @@ -117,7 +116,7 @@ abstract class AsyncCoreSpec(_system: ActorSystem) val log: LoggingAdapter = akka.event.Logging(system, this.getClass) // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) // The effect for building a cache service manager and a IIIF service manager. val managers = for { diff --git a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala index 5d35e1b1c1..c4e7c9f791 100644 --- a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala @@ -30,7 +30,6 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import zio.& import zio.Runtime -import zio.RuntimeConfig import zio.ZEnvironment import zio.ZIO import zio.ZLayer @@ -130,7 +129,7 @@ abstract class CoreSpec(_system: ActorSystem) val log: LoggingAdapter = akka.event.Logging(system, this.getClass) // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) // The effect for building a cache service manager and a IIIF service manager. val managers = for { diff --git a/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala index 50cabdd1ab..e23feb2d10 100644 --- a/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala @@ -50,7 +50,6 @@ import org.scalatest.wordspec.AnyWordSpecLike import spray.json._ import zio.& import zio.Runtime -import zio.RuntimeConfig import zio.ZEnvironment import zio.ZIO import zio.ZLayer @@ -116,7 +115,7 @@ class E2ESpec(_system: ActorSystem) val log: LoggingAdapter = akka.event.Logging(system, this.getClass) // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) // The effect for building a cache service manager and a IIIF service manager. lazy val managers = for { diff --git a/webapi/src/test/scala/org/knora/webapi/ITKnoraLiveSpec.scala b/webapi/src/test/scala/org/knora/webapi/ITKnoraLiveSpec.scala index a6a88f3495..6e5e64ed79 100644 --- a/webapi/src/test/scala/org/knora/webapi/ITKnoraLiveSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/ITKnoraLiveSpec.scala @@ -46,7 +46,6 @@ import org.scalatest.wordspec.AnyWordSpecLike import spray.json._ import zio.& import zio.Runtime -import zio.RuntimeConfig import zio.ZEnvironment import zio.ZIO import zio.ZLayer @@ -106,7 +105,7 @@ class ITKnoraLiveSpec(_system: ActorSystem) val log: LoggingAdapter = akka.event.Logging(system, this.getClass) // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) /** * The effect for building a cache service manager, a IIIF service manager, diff --git a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala index d114b5d4ea..6528385217 100644 --- a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala @@ -50,7 +50,6 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike import zio.& import zio.Runtime -import zio.RuntimeConfig import zio.ZEnvironment import zio.ZIO import zio.ZLayer @@ -106,7 +105,7 @@ class R2RSpec implicit val timeout: Timeout = Timeout(settings.defaultTimeout) // The ZIO runtime used to run functional effects - val runtime = Runtime(ZEnvironment.empty, RuntimeConfig.default @@ Logging.fromInfo) + val runtime = Runtime.unsafeFromLayer(Logging.fromInfo) // The effect for building a cache service manager and a IIIF service manager. lazy val managers = for { diff --git a/webapi/src/test/scala/org/knora/webapi/config/AppConfigSpec.scala b/webapi/src/test/scala/org/knora/webapi/config/AppConfigSpec.scala index 32d22b9d3f..057ad0a388 100644 --- a/webapi/src/test/scala/org/knora/webapi/config/AppConfigSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/config/AppConfigSpec.scala @@ -8,7 +8,7 @@ import scala.concurrent.duration.FiniteDuration object AppConfigSpec extends ZIOSpec[AppConfig] { - val layer = ZLayer.make[AppConfig](AppConfig.live) + val bootstrap = ZLayer.make[AppConfig](AppConfig.live) def spec = suite("ApplicationConfigSpec")( test("successfully provide the application configuration") { diff --git a/webapi/src/test/scala/org/knora/webapi/it/v2/KnoraSipiIntegrationV2ITSpec.scala b/webapi/src/test/scala/org/knora/webapi/it/v2/KnoraSipiIntegrationV2ITSpec.scala index 0f0a9b44da..f973958059 100644 --- a/webapi/src/test/scala/org/knora/webapi/it/v2/KnoraSipiIntegrationV2ITSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/it/v2/KnoraSipiIntegrationV2ITSpec.scala @@ -413,8 +413,6 @@ class KnoraSipiIntegrationV2ITSpec loginToken = lr.token loginToken.nonEmpty should be(true) - - logger.debug("token: {}", loginToken) } "create a resource with a still image file" in { diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheInMemImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheInMemImplSpec.scala index a090267176..85298bac6d 100644 --- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheInMemImplSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheInMemImplSpec.scala @@ -39,35 +39,35 @@ object CacheInMemImplSpec extends ZIOSpec[CacheService] { /** * Defines a layer which encompases all dependencies that are needed for - * for running the tests. + * running the tests. `bootstrap` overrides the base layer of ZIOApp. */ - val layer = ZLayer.make[CacheService](CacheServiceInMemImpl.layer) + val bootstrap = ZLayer.make[CacheService](CacheServiceInMemImpl.layer) def spec = (userTests + projectTests + otherTests) val userTests = suite("CacheInMemImplSpec - user")( test("successfully store a user and retrieve by IRI") { for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))) - } yield assert(retrievedUser)(equalTo(Some(user))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeIri = Some(user.id))) + } yield assertTrue(retrievedUser == Some(user)) } + test("successfully store a user and retrieve by USERNAME")( for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username))) } yield assert(retrievedUser)(equalTo(Some(user))) ) + test("successfully store a user and retrieve by EMAIL")( for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email))) } yield assert(retrievedUser)(equalTo(Some(user))) ) + test("successfully store and retrieve a user with special characters in his name")( for { - _ <- CacheService(_.putUserADM(userWithApostrophe)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeIri = Some(userWithApostrophe.id)))) + _ <- CacheService.putUserADM(userWithApostrophe) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeIri = Some(userWithApostrophe.id))) } yield assert(retrievedUser)(equalTo(Some(userWithApostrophe))) ) ) @@ -75,22 +75,22 @@ object CacheInMemImplSpec extends ZIOSpec[CacheService] { val projectTests = suite("CacheInMemImplSpec - project")( test("successfully store a project and retrieve by IRI")( for { - _ <- CacheService(_.putProjectADM(project)) - retrievedProject <- CacheService(_.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))) + _ <- CacheService.putProjectADM(project) + retrievedProject <- CacheService.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id))) } yield assert(retrievedProject)(equalTo(Some(project))) ) + test("successfully store a project and retrieve by SHORTCODE")( for { - _ <- CacheService(_.putProjectADM(project)) + _ <- CacheService.putProjectADM(project) retrievedProject <- - CacheService(_.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))) + CacheService.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode))) } yield assert(retrievedProject)(equalTo(Some(project))) ) + test("successfully store a project and retrieve by SHORTNAME")( for { - _ <- CacheService(_.putProjectADM(project)) + _ <- CacheService.putProjectADM(project) retrievedProject <- - CacheService(_.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))) + CacheService.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname))) } yield assert(retrievedProject)(equalTo(Some(project))) ) ) @@ -98,15 +98,15 @@ object CacheInMemImplSpec extends ZIOSpec[CacheService] { val otherTests = suite("CacheInMemImplSpec - other")( test("successfully store string value")( for { - _ <- CacheService(_.putStringValue("my-new-key", "my-new-value")) - retrievedValue <- CacheService(_.getStringValue("my-new-key")) + _ <- CacheService.putStringValue("my-new-key", "my-new-value") + retrievedValue <- CacheService.getStringValue("my-new-key") } yield assert(retrievedValue)(equalTo(Some("my-new-value"))) ) + test("successfully delete stored value")( for { - _ <- CacheService(_.putStringValue("my-new-key", "my-new-value")) - _ <- CacheService(_.removeValues(Set("my-new-key"))) - retrievedValue <- CacheService(_.getStringValue("my-new-key")) + _ <- CacheService.putStringValue("my-new-key", "my-new-value") + _ <- CacheService.removeValues(Set("my-new-key")) + retrievedValue <- CacheService.getStringValue("my-new-key") } yield assert(retrievedValue)(equalTo(None)) ) ) diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheRedisImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheRedisImplSpec.scala index c7a04fd23a..df8746c546 100644 --- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheRedisImplSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/impl/CacheRedisImplSpec.scala @@ -32,9 +32,9 @@ object CacheRedisImplSpec extends ZIOSpec[CacheService & zio.test.Annotations] { /** * Defines a layer which encompases all dependencies that are needed for - * for running the tests. + * for running the tests. `bootstrap` overrides the base layer of ZIOApp. */ - val layer = ZLayer.make[CacheService & zio.test.Annotations]( + val bootstrap = ZLayer.make[CacheService & zio.test.Annotations]( CacheServiceRedisImpl.layer, RedisTestConfig.redisTestContainer, zio.test.Annotations.live, @@ -46,20 +46,20 @@ object CacheRedisImplSpec extends ZIOSpec[CacheService & zio.test.Annotations] { val userTests = suite("CacheRedisImplSpec - user")( test("successfully store a user and retrieve by IRI") { for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeIri = Some(user.id))) } yield assert(retrievedUser)(equalTo(Some(user))) } @@ ignore + test("successfully store a user and retrieve by USERNAME")( for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username))) } yield assert(retrievedUser)(equalTo(Some(user))) ) @@ ignore + test("successfully store a user and retrieve by EMAIL")( for { - _ <- CacheService(_.putUserADM(user)) - retrievedUser <- CacheService(_.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))) + _ <- CacheService.putUserADM(user) + retrievedUser <- CacheService.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email))) } yield assert(retrievedUser)(equalTo(Some(user))) ) @@ ignore ) @@ -67,22 +67,22 @@ object CacheRedisImplSpec extends ZIOSpec[CacheService & zio.test.Annotations] { val projectTests = suite("CacheRedisImplSpec - project")( test("successfully store a project and retrieve by IRI")( for { - _ <- CacheService(_.putProjectADM(project)) - retrievedProject <- CacheService(_.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))) + _ <- CacheService.putProjectADM(project) + retrievedProject <- CacheService.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id))) } yield assert(retrievedProject)(equalTo(Some(project))) ) + test("successfully store a project and retrieve by SHORTCODE")( for { - _ <- CacheService(_.putProjectADM(project)) + _ <- CacheService.putProjectADM(project) retrievedProject <- - CacheService(_.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))) + CacheService.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode))) } yield assert(retrievedProject)(equalTo(Some(project))) ) + test("successfully store a project and retrieve by SHORTNAME")( for { - _ <- CacheService(_.putProjectADM(project)) + _ <- CacheService.putProjectADM(project) retrievedProject <- - CacheService(_.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))) + CacheService.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname))) } yield assert(retrievedProject)(equalTo(Some(project))) ) ) diff --git a/webapi/src/test/scala/org/knora/webapi/testservices/TestClientService.scala b/webapi/src/test/scala/org/knora/webapi/testservices/TestClientService.scala index cc54ef24c0..f7e99dfb7c 100644 --- a/webapi/src/test/scala/org/knora/webapi/testservices/TestClientService.scala +++ b/webapi/src/test/scala/org/knora/webapi/testservices/TestClientService.scala @@ -300,7 +300,7 @@ final case class TestClientService(config: AppConfig, httpClient: CloseableHttpC } } -object TestClientService extends Accessible[TestClientService] { +object TestClientService { /** * Acquires a configured httpClient, backed by a connection pool,