From cbda487a4a02558150254fac505e350f04b1bfce Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Sat, 5 Jun 2021 11:53:44 +0200
Subject: [PATCH 01/12] refactor (cache-service): divide into abstract and
concrete cache service implementation
---
third_party/dependencies.bzl | 2 +
webapi/BUILD.bazel | 2 +
.../knora/webapi/app/ApplicationActor.scala | 4 +-
.../scala/org/knora/webapi/app/BUILD.bazel | 2 +
.../knora/webapi/exceptions/Exceptions.scala | 4 +-
.../scala/org/knora/webapi/store/BUILD.bazel | 1 +
.../org/knora/webapi/store/StoreManager.scala | 14 +-
.../webapi/store/cacheservice/BUILD.bazel | 54 +++
.../cacheservice/CacheSerialization.scala | 4 +-
.../store/cacheservice/CacheService.scala | 42 ++
.../cacheservice/CacheServiceExceptions.scala | 29 ++
.../cacheservice/CacheServiceManager.scala | 383 ++--------------
.../store/cacheservice/redis/BUILD.bazel | 51 +++
.../redis/CacheServiceRedisImpl.scala | 422 ++++++++++++++++++
.../knora/webapi/ManagersWithMockedSipi.scala | 9 +-
.../webapi/e2e/v1/ResourcesV1R2RSpec.scala | 2 +-
.../webapi/store/MockableStoreManager.scala | 5 +-
17 files changed, 670 insertions(+), 360 deletions(-)
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheService.scala
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceExceptions.scala
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
diff --git a/third_party/dependencies.bzl b/third_party/dependencies.bzl
index 157a90001e..76b9392c0c 100644
--- a/third_party/dependencies.bzl
+++ b/third_party/dependencies.bzl
@@ -164,6 +164,8 @@ ALL_WEBAPI_MAIN_DEPENDENCIES = [
"//webapi/src/main/scala/org/knora/webapi/routing",
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
"//webapi/src/main/scala/org/knora/webapi/util",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
]
diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel
index 1839855532..b5e137ba75 100644
--- a/webapi/BUILD.bazel
+++ b/webapi/BUILD.bazel
@@ -161,6 +161,8 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/routing",
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
"//webapi/src/main/scala/org/knora/webapi/util",
# Logging
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
index 9d198065f6..5e38789a2b 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
@@ -61,6 +61,7 @@ import org.knora.webapi.routing.v1._
import org.knora.webapi.routing.v2._
import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
import org.knora.webapi.store.StoreManager
+import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
import org.knora.webapi.util.cache.CacheUtil
import redis.clients.jedis.exceptions.JedisConnectionException
@@ -69,6 +70,7 @@ import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
trait Managers {
+ implicit val system: ActorSystem
val responderManager: ActorRef
val storeManager: ActorRef
}
@@ -80,7 +82,7 @@ trait LiveManagers extends Managers {
* The actor that forwards messages to actors that deal with persistent storage.
*/
lazy val storeManager: ActorRef = context.actorOf(
- Props(new StoreManager(self) with LiveActorMaker)
+ Props(new StoreManager(appActor = self, cs = new CacheServiceRedisImpl(KnoraSettings(system))) with LiveActorMaker)
.withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
name = StoreManagerActorName
)
diff --git a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
index a561fa19d1..d73e104207 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
@@ -19,6 +19,8 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/routing",
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
"@maven//:ch_megard_akka_http_cors_2_13",
"@maven//:com_github_swagger_akka_http_swagger_akka_http_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/exceptions/Exceptions.scala b/webapi/src/main/scala/org/knora/webapi/exceptions/Exceptions.scala
index 82eb3dde5a..bca702d4d7 100644
--- a/webapi/src/main/scala/org/knora/webapi/exceptions/Exceptions.scala
+++ b/webapi/src/main/scala/org/knora/webapi/exceptions/Exceptions.scala
@@ -383,11 +383,11 @@ object InvalidApiJsonException {
}
/**
- * Indicates that the during caching with Redis something went wrong.
+ * Indicates that the during caching with the [[org.knora.webapi.store.cacheservice.CacheService]] something went wrong.
*
* @param message a description of the error.
*/
-abstract class RedisException(message: String) extends InternalServerException(message)
+abstract class CacheServiceException(message: String) extends InternalServerException(message)
/**
* Indicates that an application lock could not be acquired.
diff --git a/webapi/src/main/scala/org/knora/webapi/store/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/BUILD.bazel
index f0a8499218..bde0466e83 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/BUILD.bazel
@@ -15,6 +15,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/messages",
"//webapi/src/main/scala/org/knora/webapi/routing",
"//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
"//webapi/src/main/scala/org/knora/webapi/util",
"@maven//:com_twitter_chill_2_13",
"@maven//:com_typesafe_akka_akka_actor_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/StoreManager.scala b/webapi/src/main/scala/org/knora/webapi/store/StoreManager.scala
index f2bafb1c23..8f0725d380 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/StoreManager.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/StoreManager.scala
@@ -28,7 +28,7 @@ import org.knora.webapi.messages.store.cacheservicemessages.CacheServiceRequest
import org.knora.webapi.messages.store.sipimessages.IIIFRequest
import org.knora.webapi.messages.store.triplestoremessages.TriplestoreRequest
import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
-import org.knora.webapi.store.cacheservice.CacheServiceManager
+import org.knora.webapi.store.cacheservice.{CacheService, CacheServiceManager}
import org.knora.webapi.store.iiif.IIIFManager
import org.knora.webapi.store.triplestore.TriplestoreManager
@@ -42,7 +42,7 @@ import scala.concurrent.ExecutionContext
*
* @param appActor a reference to the main application actor.
*/
-class StoreManager(appActor: ActorRef) extends Actor with ActorLogging {
+class StoreManager(appActor: ActorRef, cs: CacheService) extends Actor with ActorLogging {
this: ActorMaker =>
/**
@@ -89,14 +89,14 @@ class StoreManager(appActor: ActorRef) extends Actor with ActorLogging {
/**
* Instantiates the Redis Manager
*/
- protected lazy val redisManager: ActorRef = makeActor(
- Props(new CacheServiceManager).withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
+ protected lazy val cacheServiceManager: ActorRef = makeActor(
+ Props(new CacheServiceManager(cs)).withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
RedisManagerActorName)
def receive: Receive = LoggingReceive {
- case tripleStoreMessage: TriplestoreRequest => triplestoreManager forward tripleStoreMessage
- case iiifMessages: IIIFRequest => iiifManager forward iiifMessages
- case redisMessages: CacheServiceRequest => redisManager forward redisMessages
+ case tripleStoreMessage: TriplestoreRequest => triplestoreManager forward tripleStoreMessage
+ case iiifMessages: IIIFRequest => iiifManager forward iiifMessages
+ case cacheServiceMessages: CacheServiceRequest => cacheServiceManager forward cacheServiceMessages
case other =>
sender ! Status.Failure(UnexpectedMessageException(s"StoreManager received an unexpected message: $other"))
}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
new file mode 100644
index 0000000000..959bf137c4
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
@@ -0,0 +1,54 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
+
+scala_library(
+ name = "cacheservice",
+ srcs = [
+ "CacheSerialization.scala",
+ "CacheService.scala",
+ "CacheServiceExceptions.scala",
+ "CacheServiceManager.scala",
+
+ ],
+ unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/exceptions",
+ "//webapi/src/main/scala/org/knora/webapi/feature",
+ "//webapi/src/main/scala/org/knora/webapi/instrumentation",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/routing",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/util",
+ "@maven//:com_twitter_chill_2_13",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_http_2_13",
+ "@maven//:com_typesafe_akka_akka_http_core_2_13",
+ "@maven//:com_typesafe_akka_akka_http_spray_json_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:commons_cli_commons_cli",
+ "@maven//:commons_codec_commons_codec",
+ "@maven//:commons_io_commons_io",
+ "@maven//:io_spray_spray_json_2_13",
+ "@maven//:org_apache_commons_commons_csv",
+ "@maven//:org_apache_commons_commons_lang3",
+ "@maven//:org_apache_commons_commons_pool2",
+ "@maven//:org_apache_httpcomponents_httpclient",
+ "@maven//:org_apache_httpcomponents_httpclient_cache",
+ "@maven//:org_apache_httpcomponents_httpcore",
+ "@maven//:org_apache_jena_apache_jena_libs",
+ "@maven//:org_apache_jena_jena_arq",
+ "@maven//:org_apache_jena_jena_base",
+ "@maven//:org_apache_jena_jena_core",
+ "@maven//:org_apache_jena_jena_tdb",
+ "@maven//:org_apache_jena_jena_text",
+ "@maven//:org_apache_lucene_lucene_core",
+ "@maven//:org_slf4j_slf4j_api",
+ "@maven//:redis_clients_jedis",
+ ],
+)
\ No newline at end of file
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala
index b2a23dff1a..1040f1af6d 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala
@@ -22,12 +22,12 @@ package org.knora.webapi.store.cacheservice
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream}
import com.twitter.chill.MeatLocker
-import org.knora.webapi.exceptions.RedisException
+import org.knora.webapi.exceptions.CacheServiceException
import org.knora.webapi.instrumentation.InstrumentationSupport
import scala.concurrent.{ExecutionContext, Future}
-case class EmptyByteArray(message: String) extends RedisException(message)
+case class EmptyByteArray(message: String) extends CacheServiceException(message)
object CacheSerialization extends InstrumentationSupport {
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheService.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheService.scala
new file mode 100644
index 0000000000..f339427102
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheService.scala
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi.store.cacheservice
+
+import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
+import org.knora.webapi.messages.store.cacheservicemessages.{CacheServiceFlushDBACK, CacheServiceStatusResponse}
+
+import scala.concurrent.{ExecutionContext, Future}
+
+/**
+ * Cache Service Interface
+ */
+trait CacheService {
+ def putUserADM(value: UserADM)(implicit ec: ExecutionContext): Future[Boolean]
+ def getUserADM(identifier: UserIdentifierADM)(implicit ec: ExecutionContext): Future[Option[UserADM]]
+ def putProjectADM(value: ProjectADM)(implicit ec: ExecutionContext): Future[Boolean]
+ def getProjectADM(identifier: ProjectIdentifierADM)(implicit ec: ExecutionContext): Future[Option[ProjectADM]]
+ def writeStringValue(key: String, value: String)(implicit ec: ExecutionContext): Future[Boolean]
+ def getStringValue(maybeKey: Option[String])(implicit ec: ExecutionContext): Future[Option[String]]
+ def removeValues(keys: Set[String])(implicit ec: ExecutionContext): Future[Boolean]
+ def flushDB(requestingUser: UserADM)(implicit ec: ExecutionContext): Future[CacheServiceFlushDBACK]
+ def ping()(implicit ec: ExecutionContext): Future[CacheServiceStatusResponse]
+}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceExceptions.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceExceptions.scala
new file mode 100644
index 0000000000..e641e75955
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceExceptions.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi.store.cacheservice
+
+import org.knora.webapi.exceptions.CacheServiceException
+
+case class EmptyKey(message: String) extends CacheServiceException(message)
+
+case class EmptyValue(message: String) extends CacheServiceException(message)
+
+case class UnsupportedValueType(message: String) extends CacheServiceException(message)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala
index eb5304b2e8..b258ab71a3 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheServiceManager.scala
@@ -20,30 +20,22 @@
package org.knora.webapi.store.cacheservice
import akka.actor.{Actor, ActorLogging, ActorSystem, Status}
-import akka.http.scaladsl.util.FastFuture
-import com.typesafe.scalalogging.{LazyLogging, Logger}
-import org.knora.webapi.exceptions.{ForbiddenException, RedisException, UnexpectedMessageException}
+import com.typesafe.scalalogging.LazyLogging
+import org.knora.webapi.exceptions.UnexpectedMessageException
import org.knora.webapi.instrumentation.InstrumentationSupport
-import org.knora.webapi.messages.admin.responder.projectsmessages.{
- ProjectADM,
- ProjectIdentifierADM,
- ProjectIdentifierType
-}
-import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM, UserIdentifierType}
+import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
import org.knora.webapi.messages.store.cacheservicemessages._
-import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl}
+import org.knora.webapi.settings.KnoraDispatchers
import org.knora.webapi.util.ActorUtil.future2Message
-import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}
import scala.concurrent.{ExecutionContext, Future}
-case class EmptyKey(message: String) extends RedisException(message)
-
-case class EmptyValue(message: String) extends RedisException(message)
-
-case class UnsupportedValueType(message: String) extends RedisException(message)
-
-class CacheServiceManager extends Actor with ActorLogging with LazyLogging with InstrumentationSupport {
+class CacheServiceManager(cs: CacheService)
+ extends Actor
+ with ActorLogging
+ with LazyLogging
+ with InstrumentationSupport {
/**
* The Knora Akka actor system.
@@ -55,38 +47,18 @@ class CacheServiceManager extends Actor with ActorLogging with LazyLogging with
*/
protected implicit val ec: ExecutionContext = context.system.dispatchers.lookup(KnoraDispatchers.KnoraActorDispatcher)
- /**
- * The Knora settings.
- */
- protected val s: KnoraSettingsImpl = KnoraSettings(context.system)
-
- /**
- * The Redis Client Pool
- */
- val pool: JedisPool = new JedisPool(new JedisPoolConfig(), s.cacheServiceRedisHost, s.cacheServiceRedisPort, 20999)
-
- // this is needed for time measurements using 'org.knora.webapi.Timing'
-
- implicit val l: Logger = logger
-
- // close the redis client pool
- override def postStop(): Unit = {
- logger.info("CacheServiceManager - shutdown in progress, initiating post stop cleanup.")
- pool.close()
- }
-
def receive = {
- case CacheServicePutUserADM(value) => future2Message(sender(), redisPutUserADM(value), log)
- case CacheServiceGetUserADM(identifier) => future2Message(sender(), redisGetUserADM(identifier), log)
- case CacheServicePutProjectADM(value) => future2Message(sender(), redisPutProjectADM(value), log)
- case CacheServiceGetProjectADM(identifier) => future2Message(sender(), redisGetProjectADM(identifier), log)
+ case CacheServicePutUserADM(value) => future2Message(sender(), putUserADM(value), log)
+ case CacheServiceGetUserADM(identifier) => future2Message(sender(), getUserADM(identifier), log)
+ case CacheServicePutProjectADM(value) => future2Message(sender(), putProjectADM(value), log)
+ case CacheServiceGetProjectADM(identifier) => future2Message(sender(), getProjectADM(identifier), log)
case CacheServicePutString(key, value) => future2Message(sender(), writeStringValue(key, value), log)
case CacheServiceGetString(key) => future2Message(sender(), getStringValue(key), log)
case CacheServiceRemoveValues(keys) => future2Message(sender(), removeValues(keys), log)
case CacheServiceFlushDB(requestingUser) => future2Message(sender(), flushDB(requestingUser), log)
case CacheServiceGetStatus => future2Message(sender(), ping(), log)
case other =>
- sender ! Status.Failure(UnexpectedMessageException(s"RedisManager received an unexpected message: $other"))
+ sender() ! Status.Failure(UnexpectedMessageException(s"RedisManager received an unexpected message: $other"))
}
/**
@@ -99,23 +71,8 @@ class CacheServiceManager extends Actor with ActorLogging with LazyLogging with
*
* @param value the stored value
*/
- private def redisPutUserADM(value: UserADM): Future[Boolean] = tracedFuture("redis-write-user") {
-
- val resultFuture = for {
- bytes: Array[Byte] <- CacheSerialization.serialize(value)
- result: Boolean <- writeBytesValue(value.id, bytes)
- // additionally store the IRI under the username and email key
- _ = writeStringValue(value.username, value.id)
- _ = writeStringValue(value.email, value.id)
- } yield result
-
- val recoverableResultFuture = resultFuture.recover {
- case e: Exception =>
- logger.warn("Aborting writing 'UserADM' to Redis - {}", e.getMessage)
- false
- }
-
- recoverableResultFuture
+ private def putUserADM(value: UserADM): Future[Boolean] = tracedFuture("caches-service-write-user") {
+ cs.putUserADM(value)
}
/**
@@ -124,49 +81,9 @@ class CacheServiceManager extends Actor with ActorLogging with LazyLogging with
*
* @param identifier the project identifier.
*/
- private def redisGetUserADM(identifier: UserIdentifierADM): Future[Option[UserADM]] =
- tracedFuture("redis-read-user") {
-
- // The data is stored under the IRI key.
- // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
- val resultFuture: Future[Option[UserADM]] = identifier.hasType match {
- case UserIdentifierType.IRI =>
- for {
- maybeBytes: Option[Array[Byte]] <- getBytesValue(identifier.toIriOption)
- maybeUser: Option[UserADM] <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeUser
-
- case UserIdentifierType.USERNAME =>
- for {
- maybeIriKey: Option[String] <- getStringValue(identifier.toUsernameOption)
- maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey)
- maybeUser: Option[UserADM] <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeUser
-
- case UserIdentifierType.EMAIL =>
- for {
- maybeIriKey: Option[String] <- getStringValue(identifier.toEmailOption)
- maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey)
- maybeUser: Option[UserADM] <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeUser
- }
-
- val recoverableResultFuture = resultFuture.recover {
- case e: Exception =>
- logger.warn("Aborting reading 'UserADM' from Redis - {}", e.getMessage)
- None
- }
-
- recoverableResultFuture
+ private def getUserADM(identifier: UserIdentifierADM): Future[Option[UserADM]] =
+ tracedFuture("cache-service-read-user") {
+ cs.getUserADM(identifier)
}
/**
@@ -179,285 +96,65 @@ class CacheServiceManager extends Actor with ActorLogging with LazyLogging with
*
* @param value the stored value
*/
- private def redisPutProjectADM(value: ProjectADM): Future[Boolean] = tracedFuture("redis-write-project") {
-
- val resultFuture = for {
- bytes: Array[Byte] <- CacheSerialization.serialize(value)
- result: Boolean <- writeBytesValue(value.id, bytes)
- _ = writeStringValue(value.shortcode, value.id)
- _ = writeStringValue(value.shortname, value.id)
- } yield result
-
- val recoverableResultFuture = resultFuture.recover {
- case e: Exception =>
- logger.warn("Aborting writing 'ProjectADM' to Redis - {}", e.getMessage)
- false
+ private def putProjectADM(value: ProjectADM)(implicit ec: ExecutionContext): Future[Boolean] =
+ tracedFuture("cache-service-write-project") {
+ cs.putProjectADM(value)
}
- recoverableResultFuture
- }
-
/**
* Retrieves the project stored under the identifier (either iri, shortname, or shortcode).
*
* @param identifier the project identifier.
*/
- private def redisGetProjectADM(identifier: ProjectIdentifierADM): Future[Option[ProjectADM]] =
+ private def getProjectADM(identifier: ProjectIdentifierADM)(
+ implicit ec: ExecutionContext): Future[Option[ProjectADM]] =
tracedFuture("redis-read-project") {
-
- // The data is stored under the IRI key.
- // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
- val resultFuture: Future[Option[ProjectADM]] = identifier.hasType match {
- case ProjectIdentifierType.IRI =>
- for {
- maybeBytes <- getBytesValue(identifier.toIriOption)
- maybeProject <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeProject
- case ProjectIdentifierType.SHORTCODE =>
- for {
- maybeIriKey <- getStringValue(identifier.toShortcodeOption)
- maybeBytes <- getBytesValue(maybeIriKey)
- maybeProject: Option[ProjectADM] <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeProject
- case ProjectIdentifierType.SHORTNAME =>
- for {
- maybeIriKey <- getStringValue(identifier.toShortnameOption)
- maybeBytes <- getBytesValue(maybeIriKey)
- maybeProject: Option[ProjectADM] <- maybeBytes match {
- case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
- case None => FastFuture.successful(None)
- }
- } yield maybeProject
- }
-
- val recoverableResultFuture = resultFuture.recover {
- case e: Exception =>
- logger.warn("Aborting reading 'ProjectADM' from Redis - {}", e.getMessage)
- None
- }
-
- recoverableResultFuture
- }
-
- /**
- * Get value stored under the key as a byte array. If no value is found
- * under the key, then a [[None]] is returned..
- *
- * @param maybeKey the key.
- */
- private def getBytesValue(maybeKey: Option[String]): Future[Option[Array[Byte]]] = {
-
- val operationFuture: Future[Option[Array[Byte]]] = maybeKey match {
- case Some(key) =>
- Future {
- val conn = pool.getResource
- try {
- Option(conn.get(key.getBytes))
- } finally {
- conn.close()
- }
- }
- case None =>
- FastFuture.successful(None)
+ cs.getProjectADM(identifier)
}
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Reading byte array from Redis failed - {}", e.getMessage)
- None
- }
-
- recoverableOperationFuture
- }
-
- /**
- * Store string or byte array value under key.
- *
- * @param key the key.
- * @param value the value.
- */
- private def writeBytesValue(key: String, value: Array[Byte]): Future[Boolean] = {
-
- if (key.isEmpty)
- throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
-
- if (value.isEmpty)
- throw EmptyValue("The byte array value is empty. Aborting writing to redis.")
-
- val operationFuture: Future[Boolean] = Future {
- val conn: Jedis = pool.getResource
- try {
- conn.set(key.getBytes, value)
- true
- } finally {
- conn.close()
- }
- }
-
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Writing to Redis failed - {}", e.getMessage)
- false
- }
-
- recoverableOperationFuture
- }
-
/**
* Get value stored under the key as a string.
*
* @param maybeKey the key.
*/
- private def getStringValue(maybeKey: Option[String]): Future[Option[String]] = {
-
- val operationFuture: Future[Option[String]] = maybeKey match {
- case Some(key) =>
- Future {
- val conn: Jedis = pool.getResource
- try {
- Option(conn.get(key))
- } finally {
- conn.close()
- }
- }
- case None =>
- FastFuture.successful(None)
- }
-
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Reading string from Redis failed, {}", e)
- None
+ private def getStringValue(maybeKey: Option[String]): Future[Option[String]] =
+ tracedFuture("cache-service-get-string") {
+ cs.getStringValue(maybeKey)
}
- recoverableOperationFuture
- }
-
/**
* Store string or byte array value under key.
*
* @param key the key.
* @param value the value.
*/
- private def writeStringValue(key: String, value: String): Future[Boolean] = {
-
- if (key.isEmpty)
- throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
-
- if (value.isEmpty)
- throw EmptyValue("The string value is empty. Aborting writing to redis.")
-
- val operationFuture: Future[Boolean] = Future {
-
- val conn: Jedis = pool.getResource
- try {
- conn.set(key, value)
- true
- } finally {
- conn.close()
- }
-
- }
-
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Writing to Redis failed - {}", e.getMessage)
- false
+ private def writeStringValue(key: String, value: String): Future[Boolean] =
+ tracedFuture("cache-service-write-string") {
+ cs.writeStringValue(key, value)
}
- recoverableOperationFuture
- }
-
/**
* Removes values for the provided keys. Any invalid keys are ignored.
*
* @param keys the keys.
*/
- private def removeValues(keys: Set[String]): Future[Boolean] = tracedFuture("redis-remove-values") {
-
- logger.debug("removeValues - {}", keys)
-
- val operationFuture: Future[Boolean] = Future {
- // del takes a vararg so I nee to convert the set to a swq and then to vararg
- val conn: Jedis = pool.getResource
- try {
- conn.del(keys.toSeq: _*)
- true
- } finally {
- conn.close()
- }
+ private def removeValues(keys: Set[String]): Future[Boolean] =
+ tracedFuture("redis-remove-values") {
+ cs.removeValues(keys)
}
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Removing keys from Redis failed.", e.getMessage)
- false
- }
-
- recoverableOperationFuture
- }
-
/**
* Flushes (removes) all stored content from the Redis store.
*/
- private def flushDB(requestingUser: UserADM): Future[CacheServiceFlushDBACK] = tracedFuture("redis-flush-db") {
-
- if (!requestingUser.isSystemUser) {
- throw ForbiddenException("Only the system user is allowed to perform this operation.")
- }
-
- val operationFuture: Future[CacheServiceFlushDBACK] = Future {
-
- val conn: Jedis = pool.getResource
- try {
- conn.flushDB()
- CacheServiceFlushDBACK()
- } finally {
- conn.close()
- }
- }
-
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- // Log any errors.
- logger.warn("Flushing DB failed", e.getMessage)
- throw e
+ private def flushDB(requestingUser: UserADM): Future[CacheServiceFlushDBACK] =
+ tracedFuture("redis-flush-db") {
+ cs.flushDB(requestingUser)
}
- recoverableOperationFuture
- }
-
/**
- * Pings the Redis store to see if it is available.
+ * Pings the cache service to see if it is available.
*/
private def ping(): Future[CacheServiceStatusResponse] = {
- val operationFuture: Future[CacheServiceStatusResponse] = Future {
-
- val conn: Jedis = pool.getResource
- try {
- conn.ping("test")
- CacheServiceStatusOK
- } finally {
- conn.close()
- }
- }
-
- val recoverableOperationFuture = operationFuture.recover {
- case e: Exception =>
- CacheServiceStatusNOK
- }
-
- recoverableOperationFuture
+ cs.ping()
}
}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
new file mode 100644
index 0000000000..0d790f740b
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -0,0 +1,51 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
+
+scala_library(
+ name = "redis",
+ srcs = [
+ "CacheServiceRedisImpl.scala",
+ ],
+ unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/exceptions",
+ "//webapi/src/main/scala/org/knora/webapi/feature",
+ "//webapi/src/main/scala/org/knora/webapi/instrumentation",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/routing",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/util",
+ "@maven//:com_twitter_chill_2_13",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_http_2_13",
+ "@maven//:com_typesafe_akka_akka_http_core_2_13",
+ "@maven//:com_typesafe_akka_akka_http_spray_json_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:commons_cli_commons_cli",
+ "@maven//:commons_codec_commons_codec",
+ "@maven//:commons_io_commons_io",
+ "@maven//:io_spray_spray_json_2_13",
+ "@maven//:org_apache_commons_commons_csv",
+ "@maven//:org_apache_commons_commons_lang3",
+ "@maven//:org_apache_commons_commons_pool2",
+ "@maven//:org_apache_httpcomponents_httpclient",
+ "@maven//:org_apache_httpcomponents_httpclient_cache",
+ "@maven//:org_apache_httpcomponents_httpcore",
+ "@maven//:org_apache_jena_apache_jena_libs",
+ "@maven//:org_apache_jena_jena_arq",
+ "@maven//:org_apache_jena_jena_base",
+ "@maven//:org_apache_jena_jena_core",
+ "@maven//:org_apache_jena_jena_tdb",
+ "@maven//:org_apache_jena_jena_text",
+ "@maven//:org_apache_lucene_lucene_core",
+ "@maven//:org_slf4j_slf4j_api",
+ "@maven//:redis_clients_jedis",
+ ],
+)
\ No newline at end of file
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
new file mode 100644
index 0000000000..8bb4860127
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
@@ -0,0 +1,422 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi.store.cacheservice.redis
+
+import akka.http.scaladsl.util.FastFuture
+import com.typesafe.scalalogging.{LazyLogging, Logger}
+import org.knora.webapi.exceptions.ForbiddenException
+import org.knora.webapi.messages.admin.responder.projectsmessages.{
+ ProjectADM,
+ ProjectIdentifierADM,
+ ProjectIdentifierType
+}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM, UserIdentifierType}
+import org.knora.webapi.messages.store.cacheservicemessages.{
+ CacheServiceFlushDBACK,
+ CacheServiceStatusNOK,
+ CacheServiceStatusOK,
+ CacheServiceStatusResponse
+}
+import org.knora.webapi.settings.KnoraSettingsImpl
+import org.knora.webapi.store.cacheservice.{CacheSerialization, CacheService, EmptyKey, EmptyValue}
+import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}
+
+import scala.concurrent.{ExecutionContext, Future}
+
+class CacheServiceRedisImpl(s: KnoraSettingsImpl) extends CacheService with LazyLogging {
+
+ /**
+ * The Redis Client Pool
+ */
+ val pool: JedisPool = new JedisPool(new JedisPoolConfig(), s.cacheServiceRedisHost, s.cacheServiceRedisPort, 20999)
+
+ // this is needed for time measurements using 'org.knora.webapi.Timing'
+
+ implicit val l: Logger = logger
+
+ /**
+ * Stores the user under the IRI and additionally the IRI under the keys of
+ * USERNAME and EMAIL:
+ *
+ * IRI -> byte array
+ * username -> IRI
+ * email -> IRI
+ *
+ * @param value the stored value
+ */
+ def putUserADM(value: UserADM)(implicit ec: ExecutionContext): Future[Boolean] = {
+ val resultFuture = for {
+ bytes: Array[Byte] <- CacheSerialization.serialize(value)
+ result: Boolean <- writeBytesValue(value.id, bytes)
+ // additionally store the IRI under the username and email key
+ _ = writeStringValue(value.username, value.id)
+ _ = writeStringValue(value.email, value.id)
+ } yield result
+
+ val recoverableResultFuture = resultFuture.recover {
+ case e: Exception =>
+ logger.warn("Aborting writing 'UserADM' to Redis - {}", e.getMessage)
+ false
+ }
+
+ recoverableResultFuture
+ }
+
+ /**
+ * Retrieves the user stored under the identifier (either iri, username,
+ * or email).
+ *
+ * @param identifier the project identifier.
+ */
+ def getUserADM(identifier: UserIdentifierADM)(implicit ec: ExecutionContext): Future[Option[UserADM]] = {
+ // The data is stored under the IRI key.
+ // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ val resultFuture: Future[Option[UserADM]] = identifier.hasType match {
+ case UserIdentifierType.IRI =>
+ for {
+ maybeBytes: Option[Array[Byte]] <- getBytesValue(identifier.toIriOption)
+ maybeUser: Option[UserADM] <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeUser
+
+ case UserIdentifierType.USERNAME =>
+ for {
+ maybeIriKey: Option[String] <- getStringValue(identifier.toUsernameOption)
+ maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey)
+ maybeUser: Option[UserADM] <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeUser
+
+ case UserIdentifierType.EMAIL =>
+ for {
+ maybeIriKey: Option[String] <- getStringValue(identifier.toEmailOption)
+ maybeBytes: Option[Array[Byte]] <- getBytesValue(maybeIriKey)
+ maybeUser: Option[UserADM] <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[UserADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeUser
+ }
+
+ val recoverableResultFuture = resultFuture.recover {
+ case e: Exception =>
+ logger.warn("Aborting reading 'UserADM' from Redis - {}", e.getMessage)
+ None
+ }
+
+ recoverableResultFuture
+ }
+
+ /**
+ * Stores the project under the IRI and additionally the IRI under the keys
+ * of SHORTCODE and SHORTNAME:
+ *
+ * IRI -> byte array
+ * shortname -> IRI
+ * shortcode -> IRI
+ *
+ * @param value the stored value
+ */
+ def putProjectADM(value: ProjectADM)(implicit ec: ExecutionContext): Future[Boolean] = {
+ val resultFuture = for {
+ bytes: Array[Byte] <- CacheSerialization.serialize(value)
+ result: Boolean <- writeBytesValue(value.id, bytes)
+ _ = writeStringValue(value.shortcode, value.id)
+ _ = writeStringValue(value.shortname, value.id)
+ } yield result
+
+ val recoverableResultFuture = resultFuture.recover {
+ case e: Exception =>
+ logger.warn("Aborting writing 'ProjectADM' to Redis - {}", e.getMessage)
+ false
+ }
+
+ recoverableResultFuture
+ }
+
+ /**
+ * Retrieves the project stored under the identifier (either iri, shortname, or shortcode).
+ *
+ * @param identifier the project identifier.
+ */
+ def getProjectADM(identifier: ProjectIdentifierADM)(implicit ec: ExecutionContext): Future[Option[ProjectADM]] = {
+
+ // The data is stored under the IRI key.
+ // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ val resultFuture: Future[Option[ProjectADM]] = identifier.hasType match {
+ case ProjectIdentifierType.IRI =>
+ for {
+ maybeBytes <- getBytesValue(identifier.toIriOption)
+ maybeProject <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeProject
+ case ProjectIdentifierType.SHORTCODE =>
+ for {
+ maybeIriKey <- getStringValue(identifier.toShortcodeOption)
+ maybeBytes <- getBytesValue(maybeIriKey)
+ maybeProject: Option[ProjectADM] <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeProject
+ case ProjectIdentifierType.SHORTNAME =>
+ for {
+ maybeIriKey <- getStringValue(identifier.toShortnameOption)
+ maybeBytes <- getBytesValue(maybeIriKey)
+ maybeProject: Option[ProjectADM] <- maybeBytes match {
+ case Some(bytes) => CacheSerialization.deserialize[ProjectADM](bytes)
+ case None => FastFuture.successful(None)
+ }
+ } yield maybeProject
+ }
+
+ val recoverableResultFuture = resultFuture.recover {
+ case e: Exception =>
+ logger.warn("Aborting reading 'ProjectADM' from Redis - {}", e.getMessage)
+ None
+ }
+
+ recoverableResultFuture
+ }
+
+ /**
+ * Store string or byte array value under key.
+ *
+ * @param key the key.
+ * @param value the value.
+ */
+ def writeStringValue(key: String, value: String)(implicit ec: ExecutionContext): Future[Boolean] = {
+
+ if (key.isEmpty)
+ throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
+
+ if (value.isEmpty)
+ throw EmptyValue("The string value is empty. Aborting writing to redis.")
+
+ val operationFuture: Future[Boolean] = Future {
+
+ val conn: Jedis = pool.getResource
+ try {
+ conn.set(key, value)
+ true
+ } finally {
+ conn.close()
+ }
+
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Writing to Redis failed - {}", e.getMessage)
+ false
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Get value stored under the key as a string.
+ *
+ * @param maybeKey the key.
+ */
+ def getStringValue(maybeKey: Option[String])(implicit ec: ExecutionContext): Future[Option[String]] = {
+
+ val operationFuture: Future[Option[String]] = maybeKey match {
+ case Some(key) =>
+ Future {
+ val conn: Jedis = pool.getResource
+ try {
+ Option(conn.get(key))
+ } finally {
+ conn.close()
+ }
+ }
+ case None =>
+ FastFuture.successful(None)
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Reading string from Redis failed, {}", e)
+ None
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Removes values for the provided keys. Any invalid keys are ignored.
+ *
+ * @param keys the keys.
+ */
+ def removeValues(keys: Set[String])(implicit ec: ExecutionContext): Future[Boolean] = {
+
+ logger.debug("removeValues - {}", keys)
+
+ val operationFuture: Future[Boolean] = Future {
+ // del takes a vararg so I nee to convert the set to a swq and then to vararg
+ val conn: Jedis = pool.getResource
+ try {
+ conn.del(keys.toSeq: _*)
+ true
+ } finally {
+ conn.close()
+ }
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Removing keys from Redis failed.", e.getMessage)
+ false
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Flushes (removes) all stored content from the Redis store.
+ */
+ def flushDB(requestingUser: UserADM)(implicit ec: ExecutionContext): Future[CacheServiceFlushDBACK] = {
+
+ if (!requestingUser.isSystemUser) {
+ throw ForbiddenException("Only the system user is allowed to perform this operation.")
+ }
+
+ val operationFuture: Future[CacheServiceFlushDBACK] = Future {
+
+ val conn: Jedis = pool.getResource
+ try {
+ conn.flushDB()
+ CacheServiceFlushDBACK()
+ } finally {
+ conn.close()
+ }
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Flushing DB failed", e.getMessage)
+ throw e
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Pings the Redis store to see if it is available.
+ */
+ def ping()(implicit ec: ExecutionContext): Future[CacheServiceStatusResponse] = {
+ val operationFuture: Future[CacheServiceStatusResponse] = Future {
+
+ val conn: Jedis = pool.getResource
+ try {
+ conn.ping("test")
+ CacheServiceStatusOK
+ } finally {
+ conn.close()
+ }
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ CacheServiceStatusNOK
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Store string or byte array value under key.
+ *
+ * @param key the key.
+ * @param value the value.
+ */
+ private def writeBytesValue(key: String, value: Array[Byte])(implicit ec: ExecutionContext): Future[Boolean] = {
+
+ if (key.isEmpty)
+ throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
+
+ if (value.isEmpty)
+ throw EmptyValue("The byte array value is empty. Aborting writing to redis.")
+
+ val operationFuture: Future[Boolean] = Future {
+ val conn: Jedis = pool.getResource
+ try {
+ conn.set(key.getBytes, value)
+ true
+ } finally {
+ conn.close()
+ }
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Writing to Redis failed - {}", e.getMessage)
+ false
+ }
+
+ recoverableOperationFuture
+ }
+
+ /**
+ * Get value stored under the key as a byte array. If no value is found
+ * under the key, then a [[None]] is returned..
+ *
+ * @param maybeKey the key.
+ */
+ private def getBytesValue(maybeKey: Option[String])(implicit ec: ExecutionContext): Future[Option[Array[Byte]]] = {
+
+ val operationFuture: Future[Option[Array[Byte]]] = maybeKey match {
+ case Some(key) =>
+ Future {
+ val conn = pool.getResource
+ try {
+ Option(conn.get(key.getBytes))
+ } finally {
+ conn.close()
+ }
+ }
+ case None =>
+ FastFuture.successful(None)
+ }
+
+ val recoverableOperationFuture = operationFuture.recover {
+ case e: Exception =>
+ // Log any errors.
+ logger.warn("Reading byte array from Redis failed - {}", e.getMessage)
+ None
+ }
+
+ recoverableOperationFuture
+ }
+
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
index f0a3471e9a..f3bf9caec7 100644
--- a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
+++ b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
@@ -25,6 +25,7 @@ import org.knora.webapi.core.LiveActorMaker
import org.knora.webapi.responders.MockableResponderManager
import org.knora.webapi.settings._
import org.knora.webapi.store.MockableStoreManager
+import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
import org.knora.webapi.store.iiif.MockSipiConnector
/**
@@ -38,8 +39,12 @@ trait ManagersWithMockedSipi extends Managers {
lazy val mockResponders: Map[String, ActorRef] = Map.empty[String, ActorRef]
lazy val storeManager: ActorRef = context.actorOf(
- Props(new MockableStoreManager(mockStoreConnectors = mockStoreConnectors, appActor = self) with LiveActorMaker),
- name = StoreManagerActorName)
+ Props(
+ new MockableStoreManager(mockStoreConnectors = mockStoreConnectors,
+ appActor = self,
+ cs = new CacheServiceRedisImpl(KnoraSettings(context.system))) with LiveActorMaker),
+ name = StoreManagerActorName
+ )
lazy val responderManager: ActorRef = context.actorOf(
Props(new MockableResponderManager(mockRespondersOrStoreConnectors = mockResponders, appActor = self)),
name = RESPONDER_MANAGER_ACTOR_NAME)
diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v1/ResourcesV1R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v1/ResourcesV1R2RSpec.scala
index 70a8156187..3fa6caf073 100644
--- a/webapi/src/test/scala/org/knora/webapi/e2e/v1/ResourcesV1R2RSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/e2e/v1/ResourcesV1R2RSpec.scala
@@ -1715,7 +1715,7 @@ class ResourcesV1R2RSpec extends R2RSpec {
"create 10,000 anything:Thing resources with random contents" in {
def maybeAppendValue(random: Random, xmlStringBuilder: StringBuilder, value: String): Unit = {
- if (random.nextBoolean) {
+ if (random.nextBoolean()) {
xmlStringBuilder.append(value)
}
}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/MockableStoreManager.scala b/webapi/src/test/scala/org/knora/webapi/store/MockableStoreManager.scala
index 3ce43e5440..7a64febed2 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/MockableStoreManager.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/MockableStoreManager.scala
@@ -22,10 +22,11 @@ package org.knora.webapi.store
import akka.actor.{ActorRef, Props}
import org.knora.webapi.core.LiveActorMaker
import org.knora.webapi.settings.{KnoraDispatchers, _}
+import org.knora.webapi.store.cacheservice.CacheService
import org.knora.webapi.store.iiif.MockableIIIFManager
-class MockableStoreManager(mockStoreConnectors: Map[String, ActorRef], appActor: ActorRef)
- extends StoreManager(appActor)
+class MockableStoreManager(mockStoreConnectors: Map[String, ActorRef], appActor: ActorRef, cs: CacheService)
+ extends StoreManager(appActor, cs)
with LiveActorMaker {
/**
From f71c936a7bf1858c0782effa37b2e545b32d4acb Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Sat, 5 Jun 2021 12:53:01 +0200
Subject: [PATCH 02/12] chore (build): cleanup
---
WORKSPACE | 2 --
.../org/knora/webapi/store/cacheservice/BUILD.bazel | 5 ++---
.../knora/webapi/store/cacheservice/redis/BUILD.bazel | 4 ++--
.../src/test/scala/org/knora/webapi/e2e/v1/BUILD.bazel | 10 ++++++++++
4 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/WORKSPACE b/WORKSPACE
index 2bc677cd9e..1982b02232 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -289,8 +289,6 @@ http_archive(
url = "https://github.com/bazelbuild/buildtools/archive/master.zip",
)
-
-
#####################################
# rules_pkg - basic packaging rules #
#####################################
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
index 959bf137c4..6eac37f04c 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
@@ -9,10 +9,9 @@ scala_library(
"CacheService.scala",
"CacheServiceExceptions.scala",
"CacheServiceManager.scala",
-
],
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/core",
@@ -51,4 +50,4 @@ scala_library(
"@maven//:org_slf4j_slf4j_api",
"@maven//:redis_clients_jedis",
],
-)
\ No newline at end of file
+)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index 0d790f740b..14deb898eb 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -7,8 +7,8 @@ scala_library(
srcs = [
"CacheServiceRedisImpl.scala",
],
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/core",
@@ -48,4 +48,4 @@ scala_library(
"@maven//:org_slf4j_slf4j_api",
"@maven//:redis_clients_jedis",
],
-)
\ No newline at end of file
+)
diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v1/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/e2e/v1/BUILD.bazel
index 8d5285d056..20b4bbf883 100644
--- a/webapi/src/test/scala/org/knora/webapi/e2e/v1/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/e2e/v1/BUILD.bazel
@@ -16,6 +16,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -34,6 +35,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -53,6 +55,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -71,6 +74,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -90,6 +94,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -129,6 +134,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -147,6 +153,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -165,6 +172,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -185,6 +193,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
@@ -203,6 +212,7 @@ scala_test(
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
# unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
"//webapi:main_library",
"//webapi:test_library",
From a90d0b4e2c3e24593f5f6e700396909ae04c623b Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Sat, 5 Jun 2021 19:17:46 +0200
Subject: [PATCH 03/12] chore (build): cleanup
---
webapi/BUILD.bazel | 1 +
.../store/cacheservice/redis/BUILD.bazel | 25 -------------------
2 files changed, 1 insertion(+), 25 deletions(-)
diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel
index b5e137ba75..5887db4c14 100644
--- a/webapi/BUILD.bazel
+++ b/webapi/BUILD.bazel
@@ -37,6 +37,7 @@ scala_library(
"@maven//:com_typesafe_akka_akka_slf4j_2_13",
"@maven//:org_slf4j_log4j_over_slf4j",
],
+ scalacopts=["-deprecation"],
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/core",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index 14deb898eb..f697452deb 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -11,40 +11,15 @@ scala_library(
unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi",
- "//webapi/src/main/scala/org/knora/webapi/core",
"//webapi/src/main/scala/org/knora/webapi/exceptions",
- "//webapi/src/main/scala/org/knora/webapi/feature",
"//webapi/src/main/scala/org/knora/webapi/instrumentation",
"//webapi/src/main/scala/org/knora/webapi/messages",
- "//webapi/src/main/scala/org/knora/webapi/routing",
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
- "//webapi/src/main/scala/org/knora/webapi/util",
- "@maven//:com_twitter_chill_2_13",
"@maven//:com_typesafe_akka_akka_actor_2_13",
- "@maven//:com_typesafe_akka_akka_http_2_13",
"@maven//:com_typesafe_akka_akka_http_core_2_13",
- "@maven//:com_typesafe_akka_akka_http_spray_json_2_13",
- "@maven//:com_typesafe_akka_akka_stream_2_13",
- "@maven//:com_typesafe_config",
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
- "@maven//:commons_cli_commons_cli",
- "@maven//:commons_codec_commons_codec",
- "@maven//:commons_io_commons_io",
- "@maven//:io_spray_spray_json_2_13",
- "@maven//:org_apache_commons_commons_csv",
- "@maven//:org_apache_commons_commons_lang3",
"@maven//:org_apache_commons_commons_pool2",
- "@maven//:org_apache_httpcomponents_httpclient",
- "@maven//:org_apache_httpcomponents_httpclient_cache",
- "@maven//:org_apache_httpcomponents_httpcore",
- "@maven//:org_apache_jena_apache_jena_libs",
- "@maven//:org_apache_jena_jena_arq",
- "@maven//:org_apache_jena_jena_base",
- "@maven//:org_apache_jena_jena_core",
- "@maven//:org_apache_jena_jena_tdb",
- "@maven//:org_apache_jena_jena_text",
- "@maven//:org_apache_lucene_lucene_core",
"@maven//:org_slf4j_slf4j_api",
"@maven//:redis_clients_jedis",
],
From 9a24a0d3e20b53688f2de5de2563ebd3cf289b84 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Mon, 7 Jun 2021 07:57:17 +0200
Subject: [PATCH 04/12] feature(cache-service): add in-memory implementation
---
README.md | 3 +-
.../store/cacheservice/inmem/BUILD.bazel | 24 +++
.../inmem/CacheServiceInMemImpl.scala | 192 ++++++++++++++++++
.../store/cacheservice/inmem/BUILD.bazel | 0
.../store/cacheservice/redis/BUILD.bazel | 0
5 files changed, 218 insertions(+), 1 deletion(-)
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
create mode 100644 webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
create mode 100644 webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
diff --git a/README.md b/README.md
index d772c7bb6f..0a13a1e534 100644
--- a/README.md
+++ b/README.md
@@ -188,7 +188,8 @@ Lukas Rosenthaler ``
## Commit Message Schema
-When writing commit messages, we follow the [Conventional Commit messages](https://www.conventionalcommits.org/) rules. Get more information in our official [DSP Contribution Documentation](https://docs.dasch.swiss/developers/dsp/contribution/#git-commit-guidelines)
+When writing commit messages, we follow the [Conventional Commit messages](https://www.conventionalcommits.org/) rules.
+Get more information in our official [DSP Contribution Documentation](https://docs.dasch.swiss/developers/dsp/contribution/#git-commit-guidelines)
## Release Versioning Convention
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
new file mode 100644
index 0000000000..f0ebb19931
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
@@ -0,0 +1,24 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
+
+scala_library(
+ name = "inmem",
+ srcs = [
+ "CacheServiceInMemImpl.scala",
+ ],
+ scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/exceptions",
+ "//webapi/src/main/scala/org/knora/webapi/instrumentation",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_http_core_2_13",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_slf4j_slf4j_api",
+ ],
+)
\ No newline at end of file
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
new file mode 100644
index 0000000000..03fdbc347e
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi.store.cacheservice.inmem
+
+import akka.http.scaladsl.util.FastFuture
+import com.typesafe.scalalogging.LazyLogging
+import org.knora.webapi.messages.admin.responder.projectsmessages.{
+ ProjectADM,
+ ProjectIdentifierADM,
+ ProjectIdentifierType
+}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM, UserIdentifierType}
+import org.knora.webapi.messages.store.cacheservicemessages.{
+ CacheServiceFlushDBACK,
+ CacheServiceStatusOK,
+ CacheServiceStatusResponse
+}
+import org.knora.webapi.store.cacheservice.{CacheService, EmptyKey, EmptyValue}
+
+import scala.concurrent.{ExecutionContext, Future}
+
+object CacheServiceInMemImpl extends CacheService with LazyLogging {
+
+ private var cache: scala.collection.mutable.Map[Any, Any] =
+ scala.collection.mutable.Map[Any, Any]()
+
+ /**
+ * Stores the user under the IRI and additionally the IRI under the keys of
+ * USERNAME and EMAIL:
+ *
+ * IRI -> byte array
+ * username -> IRI
+ * email -> IRI
+ *
+ * @param value the stored value
+ */
+ def putUserADM(value: UserADM)(implicit ec: ExecutionContext): Future[Boolean] = {
+ cache(value.id) = value
+ cache(value.username) = value.id
+ cache(value.email) = value.id
+ FastFuture.successful(true)
+ }
+
+ /**
+ * Retrieves the user stored under the identifier (either iri, username,
+ * or email).
+ *
+ * @param identifier the project identifier.
+ */
+ def getUserADM(identifier: UserIdentifierADM)(implicit ec: ExecutionContext): Future[Option[UserADM]] = {
+ // The data is stored under the IRI key.
+ // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ val resultFuture: Future[Option[UserADM]] = identifier.hasType match {
+ case UserIdentifierType.IRI => FastFuture.successful(cache.get(identifier.toIri).map(_.asInstanceOf[UserADM]))
+ case UserIdentifierType.USERNAME => {
+ cache.get(identifier.toUsername) match {
+ case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[UserADM]))
+ case None => FastFuture.successful(None)
+ }
+ }
+ case UserIdentifierType.EMAIL =>
+ cache.get(identifier.toEmail) match {
+ case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[UserADM]))
+ case None => FastFuture.successful(None)
+ }
+ }
+ resultFuture
+ }
+
+ /**
+ * Stores the project under the IRI and additionally the IRI under the keys
+ * of SHORTCODE and SHORTNAME:
+ *
+ * IRI -> byte array
+ * shortname -> IRI
+ * shortcode -> IRI
+ *
+ * @param value the stored value
+ */
+ def putProjectADM(value: ProjectADM)(implicit ec: ExecutionContext): Future[Boolean] = {
+ cache(value.id) = value
+ cache(value.shortcode) = value.id
+ cache(value.shortname) = value.id
+ FastFuture.successful(true)
+ }
+
+ /**
+ * Retrieves the project stored under the identifier (either iri, shortname, or shortcode).
+ *
+ * @param identifier the project identifier.
+ */
+ def getProjectADM(identifier: ProjectIdentifierADM)(implicit ec: ExecutionContext): Future[Option[ProjectADM]] = {
+ // The data is stored under the IRI key.
+ // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ val resultFuture: Future[Option[ProjectADM]] = identifier.hasType match {
+ case ProjectIdentifierType.IRI =>
+ FastFuture.successful(cache.get(identifier.toIri).map(_.asInstanceOf[ProjectADM]))
+ case ProjectIdentifierType.SHORTCODE =>
+ cache.get(identifier.toShortcode) match {
+ case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[ProjectADM]))
+ case None => FastFuture.successful(None)
+ }
+ case ProjectIdentifierType.SHORTNAME =>
+ cache.get(identifier.toShortname) match {
+ case Some(iriKey) => FastFuture.successful(cache.get(iriKey).map(_.asInstanceOf[ProjectADM]))
+ case None => FastFuture.successful(None)
+ }
+ }
+ resultFuture
+ }
+
+ /**
+ * Store string or byte array value under key.
+ *
+ * @param key the key.
+ * @param value the value.
+ */
+ def writeStringValue(key: String, value: String)(implicit ec: ExecutionContext): Future[Boolean] = {
+
+ if (key.isEmpty)
+ throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
+
+ if (value.isEmpty)
+ throw EmptyValue("The string value is empty. Aborting writing to redis.")
+
+ cache(key) = value
+ FastFuture.successful(true)
+ }
+
+ /**
+ * Get value stored under the key as a string.
+ *
+ * @param maybeKey the key.
+ */
+ def getStringValue(maybeKey: Option[String])(implicit ec: ExecutionContext): Future[Option[String]] = {
+ maybeKey match {
+ case Some(key) =>
+ FastFuture.successful(cache.get(key).map(_.asInstanceOf[String]))
+ case None =>
+ FastFuture.successful(None)
+ }
+ }
+
+ /**
+ * Removes values for the provided keys. Any invalid keys are ignored.
+ *
+ * @param keys the keys.
+ */
+ def removeValues(keys: Set[String])(implicit ec: ExecutionContext): Future[Boolean] = {
+
+ logger.debug("removeValues - {}", keys)
+ keys foreach { key =>
+ cache remove key
+ }
+
+ FastFuture.successful(true)
+ }
+
+ /**
+ * Flushes (removes) all stored content from the Redis store.
+ */
+ def flushDB(requestingUser: UserADM)(implicit ec: ExecutionContext): Future[CacheServiceFlushDBACK] = {
+ cache = scala.collection.mutable.Map[Any, Any]()
+ FastFuture.successful(CacheServiceFlushDBACK())
+ }
+
+ /**
+ * Pings the Redis store to see if it is available.
+ */
+ def ping()(implicit ec: ExecutionContext): Future[CacheServiceStatusResponse] = {
+ FastFuture.successful(CacheServiceStatusOK)
+ }
+
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
new file mode 100644
index 0000000000..e69de29bb2
From 1b81a35e7e11a68b1323d9748faea7cc05e8da3e Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Tue, 8 Jun 2021 13:55:22 +0200
Subject: [PATCH 05/12] refactor(cache-service): separate settings
---
webapi/BUILD.bazel | 1 +
.../knora/webapi/app/ApplicationActor.scala | 26 ++++--
.../scala/org/knora/webapi/app/BUILD.bazel | 1 +
.../org/knora/webapi/messages/BUILD.bazel | 2 +
...esponderUtil.scala => ResponderData.scala} | 7 +-
.../search/gravsearch/GravsearchParser.scala | 2 +-
.../org/knora/webapi/responders/BUILD.bazel | 2 +
.../knora/webapi/responders/Responder.scala | 8 +-
.../webapi/responders/ResponderManager.scala | 10 +--
.../admin/ProjectsResponderADM.scala | 4 +-
.../responders/admin/UsersResponderADM.scala | 4 +-
.../org/knora/webapi/settings/BUILD.bazel | 1 +
.../knora/webapi/settings/KnoraSettings.scala | 8 +-
.../store/cacheservice/redis/BUILD.bazel | 2 +-
.../redis/CacheServiceRedisImpl.scala | 4 +-
.../store/cacheservice/settings/BUILD.bazel | 15 ++++
.../settings/CacheServiceSettings.scala | 33 +++++++
.../test/scala/org/knora/webapi/BUILD.bazel | 2 +
.../scala/org/knora/webapi/CoreSpec.scala | 5 +-
.../knora/webapi/ManagersWithMockedSipi.scala | 34 ++++---
.../org/knora/webapi/RedisTestContainer.scala | 45 ++++++++++
.../scala/org/knora/webapi/UnitSpec.scala | 57 ++++++++++++
.../responders/MockableResponderManager.scala | 7 +-
.../cacheservice/CacheSerializationSpec.scala | 19 ++--
.../CacheServiceManagerSpec.scala | 19 ++--
.../store/cacheservice/inmem/BUILD.bazel | 41 +++++++++
.../inmem/CacheServiceInMemImplSpec.scala | 83 +++++++++++++++++
.../store/cacheservice/redis/BUILD.bazel | 42 +++++++++
.../redis/CacheServiceRedisImplSpec.scala | 90 +++++++++++++++++++
29 files changed, 514 insertions(+), 60 deletions(-)
rename webapi/src/main/scala/org/knora/webapi/messages/util/{ResponderUtil.scala => ResponderData.scala} (74%)
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/BUILD.bazel
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
create mode 100644 webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
create mode 100644 webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
create mode 100644 webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
create mode 100644 webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel
index 5887db4c14..7f0155fcd6 100644
--- a/webapi/BUILD.bazel
+++ b/webapi/BUILD.bazel
@@ -164,6 +164,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/store",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
# Logging
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
index 5e38789a2b..855888114f 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
@@ -30,7 +30,7 @@ import ch.megard.akka.http.cors.scaladsl.CorsDirectives
import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings
import com.typesafe.scalalogging.LazyLogging
import kamon.Kamon
-import org.knora.webapi.core.LiveActorMaker
+import org.knora.webapi.core.{Core, LiveActorMaker}
import org.knora.webapi.exceptions.{
InconsistentRepositoryDataException,
SipiException,
@@ -50,7 +50,7 @@ import org.knora.webapi.messages.store.cacheservicemessages.{
}
import org.knora.webapi.messages.store.sipimessages.{IIIFServiceGetStatus, IIIFServiceStatusNOK, IIIFServiceStatusOK}
import org.knora.webapi.messages.store.triplestoremessages._
-import org.knora.webapi.messages.util.KnoraSystemInstances
+import org.knora.webapi.messages.util.{KnoraSystemInstances, ResponderData}
import org.knora.webapi.messages.v1.responder.KnoraRequestV1
import org.knora.webapi.messages.v2.responder.ontologymessages.LoadOntologiesRequestV2
import org.knora.webapi.messages.v2.responder.{KnoraRequestV2, SuccessResponseV2}
@@ -62,6 +62,7 @@ import org.knora.webapi.routing.v2._
import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
import org.knora.webapi.store.StoreManager
import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
import org.knora.webapi.util.cache.CacheUtil
import redis.clients.jedis.exceptions.JedisConnectionException
@@ -82,7 +83,10 @@ trait LiveManagers extends Managers {
* The actor that forwards messages to actors that deal with persistent storage.
*/
lazy val storeManager: ActorRef = context.actorOf(
- Props(new StoreManager(appActor = self, cs = new CacheServiceRedisImpl(KnoraSettings(system))) with LiveActorMaker)
+ Props(
+ new StoreManager(appActor = self,
+ cs = new CacheServiceRedisImpl(new CacheServiceSettings(system.settings.config)))
+ with LiveActorMaker)
.withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
name = StoreManagerActorName
)
@@ -91,7 +95,14 @@ trait LiveManagers extends Managers {
* The actor that forwards messages to responder actors to handle API requests.
*/
lazy val responderManager: ActorRef = context.actorOf(
- Props(new ResponderManager(self) with LiveActorMaker)
+ Props(
+ new ResponderManager(
+ appActor = self,
+ responderData = ResponderData(system = context.system,
+ appActor = self,
+ knoraSettings = KnoraSettings(system),
+ cacheServiceSettings = new CacheServiceSettings(system.settings.config))
+ ) with LiveActorMaker)
.withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
name = RESPONDER_MANAGER_ACTOR_NAME
)
@@ -117,6 +128,11 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
*/
implicit val knoraSettings: KnoraSettingsImpl = KnoraSettings(system)
+ /**
+ * The Cache Service's configuration.
+ */
+ implicit val cacheServiceSettings: CacheServiceSettings = new CacheServiceSettings(system.settings.config)
+
/**
* The default feature factory configuration, which is used during startup.
*/
@@ -171,7 +187,7 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
private var printConfigState = false
private var ignoreRepository = true
private var withIIIFService = true
- private val withCacheService = knoraSettings.cacheServiceEnabled
+ private val withCacheService = cacheServiceSettings.cacheServiceEnabled
/**
* Startup of the ApplicationActor is a two step process:
diff --git a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
index d73e104207..4de5fcbf88 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
@@ -21,6 +21,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/store",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
"@maven//:ch_megard_akka_http_cors_2_13",
"@maven//:com_github_swagger_akka_http_swagger_akka_http_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
index d12410c2fc..5ab1063965 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
@@ -6,6 +6,7 @@ scala_library(
name = "messages",
srcs = glob(["**/*.scala"]) + ["//webapi/src/main/twirl:twirl_sources"],
unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/annotation",
@@ -14,6 +15,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_apicatalog_titanium_json_ld",
"@maven//:com_google_gwt_gwt_servlet",
"@maven//:com_ibm_icu_icu4j",
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/ResponderUtil.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/ResponderData.scala
similarity index 74%
rename from webapi/src/main/scala/org/knora/webapi/messages/util/ResponderUtil.scala
rename to webapi/src/main/scala/org/knora/webapi/messages/util/ResponderData.scala
index 15df597589..3ed7b16d45 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/util/ResponderUtil.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/util/ResponderData.scala
@@ -20,6 +20,8 @@
package org.knora.webapi.messages.util
import akka.actor.{ActorRef, ActorSystem}
+import org.knora.webapi.settings.KnoraSettingsImpl
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
/**
* Data needed to be passed to each responder.
@@ -27,4 +29,7 @@ import akka.actor.{ActorRef, ActorSystem}
* @param system the actor system.
* @param appActor the main application actor.
*/
-case class ResponderData(system: ActorSystem, appActor: ActorRef)
+case class ResponderData(system: ActorSystem,
+ appActor: ActorRef,
+ knoraSettings: KnoraSettingsImpl,
+ cacheServiceSettings: CacheServiceSettings)
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/GravsearchParser.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/GravsearchParser.scala
index 7212d656b9..2bf9115a2b 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/GravsearchParser.scala
+++ b/webapi/src/main/scala/org/knora/webapi/messages/util/search/gravsearch/GravsearchParser.scala
@@ -172,7 +172,7 @@ object GravsearchParser {
wherePatterns.toSeq
}
- private def unsupported(node: algebra.QueryModelNode) {
+ private def unsupported(node: algebra.QueryModelNode): Unit = {
throw GravsearchException(s"SPARQL feature not supported in Gravsearch query: $node")
}
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
index c8027d1a2c..53108e1fbb 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
@@ -6,6 +6,7 @@ scala_library(
name = "responders",
srcs = glob(["**/*.scala"]),
unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/annotation",
@@ -17,6 +18,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_typesafe_akka_akka_actor_2_13",
"@maven//:com_typesafe_akka_akka_http_2_13",
"@maven//:com_typesafe_akka_akka_http_core_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/Responder.scala b/webapi/src/main/scala/org/knora/webapi/responders/Responder.scala
index 4bde0a8767..b993a235c9 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/Responder.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/Responder.scala
@@ -33,6 +33,7 @@ import akka.http.scaladsl.util.FastFuture
import akka.pattern._
import akka.util.Timeout
import com.typesafe.scalalogging.{LazyLogging, Logger}
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
import scala.concurrent.{ExecutionContext, Future}
import scala.language.postfixOps
@@ -75,7 +76,12 @@ abstract class Responder(responderData: ResponderData) extends LazyLogging {
/**
* The application settings.
*/
- protected val settings: KnoraSettingsImpl = KnoraSettings(system)
+ protected val settings: KnoraSettingsImpl = responderData.knoraSettings
+
+ /**
+ * The Cache Service settings.
+ */
+ protected val cacheServiceSettings: CacheServiceSettings = responderData.cacheServiceSettings
/**
* The main application actor.
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/ResponderManager.scala b/webapi/src/main/scala/org/knora/webapi/responders/ResponderManager.scala
index cfb920da4e..25657af132 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/ResponderManager.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/ResponderManager.scala
@@ -60,7 +60,7 @@ import scala.concurrent.ExecutionContext
*
* @param appActor the main application actor.
*/
-class ResponderManager(appActor: ActorRef) extends Actor with ActorLogging {
+class ResponderManager(appActor: ActorRef, responderData: ResponderData) extends Actor with ActorLogging {
this: ActorMaker =>
/**
@@ -74,14 +74,6 @@ class ResponderManager(appActor: ActorRef) extends Actor with ActorLogging {
protected implicit val executionContext: ExecutionContext =
system.dispatchers.lookup(KnoraDispatchers.KnoraActorDispatcher)
- /**
- * The responder data.
- */
- private val responderData = ResponderData(
- system = system,
- appActor = appActor
- )
-
// A subclass can replace the standard responders with custom responders, e.g. for testing. To do this, it must
// override one or more of the protected val members below representing responder classes. To construct a default
// responder, a subclass can call one of the protected methods below.
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala
index 29d744c599..6817c509b4 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala
@@ -1153,7 +1153,7 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo
private def getProjectFromCacheOrTriplestore(
identifier: ProjectIdentifierADM,
featureFactoryConfig: FeatureFactoryConfig): Future[Option[ProjectADM]] = {
- if (settings.cacheServiceEnabled) {
+ if (cacheServiceSettings.cacheServiceEnabled) {
// caching enabled
getProjectFromCache(identifier)
.flatMap {
@@ -1405,7 +1405,7 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo
* Removes the project from cache.
*/
private def invalidateCachedProjectADM(maybeProject: Option[ProjectADM]): Future[Boolean] = {
- if (settings.cacheServiceEnabled) {
+ if (cacheServiceSettings.cacheServiceEnabled) {
val keys: Set[String] =
Seq(maybeProject.map(_.id), maybeProject.map(_.shortname), maybeProject.map(_.shortcode)).flatten.toSet
// only send to Redis if keys are not empty
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala
index 0ad6432b50..00c1dafd67 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala
+++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/UsersResponderADM.scala
@@ -1626,7 +1626,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde
*/
private def getUserFromCacheOrTriplestore(identifier: UserIdentifierADM,
featureFactoryConfig: FeatureFactoryConfig): Future[Option[UserADM]] = {
- if (settings.cacheServiceEnabled) {
+ if (cacheServiceSettings.cacheServiceEnabled) {
// caching enabled
getUserFromCache(identifier)
.flatMap {
@@ -1981,7 +1981,7 @@ class UsersResponderADM(responderData: ResponderData) extends Responder(responde
* Removes the user from cache.
*/
private def invalidateCachedUserADM(maybeUser: Option[UserADM]): Future[Boolean] = {
- if (settings.cacheServiceEnabled) {
+ if (cacheServiceSettings.cacheServiceEnabled) {
val keys: Set[String] = Seq(maybeUser.map(_.id), maybeUser.map(_.email), maybeUser.map(_.username)).flatten.toSet
// only send to Redis if keys are not empty
if (keys.nonEmpty) {
diff --git a/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
index b70cdcc03f..a8530bc445 100644
--- a/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
@@ -6,6 +6,7 @@ scala_library(
name = "settings",
srcs = glob(["*.scala"]),
unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
deps = [
"//webapi/src/main/scala/org/knora/webapi/exceptions",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
diff --git a/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala b/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
index 6659b1cf81..7166ed4525 100644
--- a/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
+++ b/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
@@ -271,9 +271,7 @@ class KnoraSettingsImpl(config: Config, log: LoggingAdapter) extends Extension {
val bcryptPasswordStrength: Int = config.getInt("app.bcrypt-password-strength")
// Cache Service
- val cacheServiceEnabled: Boolean = config.getBoolean("app.cache-service.enabled")
- val cacheServiceRedisHost: String = config.getString("app.cache-service.redis.host")
- val cacheServiceRedisPort: Int = config.getInt("app.cache-service.redis.port")
+ // moved, see org.knora.webapi.store.cacheservice.settings
// Client test data service
@@ -297,8 +295,8 @@ class KnoraSettingsImpl(config: Config, log: LoggingAdapter) extends Extension {
private def getFiniteDuration(path: String, underlying: Config): FiniteDuration =
Duration(underlying.getString(path)) match {
- case x: FiniteDuration ⇒ x
- case _ ⇒ throw new ConfigurationException(s"Config setting '$path' must be a finite duration")
+ case x: FiniteDuration => x
+ case _ => throw new ConfigurationException(s"Config setting '$path' must be a finite duration")
}
val prometheusEndpoint: Boolean = config.getBoolean("app.monitoring.prometheus-endpoint")
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index f697452deb..c4192bca53 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -14,8 +14,8 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/exceptions",
"//webapi/src/main/scala/org/knora/webapi/instrumentation",
"//webapi/src/main/scala/org/knora/webapi/messages",
- "//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_typesafe_akka_akka_actor_2_13",
"@maven//:com_typesafe_akka_akka_http_core_2_13",
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
index 8bb4860127..233569f294 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
@@ -35,13 +35,13 @@ import org.knora.webapi.messages.store.cacheservicemessages.{
CacheServiceStatusOK,
CacheServiceStatusResponse
}
-import org.knora.webapi.settings.KnoraSettingsImpl
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
import org.knora.webapi.store.cacheservice.{CacheSerialization, CacheService, EmptyKey, EmptyValue}
import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}
import scala.concurrent.{ExecutionContext, Future}
-class CacheServiceRedisImpl(s: KnoraSettingsImpl) extends CacheService with LazyLogging {
+class CacheServiceRedisImpl(s: CacheServiceSettings) extends CacheService with LazyLogging {
/**
* The Redis Client Pool
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/BUILD.bazel
new file mode 100644
index 0000000000..23044ebd20
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/BUILD.bazel
@@ -0,0 +1,15 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
+
+scala_library(
+ name = "settings",
+ srcs = [
+ "CacheServiceSettings.scala",
+ ],
+ scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
+ deps = [
+ "@maven//:com_typesafe_config",
+ ],
+)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
new file mode 100644
index 0000000000..c836128b38
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi
+package store.cacheservice.settings
+
+import com.typesafe.config.Config
+
+/**
+ * Holds the Cache Service specific settings.
+ */
+class CacheServiceSettings(config: Config) {
+ val cacheServiceEnabled: Boolean = config.getBoolean("app.cache-service.enabled")
+ val cacheServiceRedisHost: String = config.getString("app.cache-service.redis.host")
+ val cacheServiceRedisPort: Int = config.getInt("app.cache-service.redis.port")
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/BUILD.bazel
index 70144af980..ab9bc242d7 100644
--- a/webapi/src/test/scala/org/knora/webapi/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/BUILD.bazel
@@ -13,8 +13,10 @@ filegroup(
"KnoraFakeCore.scala",
"ManagersWithMockedSipi.scala",
"R2RSpec.scala",
+ "RedisTestContainer.scala",
"TestContainers.scala",
"TestProbeMaker.scala",
+ "UnitSpec.scala",
"//webapi/src/test/scala/org/knora/webapi/e2e:srcs",
"//webapi/src/test/scala/org/knora/webapi/responders:srcs",
"//webapi/src/test/scala/org/knora/webapi/sharedtestdata:srcs",
diff --git a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
index 5d6a60bba0..016662bea3 100644
--- a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
@@ -30,6 +30,7 @@ import messages.util.rdf.RdfFeatureFactory
import messages.util.{KnoraSystemInstances, ResponderData}
import messages.v2.responder.ontologymessages.LoadOntologiesRequestV2
import settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
+import store.cacheservice.settings.CacheServiceSettings
import util.StartupUtils
import akka.actor.{ActorRef, ActorSystem, Props}
@@ -122,7 +123,9 @@ abstract class CoreSpec(_system: ActorSystem)
val responderData: ResponderData = ResponderData(
system = system,
- appActor = appActor
+ appActor = appActor,
+ knoraSettings = settings,
+ cacheServiceSettings = new CacheServiceSettings(system.settings.config)
)
protected val defaultFeatureFactoryConfig: FeatureFactoryConfig = new TestFeatureFactoryConfig(
diff --git a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
index f3bf9caec7..2b192b1ba0 100644
--- a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
+++ b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
@@ -19,14 +19,17 @@
package org.knora.webapi
+import app.Managers
+import core.LiveActorMaker
+import messages.util.ResponderData
+import responders.MockableResponderManager
+import settings._
+import store.MockableStoreManager
+import store.cacheservice.redis.CacheServiceRedisImpl
+import store.cacheservice.settings.CacheServiceSettings
+import store.iiif.MockSipiConnector
+
import akka.actor.{Actor, ActorRef, Props}
-import org.knora.webapi.app.Managers
-import org.knora.webapi.core.LiveActorMaker
-import org.knora.webapi.responders.MockableResponderManager
-import org.knora.webapi.settings._
-import org.knora.webapi.store.MockableStoreManager
-import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
-import org.knora.webapi.store.iiif.MockSipiConnector
/**
* Mixin trait for running the application with mocked Sipi
@@ -42,10 +45,21 @@ trait ManagersWithMockedSipi extends Managers {
Props(
new MockableStoreManager(mockStoreConnectors = mockStoreConnectors,
appActor = self,
- cs = new CacheServiceRedisImpl(KnoraSettings(context.system))) with LiveActorMaker),
+ cs = new CacheServiceRedisImpl(new CacheServiceSettings(context.system.settings.config)))
+ with LiveActorMaker),
name = StoreManagerActorName
)
+
lazy val responderManager: ActorRef = context.actorOf(
- Props(new MockableResponderManager(mockRespondersOrStoreConnectors = mockResponders, appActor = self)),
- name = RESPONDER_MANAGER_ACTOR_NAME)
+ Props(
+ new MockableResponderManager(
+ mockRespondersOrStoreConnectors = mockResponders,
+ appActor = self,
+ responderData = ResponderData(system,
+ self,
+ knoraSettings = KnoraSettings(system),
+ cacheServiceSettings = new CacheServiceSettings(system.settings.config))
+ )),
+ name = RESPONDER_MANAGER_ACTOR_NAME
+ )
}
diff --git a/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala b/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
new file mode 100644
index 0000000000..a682ba26a3
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of Knora.
+ *
+ * Knora is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Knora is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with Knora. If not, see .
+ */
+
+package org.knora.webapi
+
+import com.typesafe.config.{Config, ConfigFactory}
+import org.testcontainers.containers.GenericContainer
+import org.testcontainers.utility.DockerImageName
+
+import scala.jdk.CollectionConverters._
+
+/**
+ * Provides all containers necessary for running tests.
+ */
+object RedisTestContainer {
+
+ val RedisImageName: DockerImageName = DockerImageName.parse("redis:5")
+ val RedisContainer = new GenericContainer(RedisImageName)
+ RedisContainer.withExposedPorts(6379)
+ RedisContainer.start()
+
+ private val portMap = Map(
+ "app.cache-service.redis.port" -> RedisContainer.getFirstMappedPort
+ ).asJava
+
+ // all tests need to be configured with these ports.
+ val PortConfig: Config =
+ ConfigFactory.parseMap(portMap, "Ports from ContainerizedSpec").withFallback(ConfigFactory.load())
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
new file mode 100644
index 0000000000..498b4a6a3b
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of Knora.
+ *
+ * Knora is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Knora is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with Knora. If not, see .
+ */
+
+package org.knora.webapi
+
+import com.typesafe.config.{Config, ConfigFactory}
+import com.typesafe.scalalogging.LazyLogging
+import org.knora.webapi.settings.{KnoraSettings, KnoraSettingsImpl}
+import org.scalatest.BeforeAndAfterAll
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.wordspec.AnyWordSpecLike
+
+import scala.language.postfixOps
+
+object UnitSpec {
+
+ /*
+ Loads the following (first-listed are higher priority):
+ - system properties (e.g., -Dconfig.resource=fuseki.conf)
+ - test/resources/application.conf
+ - main/resources/application.conf
+ */
+ val defaultConfig: Config = ConfigFactory.load()
+
+ /* Copied from: akka/akka-testkit/src/test/scala/akka/testkit/AkkaSpec.scala */
+ def getCallerName(clazz: Class[_]): String = {
+ val s = (Thread.currentThread.getStackTrace map (_.getClassName) drop 1)
+ .dropWhile(_ matches "(java.lang.Thread|.*UnitSpec.?$)")
+ val reduced = s.lastIndexWhere(_ == clazz.getName) match {
+ case -1 ⇒ s
+ case z ⇒ s drop (z + 1)
+ }
+ reduced.head.replaceFirst(""".*\.""", "").replaceAll("[^a-zA-Z_0-9]", "_")
+ }
+}
+
+abstract class UnitSpec(_config: Config) extends AnyWordSpecLike with Matchers with BeforeAndAfterAll with LazyLogging {
+
+ def this() =
+ this(UnitSpec.defaultConfig)
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/responders/MockableResponderManager.scala b/webapi/src/test/scala/org/knora/webapi/responders/MockableResponderManager.scala
index 5f5c51f2ce..1e11a86bf0 100644
--- a/webapi/src/test/scala/org/knora/webapi/responders/MockableResponderManager.scala
+++ b/webapi/src/test/scala/org/knora/webapi/responders/MockableResponderManager.scala
@@ -21,6 +21,7 @@ package org.knora.webapi.responders
import akka.actor._
import org.knora.webapi.core.{ActorMaker, LiveActorMaker}
+import org.knora.webapi.messages.util.ResponderData
/**
* A subclass of [[ResponderManager]] that allows tests to substitute custom responders for the standard ones.
@@ -30,8 +31,10 @@ import org.knora.webapi.core.{ActorMaker, LiveActorMaker}
* used as the key in the map.
* @param appActor the main application actor.
*/
-class MockableResponderManager(mockRespondersOrStoreConnectors: Map[String, ActorRef], appActor: ActorRef)
- extends ResponderManager(appActor)
+class MockableResponderManager(mockRespondersOrStoreConnectors: Map[String, ActorRef],
+ appActor: ActorRef,
+ responderData: ResponderData)
+ extends ResponderManager(appActor, responderData)
with LiveActorMaker {
this: ActorMaker =>
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala
index f83086aac5..f9baad5d12 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala
@@ -1,20 +1,21 @@
/*
* Copyright © 2015-2021 the contributors (see Contributors.md).
*
- * This file is part of Knora.
+ * This file is part of the DaSCH Service Platform.
*
- * Knora is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
*
- * Knora is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
- * License along with Knora. If not, see .
+ * License along with the DaSCH Service Platform. If not, see
+ * .
*/
package org.knora.webapi.store.cacheservice
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
index 57108883e4..7325c6a059 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
@@ -1,20 +1,21 @@
/*
* Copyright © 2015-2021 the contributors (see Contributors.md).
*
- * This file is part of Knora.
+ * This file is part of the DaSCH Service Platform.
*
- * Knora is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
*
- * Knora is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
- * License along with Knora. If not, see .
+ * License along with the DaSCH Service Platform. If not, see
+ * .
*/
package org.knora.webapi.store.cacheservice
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
index e69de29bb2..a428c4a98a 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
@@ -0,0 +1,41 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test")
+load("//third_party:dependencies.bzl", "ALL_WEBAPI_MAIN_DEPENDENCIES", "BASE_TEST_DEPENDENCIES", "BASE_TEST_DEPENDENCIES_WITH_JSON", "BASE_TEST_DEPENDENCIES_WITH_JSON_LD")
+
+scala_test(
+ name = "CacheServiceInMemImplSpec",
+ size = "small", # 60s
+ srcs = [
+ "CacheServiceInMemImplSpec.scala",
+ ],
+ data = [
+ "//knora-ontologies",
+ "//test_data",
+ ],
+ jvm_flags = ["-Dconfig.resource=fuseki.conf"],
+ unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem",
+ "//webapi:test_library",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_slf4j_slf4j_api",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_akka_akka_testkit_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:org_scalatest_scalatest_2_13",
+ "@maven//:org_scalatest_scalatest_core_2_13",
+ "@maven//:org_scalatest_scalatest_wordspec_2_13",
+ "@maven//:org_scalatest_scalatest_matchers_core_2_13",
+ "@maven//:org_scalatest_scalatest_shouldmatchers_2_13",
+ "@maven//:org_scalatest_scalatest_compatible",
+ "@maven//:org_scalactic_scalactic_2_13",
+ ]
+)
\ No newline at end of file
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
new file mode 100644
index 0000000000..aa9c4ecc1b
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi
+package store.cacheservice.inmem
+
+import messages.StringFormatter
+import messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
+import messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
+import sharedtestdata.SharedTestDataADM
+
+/**
+ * This spec is used to test [[org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl]].
+ */
+class CacheServiceInMemImplSpec extends CoreSpec() {
+
+ implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
+
+ private val user: UserADM = SharedTestDataADM.imagesUser01
+ private val project: ProjectADM = SharedTestDataADM.imagesProject
+
+ private val inMemCache: CacheServiceInMemImpl.type = CacheServiceInMemImpl
+
+ "The CacheServiceInMemImpl" should {
+
+ "successfully store a user" in {
+ val res = inMemCache.putUserADM(user)
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by IRI" in {
+ val res = inMemCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by USERNAME" in {
+ val res = inMemCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by EMAIL" in {
+ val res = inMemCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
+ res should equal(true)
+ }
+
+ "successfully store a project" in {
+ val res = inMemCache.putProjectADM(project)
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by IRI" in {
+ val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by SHORTNAME" in {
+ val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by SHORTCODE" in {
+ val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
+ res should equal(true)
+ }
+ }
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index e69de29bb2..28fbc5e59a 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -0,0 +1,42 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test")
+load("//third_party:dependencies.bzl", "ALL_WEBAPI_MAIN_DEPENDENCIES", "BASE_TEST_DEPENDENCIES", "BASE_TEST_DEPENDENCIES_WITH_JSON", "BASE_TEST_DEPENDENCIES_WITH_JSON_LD")
+
+scala_test(
+ name = "CacheServiceRedisImplSpec",
+ size = "small", # 60s
+ srcs = [
+ "CacheServiceRedisImplSpec.scala",
+ ],
+ data = [
+ "//knora-ontologies",
+ "//test_data",
+ ],
+ jvm_flags = ["-Dconfig.resource=fuseki.conf"],
+ unused_dependency_checker_mode = "warn",
+ scalacopts = ["-deprecation"],
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
+ "//webapi:test_library",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_slf4j_slf4j_api",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_akka_akka_testkit_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:org_scalatest_scalatest_2_13",
+ "@maven//:org_scalatest_scalatest_core_2_13",
+ "@maven//:org_scalatest_scalatest_wordspec_2_13",
+ "@maven//:org_scalatest_scalatest_matchers_core_2_13",
+ "@maven//:org_scalatest_scalatest_shouldmatchers_2_13",
+ "@maven//:org_scalatest_scalatest_compatible",
+ "@maven//:org_scalactic_scalactic_2_13",
+ ],
+)
\ No newline at end of file
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
new file mode 100644
index 0000000000..d4bfd74dcb
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2015-2021 the contributors (see Contributors.md).
+ *
+ * This file is part of the DaSCH Service Platform.
+ *
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with the DaSCH Service Platform. If not, see
+ * .
+ */
+
+package org.knora.webapi.store.cacheservice.redis
+
+import org.knora.webapi.messages.StringFormatter
+import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
+import org.knora.webapi.sharedtestdata.SharedTestDataADM
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
+import org.knora.webapi.{RedisTestContainer, UnitSpec}
+
+import scala.concurrent.ExecutionContext
+
+/**
+ * This spec is used to test [[org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImplSpec]].
+ * Adding the [[RedisTestContainer.PortConfig]] config will start the Redis container and make it
+ * available to the test.
+ */
+class CacheServiceRedisImplSpec extends UnitSpec(RedisTestContainer.PortConfig) {
+
+ implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
+ implicit val ec: ExecutionContext = ExecutionContext.global
+
+ private val user: UserADM = SharedTestDataADM.imagesUser01
+ private val project: ProjectADM = SharedTestDataADM.imagesProject
+
+ private val redisCache: CacheServiceRedisImpl = new CacheServiceRedisImpl(
+ new CacheServiceSettings(RedisTestContainer.PortConfig))
+
+ "The CacheServiceRedisImpl" should {
+
+ "successfully store a user" in {
+ val res = redisCache.putUserADM(user)
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by IRI" in {
+ val res = redisCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by USERNAME" in {
+ val res = redisCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a user by EMAIL" in {
+ val res = redisCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
+ res should equal(true)
+ }
+
+ "successfully store a project" in {
+ val res = redisCache.putProjectADM(project)
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by IRI" in {
+ val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by SHORTNAME" in {
+ val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
+ res should equal(true)
+ }
+
+ "successfully retrieve a project by SHORTCODE" in {
+ val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
+ res should equal(true)
+ }
+ }
+}
From 1fe719d4d8bef12bab95fb914d4a9521da76ab58 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Thu, 10 Jun 2021 22:37:57 +0200
Subject: [PATCH 06/12] test(cache-service): add unit and integration tests
---
.../webapi/store/cacheservice/BUILD.bazel | 1 -
.../store/cacheservice/redis/BUILD.bazel | 1 +
.../redis/CacheServiceRedisImpl.scala | 3 +-
.../cacheservice/serialization/BUILD.bazel | 50 ++++++++++
.../CacheSerialization.scala | 28 +++---
.../org/knora/webapi/RedisTestContainer.scala | 2 +-
.../org/knora/webapi/TestContainers.scala | 2 +-
.../scala/org/knora/webapi/UnitSpec.scala | 6 +-
.../webapi/store/cacheservice/BUILD.bazel | 18 ----
.../CacheServiceManagerSpec.scala | 2 +-
.../store/cacheservice/inmem/BUILD.bazel | 23 ++---
.../inmem/CacheServiceInMemImplSpec.scala | 94 ++++++++++---------
.../store/cacheservice/redis/BUILD.bazel | 24 +++--
.../redis/CacheServiceRedisImplSpec.scala | 32 +++----
.../cacheservice/serialization/BUILD.bazel | 37 ++++++++
.../CacheSerializationSpec.scala | 6 +-
16 files changed, 199 insertions(+), 130 deletions(-)
create mode 100644 webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
rename webapi/src/main/scala/org/knora/webapi/store/cacheservice/{ => serialization}/CacheSerialization.scala (72%)
create mode 100644 webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
rename webapi/src/test/scala/org/knora/webapi/store/cacheservice/{ => serialization}/CacheSerializationSpec.scala (92%)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
index 6eac37f04c..607d0205ad 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
@@ -5,7 +5,6 @@ load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
scala_library(
name = "cacheservice",
srcs = [
- "CacheSerialization.scala",
"CacheService.scala",
"CacheServiceExceptions.scala",
"CacheServiceManager.scala",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index c4192bca53..db7e971ebb 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -15,6 +15,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/instrumentation",
"//webapi/src/main/scala/org/knora/webapi/messages",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_typesafe_akka_akka_actor_2_13",
"@maven//:com_typesafe_akka_akka_http_core_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
index 233569f294..e42f5c036b 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
@@ -35,8 +35,9 @@ import org.knora.webapi.messages.store.cacheservicemessages.{
CacheServiceStatusOK,
CacheServiceStatusResponse
}
+import org.knora.webapi.store.cacheservice.serialization.CacheSerialization
import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
-import org.knora.webapi.store.cacheservice.{CacheSerialization, CacheService, EmptyKey, EmptyValue}
+import org.knora.webapi.store.cacheservice.{CacheService, EmptyKey, EmptyValue}
import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}
import scala.concurrent.{ExecutionContext, Future}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
new file mode 100644
index 0000000000..8cef4a7af3
--- /dev/null
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
@@ -0,0 +1,50 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
+
+scala_library(
+ name = "serialization",
+ srcs = [
+ "CacheSerialization.scala",
+ ],
+ scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
+ deps = [
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/exceptions",
+ "//webapi/src/main/scala/org/knora/webapi/feature",
+ "//webapi/src/main/scala/org/knora/webapi/instrumentation",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/routing",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/util",
+ "@maven//:com_twitter_chill_2_13",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_http_2_13",
+ "@maven//:com_typesafe_akka_akka_http_core_2_13",
+ "@maven//:com_typesafe_akka_akka_http_spray_json_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:commons_cli_commons_cli",
+ "@maven//:commons_codec_commons_codec",
+ "@maven//:commons_io_commons_io",
+ "@maven//:io_spray_spray_json_2_13",
+ "@maven//:org_apache_commons_commons_csv",
+ "@maven//:org_apache_commons_commons_lang3",
+ "@maven//:org_apache_commons_commons_pool2",
+ "@maven//:org_apache_httpcomponents_httpclient",
+ "@maven//:org_apache_httpcomponents_httpclient_cache",
+ "@maven//:org_apache_httpcomponents_httpcore",
+ "@maven//:org_apache_jena_apache_jena_libs",
+ "@maven//:org_apache_jena_jena_arq",
+ "@maven//:org_apache_jena_jena_base",
+ "@maven//:org_apache_jena_jena_core",
+ "@maven//:org_apache_jena_jena_tdb",
+ "@maven//:org_apache_jena_jena_text",
+ "@maven//:org_apache_lucene_lucene_core",
+ "@maven//:org_slf4j_slf4j_api",
+ "@maven//:redis_clients_jedis",
+ ],
+)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
similarity index 72%
rename from webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala
rename to webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
index 1040f1af6d..ab0cc37f01 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/CacheSerialization.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
@@ -1,30 +1,32 @@
/*
* Copyright © 2015-2021 the contributors (see Contributors.md).
*
- * This file is part of Knora.
+ * This file is part of the DaSCH Service Platform.
*
- * Knora is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * The DaSCH Service Platform is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Affero General Public
+ * License as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
*
- * Knora is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * The DaSCH Service Platform is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
- * License along with Knora. If not, see .
+ * License along with the DaSCH Service Platform. If not, see
+ * .
*/
-package org.knora.webapi.store.cacheservice
+package org.knora.webapi
+package store.cacheservice.serialization
-import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream}
+import exceptions.CacheServiceException
+import instrumentation.InstrumentationSupport
import com.twitter.chill.MeatLocker
-import org.knora.webapi.exceptions.CacheServiceException
-import org.knora.webapi.instrumentation.InstrumentationSupport
+import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream}
import scala.concurrent.{ExecutionContext, Future}
case class EmptyByteArray(message: String) extends CacheServiceException(message)
diff --git a/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala b/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
index a682ba26a3..652203c7d7 100644
--- a/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
+++ b/webapi/src/test/scala/org/knora/webapi/RedisTestContainer.scala
@@ -41,5 +41,5 @@ object RedisTestContainer {
// all tests need to be configured with these ports.
val PortConfig: Config =
- ConfigFactory.parseMap(portMap, "Ports from ContainerizedSpec").withFallback(ConfigFactory.load())
+ ConfigFactory.parseMap(portMap, "Ports from RedisTestContainer").withFallback(ConfigFactory.load())
}
diff --git a/webapi/src/test/scala/org/knora/webapi/TestContainers.scala b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
index f42fa41e83..5f6fa430bd 100644
--- a/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
+++ b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
@@ -77,5 +77,5 @@ object TestContainers {
).asJava
// all tests need to be configured with these ports.
- val PortConfig: Config = ConfigFactory.parseMap(portMap, "Ports from ContainerizedSpec")
+ val PortConfig: Config = ConfigFactory.parseMap(portMap, "Ports from TestContainers")
}
diff --git a/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
index 498b4a6a3b..a67271e5cb 100644
--- a/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
@@ -19,9 +19,10 @@
package org.knora.webapi
+import messages.StringFormatter
+
import com.typesafe.config.{Config, ConfigFactory}
import com.typesafe.scalalogging.LazyLogging
-import org.knora.webapi.settings.{KnoraSettings, KnoraSettingsImpl}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
@@ -54,4 +55,7 @@ abstract class UnitSpec(_config: Config) extends AnyWordSpecLike with Matchers w
def this() =
this(UnitSpec.defaultConfig)
+
+ // needs to be initialized early on
+ StringFormatter.initForTest()
}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
index ff0d569489..edcb77f463 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/BUILD.bazel
@@ -3,24 +3,6 @@ package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test")
load("//third_party:dependencies.bzl", "ALL_WEBAPI_MAIN_DEPENDENCIES", "BASE_TEST_DEPENDENCIES", "BASE_TEST_DEPENDENCIES_WITH_JSON", "BASE_TEST_DEPENDENCIES_WITH_JSON_LD")
-scala_test(
- name = "CacheSerializationSpec",
- size = "small", # 60s
- srcs = [
- "CacheSerializationSpec.scala",
- ],
- data = [
- "//knora-ontologies",
- "//test_data",
- ],
- jvm_flags = ["-Dconfig.resource=fuseki.conf"],
- # unused_dependency_checker_mode = "warn",
- deps = ALL_WEBAPI_MAIN_DEPENDENCIES + [
- "//webapi:main_library",
- "//webapi:test_library",
- ] + BASE_TEST_DEPENDENCIES,
-)
-
scala_test(
name = "CacheServiceManagerSpec",
size = "small", # 60s
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
index 7325c6a059..c171010723 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheServiceManagerSpec.scala
@@ -41,7 +41,7 @@ object CacheServiceManagerSpec {
}
/**
- * This spec is used to test [[org.knora.webapi.store.cacheservice.CacheSerialization]].
+ * This spec is used to test [[org.knora.webapi.store.cacheservice.serialization.CacheSerialization]].
*/
class CacheServiceManagerSpec extends CoreSpec(CacheServiceManagerSpec.config) {
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
index a428c4a98a..23767f367b 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
@@ -14,28 +14,21 @@ scala_test(
"//test_data",
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
+ "//webapi:test_library",
"//webapi/src/main/scala/org/knora/webapi",
- "//webapi/src/main/scala/org/knora/webapi/core",
"//webapi/src/main/scala/org/knora/webapi/messages",
- "//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem",
- "//webapi:test_library",
- "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
- "@maven//:org_slf4j_slf4j_api",
- "@maven//:com_typesafe_akka_akka_actor_2_13",
- "@maven//:com_typesafe_akka_akka_stream_2_13",
- "@maven//:com_typesafe_akka_akka_testkit_2_13",
"@maven//:com_typesafe_config",
- "@maven//:org_scalatest_scalatest_2_13",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_scalactic_scalactic_2_13",
+ "@maven//:org_scalatest_scalatest_compatible",
"@maven//:org_scalatest_scalatest_core_2_13",
- "@maven//:org_scalatest_scalatest_wordspec_2_13",
"@maven//:org_scalatest_scalatest_matchers_core_2_13",
"@maven//:org_scalatest_scalatest_shouldmatchers_2_13",
- "@maven//:org_scalatest_scalatest_compatible",
- "@maven//:org_scalactic_scalactic_2_13",
- ]
-)
\ No newline at end of file
+ "@maven//:org_scalatest_scalatest_wordspec_2_13",
+ ],
+)
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
index aa9c4ecc1b..c0dba213d0 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImplSpec.scala
@@ -18,66 +18,68 @@
* .
*/
-package org.knora.webapi
-package store.cacheservice.inmem
+package org.knora.webapi.store.cacheservice.inmem
-import messages.StringFormatter
-import messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
-import messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
-import sharedtestdata.SharedTestDataADM
+import org.knora.webapi.UnitSpec
+import org.knora.webapi.messages.StringFormatter
+import org.knora.webapi.messages.admin.responder.projectsmessages.{ProjectADM, ProjectIdentifierADM}
+import org.knora.webapi.messages.admin.responder.usersmessages.{UserADM, UserIdentifierADM}
+import org.knora.webapi.sharedtestdata.SharedTestDataADM
/**
- * This spec is used to test [[org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl]].
- */
-class CacheServiceInMemImplSpec extends CoreSpec() {
+ * This spec is used to test [[org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl]].
+ */
+class CacheServiceInMemImplSpec extends UnitSpec() {
- implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
+ implicit protected val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance
+ implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
- private val user: UserADM = SharedTestDataADM.imagesUser01
- private val project: ProjectADM = SharedTestDataADM.imagesProject
- private val inMemCache: CacheServiceInMemImpl.type = CacheServiceInMemImpl
+ private val user: UserADM = SharedTestDataADM.imagesUser01
+ private val project: ProjectADM = SharedTestDataADM.imagesProject
- "The CacheServiceInMemImpl" should {
+ private val inMemCache: CacheServiceInMemImpl.type = CacheServiceInMemImpl
- "successfully store a user" in {
- val res = inMemCache.putUserADM(user)
- res should equal(true)
- }
+ "The CacheServiceInMemImpl" should {
- "successfully retrieve a user by IRI" in {
- val res = inMemCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
- res should equal(true)
- }
+ "successfully store a user" in {
+ val resFuture = inMemCache.putUserADM(user)
+ resFuture map {res => res should equal(true)}
+ }
- "successfully retrieve a user by USERNAME" in {
- val res = inMemCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
- res should equal(true)
- }
+ "successfully retrieve a user by IRI" in {
+ val resFuture = inMemCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
+ resFuture map {res => res should equal(Some(user))}
+ }
- "successfully retrieve a user by EMAIL" in {
- val res = inMemCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
- res should equal(true)
- }
+ "successfully retrieve a user by USERNAME" in {
+ val resFuture = inMemCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
+ resFuture map {res => res should equal(Some(user))}
+ }
- "successfully store a project" in {
- val res = inMemCache.putProjectADM(project)
- res should equal(true)
- }
+ "successfully retrieve a user by EMAIL" in {
+ val resFuture = inMemCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
+ resFuture map {res => res should equal(Some(user))}
+ }
- "successfully retrieve a project by IRI" in {
- val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
- res should equal(true)
- }
+ "successfully store a project" in {
+ val resFuture = inMemCache.putProjectADM(project)
+ resFuture map { res => res should equal(true)}
+ }
- "successfully retrieve a project by SHORTNAME" in {
- val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
- res should equal(true)
- }
+ "successfully retrieve a project by IRI" in {
+ val resFuture = inMemCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
+ resFuture map { res => res should equal(Some(project))}
+ }
+
+ "successfully retrieve a project by SHORTNAME" in {
+ val resFuture = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
+ resFuture map { res => res should equal(Some(project))}
+ }
- "successfully retrieve a project by SHORTCODE" in {
- val res = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
- res should equal(true)
+ "successfully retrieve a project by SHORTCODE" in {
+ val resFuture = inMemCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
+ resFuture map { res => res should equal(Some(project))}
+ }
}
- }
}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index 28fbc5e59a..0e03b52e0a 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -9,34 +9,32 @@ scala_test(
srcs = [
"CacheServiceRedisImplSpec.scala",
],
+ resources = [
+ "//webapi/src/main/resources",
+ "//webapi/src/test/resources",
+ ],
data = [
"//knora-ontologies",
"//test_data",
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
+ "//webapi:test_library",
"//webapi/src/main/scala/org/knora/webapi",
- "//webapi/src/main/scala/org/knora/webapi/core",
"//webapi/src/main/scala/org/knora/webapi/messages",
- "//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
- "//webapi:test_library",
- "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
- "@maven//:org_slf4j_slf4j_api",
- "@maven//:com_typesafe_akka_akka_actor_2_13",
- "@maven//:com_typesafe_akka_akka_stream_2_13",
- "@maven//:com_typesafe_akka_akka_testkit_2_13",
"@maven//:com_typesafe_config",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_scalactic_scalactic_2_13",
"@maven//:org_scalatest_scalatest_2_13",
+ "@maven//:org_scalatest_scalatest_compatible",
"@maven//:org_scalatest_scalatest_core_2_13",
- "@maven//:org_scalatest_scalatest_wordspec_2_13",
"@maven//:org_scalatest_scalatest_matchers_core_2_13",
"@maven//:org_scalatest_scalatest_shouldmatchers_2_13",
- "@maven//:org_scalatest_scalatest_compatible",
- "@maven//:org_scalactic_scalactic_2_13",
+ "@maven//:org_scalatest_scalatest_wordspec_2_13",
],
-)
\ No newline at end of file
+)
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
index d4bfd74dcb..276bf8f6d2 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImplSpec.scala
@@ -48,43 +48,43 @@ class CacheServiceRedisImplSpec extends UnitSpec(RedisTestContainer.PortConfig)
"The CacheServiceRedisImpl" should {
"successfully store a user" in {
- val res = redisCache.putUserADM(user)
- res should equal(true)
+ val resFuture = redisCache.putUserADM(user)
+ resFuture map {res => res should equal(true)}
}
"successfully retrieve a user by IRI" in {
- val res = redisCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
- res should equal(true)
+ val resFuture = redisCache.getUserADM(UserIdentifierADM(maybeIri = Some(user.id)))
+ resFuture map {res => res should equal(Some(user))}
}
"successfully retrieve a user by USERNAME" in {
- val res = redisCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
- res should equal(true)
+ val resFuture = redisCache.getUserADM(UserIdentifierADM(maybeUsername = Some(user.username)))
+ resFuture map {res => res should equal(Some(user))}
}
"successfully retrieve a user by EMAIL" in {
- val res = redisCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
- res should equal(true)
+ val resFuture = redisCache.getUserADM(UserIdentifierADM(maybeEmail = Some(user.email)))
+ resFuture map {res => res should equal(Some(user))}
}
"successfully store a project" in {
- val res = redisCache.putProjectADM(project)
- res should equal(true)
+ val resFuture = redisCache.putProjectADM(project)
+ resFuture map { res => res should equal(true)}
}
"successfully retrieve a project by IRI" in {
- val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
- res should equal(true)
+ val resFuture = redisCache.getProjectADM(ProjectIdentifierADM(maybeIri = Some(project.id)))
+ resFuture map { res => res should equal(Some(project))}
}
"successfully retrieve a project by SHORTNAME" in {
- val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
- res should equal(true)
+ val resFuture = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortname = Some(project.shortname)))
+ resFuture map { res => res should equal(Some(project))}
}
"successfully retrieve a project by SHORTCODE" in {
- val res = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
- res should equal(true)
+ val resFuture = redisCache.getProjectADM(ProjectIdentifierADM(maybeShortcode = Some(project.shortcode)))
+ resFuture map { res => res should equal(Some(project))}
}
}
}
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
new file mode 100644
index 0000000000..f0e2a42a66
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
@@ -0,0 +1,37 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test")
+
+scala_test(
+ name = "CacheSerializationSpec",
+ size = "small", # 60s
+ srcs = [
+ "CacheSerializationSpec.scala",
+ ],
+ data = [
+ "//knora-ontologies",
+ "//test_data",
+ ],
+ jvm_flags = ["-Dconfig.resource=fuseki.conf"],
+ unused_dependency_checker_mode = "warn",
+ deps = [
+ "//webapi:test_library",
+ "//webapi/src/main/scala/org/knora/webapi",
+ "//webapi/src/main/scala/org/knora/webapi/core",
+ "//webapi/src/main/scala/org/knora/webapi/instrumentation",
+ "//webapi/src/main/scala/org/knora/webapi/messages",
+ "//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization",
+ "@maven//:com_typesafe_akka_akka_actor_2_13",
+ "@maven//:com_typesafe_akka_akka_stream_2_13",
+ "@maven//:com_typesafe_akka_akka_testkit_2_13",
+ "@maven//:com_typesafe_config",
+ "@maven//:com_typesafe_scala_logging_scala_logging_2_13",
+ "@maven//:org_scalactic_scalactic_2_13",
+ "@maven//:org_scalatest_scalatest_compatible",
+ "@maven//:org_scalatest_scalatest_core_2_13",
+ "@maven//:org_scalatest_scalatest_matchers_core_2_13",
+ "@maven//:org_scalatest_scalatest_shouldmatchers_2_13",
+ "@maven//:org_scalatest_scalatest_wordspec_2_13",
+ ],
+)
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
similarity index 92%
rename from webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala
rename to webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
index f9baad5d12..149b69bef1 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/CacheSerializationSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
@@ -18,10 +18,10 @@
* .
*/
-package org.knora.webapi.store.cacheservice
+package org.knora.webapi.store.cacheservice.serialization
import com.typesafe.config.ConfigFactory
-import org.knora.webapi._
+import org.knora.webapi.CoreSpec
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectADM
import org.knora.webapi.messages.admin.responder.usersmessages.UserADM
import org.knora.webapi.sharedtestdata.SharedTestDataADM
@@ -34,7 +34,7 @@ object CacheSerializationSpec {
}
/**
- * This spec is used to test [[org.knora.webapi.store.cacheservice.CacheSerialization]].
+ * This spec is used to test [[CacheSerialization]].
*/
class CacheSerializationSpec extends CoreSpec(CacheSerializationSpec.config) {
From 6a0a459f057b6a0c8ccc0a93e3f429f7302f7a02 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Thu, 10 Jun 2021 23:54:00 +0200
Subject: [PATCH 07/12] test(cache-service): add unit and integration tests
---
.../webapi/store/cacheservice/serialization/BUILD.bazel | 5 -----
.../cacheservice/serialization/CacheSerializationSpec.scala | 6 ++++--
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
index f0e2a42a66..2a87201970 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/BUILD.bazel
@@ -17,14 +17,9 @@ scala_test(
deps = [
"//webapi:test_library",
"//webapi/src/main/scala/org/knora/webapi",
- "//webapi/src/main/scala/org/knora/webapi/core",
"//webapi/src/main/scala/org/knora/webapi/instrumentation",
"//webapi/src/main/scala/org/knora/webapi/messages",
- "//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization",
- "@maven//:com_typesafe_akka_akka_actor_2_13",
- "@maven//:com_typesafe_akka_akka_stream_2_13",
- "@maven//:com_typesafe_akka_akka_testkit_2_13",
"@maven//:com_typesafe_config",
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
"@maven//:org_scalactic_scalactic_2_13",
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
index 149b69bef1..769c22511b 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerializationSpec.scala
@@ -21,7 +21,7 @@
package org.knora.webapi.store.cacheservice.serialization
import com.typesafe.config.ConfigFactory
-import org.knora.webapi.CoreSpec
+import org.knora.webapi.UnitSpec
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectADM
import org.knora.webapi.messages.admin.responder.usersmessages.UserADM
import org.knora.webapi.sharedtestdata.SharedTestDataADM
@@ -36,7 +36,9 @@ object CacheSerializationSpec {
/**
* This spec is used to test [[CacheSerialization]].
*/
-class CacheSerializationSpec extends CoreSpec(CacheSerializationSpec.config) {
+class CacheSerializationSpec extends UnitSpec(CacheSerializationSpec.config) {
+
+ implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
"serialize and deserialize" should {
From c3a65ef1f4451fad79dce57eb5fe7030aad68da7 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Fri, 11 Jun 2021 11:44:59 +0200
Subject: [PATCH 08/12] test(cache-service): add unit and integration tests
---
webapi/BUILD.bazel | 3 ++-
.../knora/webapi/app/ApplicationActor.scala | 17 +++---------
.../scala/org/knora/webapi/app/BUILD.bazel | 1 +
.../scala/org/knora/webapi/CoreSpec.scala | 8 +++---
.../org/knora/webapi/KnoraFakeCore.scala | 2 +-
.../knora/webapi/ManagersWithMockedSipi.scala | 26 +++++++++----------
.../test/scala/org/knora/webapi/R2RSpec.scala | 4 +--
.../org/knora/webapi/TestContainers.scala | 16 +++++++-----
.../scala/org/knora/webapi/UnitSpec.scala | 4 +--
.../v1/ResourcesResponderV1Spec.scala | 4 +--
10 files changed, 40 insertions(+), 45 deletions(-)
diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel
index 7f0155fcd6..6a44677bed 100644
--- a/webapi/BUILD.bazel
+++ b/webapi/BUILD.bazel
@@ -141,6 +141,7 @@ scala_library(
"//sipi/config",
"//webapi/src/test/resources",
],
+ scalacopts = ["-deprecation"],
unused_dependency_checker_mode = "warn",
runtime_deps = [
"@maven//:ch_qos_logback_logback_classic",
@@ -163,7 +164,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
- "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
# Logging
diff --git a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
index 855888114f..10766d2bd0 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
@@ -31,23 +31,14 @@ import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings
import com.typesafe.scalalogging.LazyLogging
import kamon.Kamon
import org.knora.webapi.core.{Core, LiveActorMaker}
-import org.knora.webapi.exceptions.{
- InconsistentRepositoryDataException,
- SipiException,
- UnexpectedMessageException,
- UnsupportedValueException
-}
+import org.knora.webapi.exceptions.{InconsistentRepositoryDataException, SipiException, UnexpectedMessageException, UnsupportedValueException}
import org.knora.webapi.feature.{FeatureFactoryConfig, KnoraSettingsFeatureFactoryConfig}
import org.knora.webapi.http.directives.DSPApiDirectives
import org.knora.webapi.http.version.ServerVersion
import org.knora.webapi.messages.admin.responder.KnoraRequestADM
import org.knora.webapi.messages.app.appmessages._
import org.knora.webapi.messages.store.StoreRequest
-import org.knora.webapi.messages.store.cacheservicemessages.{
- CacheServiceGetStatus,
- CacheServiceStatusNOK,
- CacheServiceStatusOK
-}
+import org.knora.webapi.messages.store.cacheservicemessages.{CacheServiceGetStatus, CacheServiceStatusNOK, CacheServiceStatusOK}
import org.knora.webapi.messages.store.sipimessages.{IIIFServiceGetStatus, IIIFServiceStatusNOK, IIIFServiceStatusOK}
import org.knora.webapi.messages.store.triplestoremessages._
import org.knora.webapi.messages.util.{KnoraSystemInstances, ResponderData}
@@ -61,6 +52,7 @@ import org.knora.webapi.routing.v1._
import org.knora.webapi.routing.v2._
import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
import org.knora.webapi.store.StoreManager
+import org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl
import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
import org.knora.webapi.util.cache.CacheUtil
@@ -84,8 +76,7 @@ trait LiveManagers extends Managers {
*/
lazy val storeManager: ActorRef = context.actorOf(
Props(
- new StoreManager(appActor = self,
- cs = new CacheServiceRedisImpl(new CacheServiceSettings(system.settings.config)))
+ new StoreManager(appActor = self, cs = CacheServiceInMemImpl)
with LiveActorMaker)
.withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
name = StoreManagerActorName
diff --git a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
index 4de5fcbf88..00ed4ee205 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/app/BUILD.bazel
@@ -20,6 +20,7 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/settings",
"//webapi/src/main/scala/org/knora/webapi/store",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis",
"//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
diff --git a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
index 016662bea3..03fc01918d 100644
--- a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
@@ -64,8 +64,8 @@ object CoreSpec {
val s = (Thread.currentThread.getStackTrace map (_.getClassName) drop 1)
.dropWhile(_ matches "(java.lang.Thread|.*CoreSpec.?$)")
val reduced = s.lastIndexWhere(_ == clazz.getName) match {
- case -1 ⇒ s
- case z ⇒ s drop (z + 1)
+ case -1 => s
+ case z => s drop (z + 1)
}
reduced.head.replaceFirst(""".*\.""", "").replaceAll("[^a-zA-Z_0-9]", "_")
}
@@ -133,7 +133,7 @@ abstract class CoreSpec(_system: ActorSystem)
parent = new KnoraSettingsFeatureFactoryConfig(settings)
)
- final override def beforeAll() {
+ final override def beforeAll(): () = {
// set allow reload over http
appActor ! SetAllowReloadOverHTTPState(true)
@@ -148,7 +148,7 @@ abstract class CoreSpec(_system: ActorSystem)
// memusage()
}
- final override def afterAll() {
+ final override def afterAll(): () = {
appActor ! AppStop()
// memusage()
}
diff --git a/webapi/src/test/scala/org/knora/webapi/KnoraFakeCore.scala b/webapi/src/test/scala/org/knora/webapi/KnoraFakeCore.scala
index 8b2ec42ff7..7aa0c72916 100644
--- a/webapi/src/test/scala/org/knora/webapi/KnoraFakeCore.scala
+++ b/webapi/src/test/scala/org/knora/webapi/KnoraFakeCore.scala
@@ -66,7 +66,7 @@ trait KnoraFakeCore {
* Starts the Faked Knora API server.
*/
def startService(): Unit = {
- Http().bindAndHandle(Route.handlerFlow(apiRoutes), settings.internalKnoraApiHost, settings.internalKnoraApiPort)
+ Http().newServerAt(settings.internalKnoraApiHost, settings.internalKnoraApiPort).bindFlow(Route.toFlow(apiRoutes))
println(
s"Faked Knora API Server started at http://${settings.internalKnoraApiHost}:${settings.internalKnoraApiPort}.")
}
diff --git a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
index 2b192b1ba0..664afd4f0a 100644
--- a/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
+++ b/webapi/src/test/scala/org/knora/webapi/ManagersWithMockedSipi.scala
@@ -19,17 +19,16 @@
package org.knora.webapi
-import app.Managers
-import core.LiveActorMaker
-import messages.util.ResponderData
-import responders.MockableResponderManager
-import settings._
-import store.MockableStoreManager
-import store.cacheservice.redis.CacheServiceRedisImpl
-import store.cacheservice.settings.CacheServiceSettings
-import store.iiif.MockSipiConnector
-
import akka.actor.{Actor, ActorRef, Props}
+import org.knora.webapi.app.Managers
+import org.knora.webapi.core.LiveActorMaker
+import org.knora.webapi.messages.util.ResponderData
+import org.knora.webapi.responders.MockableResponderManager
+import org.knora.webapi.settings._
+import org.knora.webapi.store.MockableStoreManager
+import org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl
+import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
+import org.knora.webapi.store.iiif.MockSipiConnector
/**
* Mixin trait for running the application with mocked Sipi
@@ -43,10 +42,9 @@ trait ManagersWithMockedSipi extends Managers {
lazy val storeManager: ActorRef = context.actorOf(
Props(
- new MockableStoreManager(mockStoreConnectors = mockStoreConnectors,
- appActor = self,
- cs = new CacheServiceRedisImpl(new CacheServiceSettings(context.system.settings.config)))
- with LiveActorMaker),
+ new MockableStoreManager(mockStoreConnectors = mockStoreConnectors, appActor = self, cs = CacheServiceInMemImpl)
+ with LiveActorMaker
+ ),
name = StoreManagerActorName
)
diff --git a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
index 00b7cf58e9..e9fbcd7edd 100644
--- a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
@@ -108,7 +108,7 @@ class R2RSpec
val log: LoggingAdapter = akka.event.Logging(system, this.getClass)
- override def beforeAll() {
+ override def beforeAll(): () = {
// set allow reload over http
appActor ! SetAllowReloadOverHTTPState(true)
@@ -121,7 +121,7 @@ class R2RSpec
loadTestData(rdfDataObjects)
}
- override def afterAll() {
+ override def afterAll(): () = {
/* Stop the server when everything else has finished */
appActor ! AppStop()
}
diff --git a/webapi/src/test/scala/org/knora/webapi/TestContainers.scala b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
index 5f6fa430bd..8b1727b56f 100644
--- a/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
+++ b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
@@ -64,16 +64,20 @@ object TestContainers {
val sipiIp: String = SipiContainer.getHost
val sipiPort: Int = SipiContainer.getFirstMappedPort
- val RedisImageName: DockerImageName = DockerImageName.parse("redis:5")
- val RedisContainer = new GenericContainer(RedisImageName)
- RedisContainer.withExposedPorts(6379)
- RedisContainer.start()
+
+ // The new default is the inmem cache implementation, so no need
+ // for a container
+ //
+ // val RedisImageName: DockerImageName = DockerImageName.parse("redis:5")
+ // val RedisContainer = new GenericContainer(RedisImageName)
+ // RedisContainer.withExposedPorts(6379)
+ // RedisContainer.start()
private val portMap = Map(
"app.triplestore.fuseki.port" -> FusekiContainer.getFirstMappedPort,
"app.sipi.internal-host" -> sipiIp,
- "app.sipi.internal-port" -> sipiPort,
- "app.cache-service.redis.port" -> RedisContainer.getFirstMappedPort
+ "app.sipi.internal-port" -> sipiPort
+ // "app.cache-service.redis.port" -> RedisContainer.getFirstMappedPort
).asJava
// all tests need to be configured with these ports.
diff --git a/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
index a67271e5cb..c8c66ba929 100644
--- a/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/UnitSpec.scala
@@ -44,8 +44,8 @@ object UnitSpec {
val s = (Thread.currentThread.getStackTrace map (_.getClassName) drop 1)
.dropWhile(_ matches "(java.lang.Thread|.*UnitSpec.?$)")
val reduced = s.lastIndexWhere(_ == clazz.getName) match {
- case -1 ⇒ s
- case z ⇒ s drop (z + 1)
+ case -1 => s
+ case z => s drop (z + 1)
}
reduced.head.replaceFirst(""".*\.""", "").replaceAll("[^a-zA-Z_0-9]", "_")
}
diff --git a/webapi/src/test/scala/org/knora/webapi/responders/v1/ResourcesResponderV1Spec.scala b/webapi/src/test/scala/org/knora/webapi/responders/v1/ResourcesResponderV1Spec.scala
index c98b1884b9..e4dceffe2c 100644
--- a/webapi/src/test/scala/org/knora/webapi/responders/v1/ResourcesResponderV1Spec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/responders/v1/ResourcesResponderV1Spec.scala
@@ -675,11 +675,11 @@ class ResourcesResponderV1Spec extends CoreSpec(ResourcesResponderV1Spec.config)
case (expectedProp: PropertyV1, receivedProp: PropertyV1) =>
// sort property attributes
val expectedPropWithSortedAttr = expectedProp.copy(
- attributes = expectedProp.attributes.sorted
+ attributes = expectedProp.attributes.toSeq.sorted.unwrap
)
val receivedPropWithSortedAttr = receivedProp.copy(
- attributes = receivedProp.attributes.sorted
+ attributes = receivedProp.attributes.toSeq.sorted.unwrap
)
assert(
From 32e621d9666503d23373c72b19d6cb5cf5af87b6 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Fri, 11 Jun 2021 12:41:27 +0200
Subject: [PATCH 09/12] chore(build): cleanup
---
webapi/BUILD.bazel | 2 +-
.../src/main/scala/org/knora/webapi/messages/BUILD.bazel | 4 ++--
.../main/scala/org/knora/webapi/responders/BUILD.bazel | 4 ++--
.../src/main/scala/org/knora/webapi/settings/BUILD.bazel | 2 +-
.../org/knora/webapi/store/cacheservice/inmem/BUILD.bazel | 2 +-
.../org/knora/webapi/store/cacheservice/redis/BUILD.bazel | 8 ++++----
6 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel
index 6a44677bed..eded0335cd 100644
--- a/webapi/BUILD.bazel
+++ b/webapi/BUILD.bazel
@@ -30,6 +30,7 @@ scala_library(
"//webapi/scripts:fuseki_repository_config_ttl_template",
"//webapi/src/main/resources",
],
+ scalacopts = ["-deprecation"],
unused_dependency_checker_mode = "warn",
runtime_deps = [
"@maven//:ch_qos_logback_logback_classic",
@@ -37,7 +38,6 @@ scala_library(
"@maven//:com_typesafe_akka_akka_slf4j_2_13",
"@maven//:org_slf4j_log4j_over_slf4j",
],
- scalacopts=["-deprecation"],
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/core",
diff --git a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
index 5ab1063965..5efc64ca71 100644
--- a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel
@@ -5,17 +5,17 @@ load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
scala_library(
name = "messages",
srcs = glob(["**/*.scala"]) + ["//webapi/src/main/twirl:twirl_sources"],
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/annotation",
"//webapi/src/main/scala/org/knora/webapi/exceptions",
"//webapi/src/main/scala/org/knora/webapi/feature",
"//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
- "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_apicatalog_titanium_json_ld",
"@maven//:com_google_gwt_gwt_servlet",
"@maven//:com_ibm_icu_icu4j",
diff --git a/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
index 53108e1fbb..de680f45a3 100644
--- a/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/responders/BUILD.bazel
@@ -5,8 +5,8 @@ load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
scala_library(
name = "responders",
srcs = glob(["**/*.scala"]),
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi",
"//webapi/src/main/scala/org/knora/webapi/annotation",
@@ -16,9 +16,9 @@ scala_library(
"//webapi/src/main/scala/org/knora/webapi/instrumentation",
"//webapi/src/main/scala/org/knora/webapi/messages",
"//webapi/src/main/scala/org/knora/webapi/settings",
+ "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"//webapi/src/main/scala/org/knora/webapi/util",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
- "//webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings",
"@maven//:com_typesafe_akka_akka_actor_2_13",
"@maven//:com_typesafe_akka_akka_http_2_13",
"@maven//:com_typesafe_akka_akka_http_core_2_13",
diff --git a/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
index a8530bc445..995c612376 100644
--- a/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/settings/BUILD.bazel
@@ -5,8 +5,8 @@ load("@io_bazel_rules_scala//scala:scala.bzl", "scala_library")
scala_library(
name = "settings",
srcs = glob(["*.scala"]),
- unused_dependency_checker_mode = "warn",
scalacopts = ["-deprecation"],
+ unused_dependency_checker_mode = "warn",
deps = [
"//webapi/src/main/scala/org/knora/webapi/exceptions",
"//webapi/src/main/scala/org/knora/webapi/util/cache",
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
index f0ebb19931..a3310bda75 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/BUILD.bazel
@@ -21,4 +21,4 @@ scala_library(
"@maven//:com_typesafe_scala_logging_scala_logging_2_13",
"@maven//:org_slf4j_slf4j_api",
],
-)
\ No newline at end of file
+)
diff --git a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
index 0e03b52e0a..71f71fc93b 100644
--- a/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
+++ b/webapi/src/test/scala/org/knora/webapi/store/cacheservice/redis/BUILD.bazel
@@ -9,15 +9,15 @@ scala_test(
srcs = [
"CacheServiceRedisImplSpec.scala",
],
- resources = [
- "//webapi/src/main/resources",
- "//webapi/src/test/resources",
- ],
data = [
"//knora-ontologies",
"//test_data",
],
jvm_flags = ["-Dconfig.resource=fuseki.conf"],
+ resources = [
+ "//webapi/src/main/resources",
+ "//webapi/src/test/resources",
+ ],
scalacopts = ["-deprecation"],
unused_dependency_checker_mode = "warn",
deps = [
From c8db4da46dec6a47016c7ae9b091b071509e6957 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Mon, 14 Jun 2021 13:18:01 +0200
Subject: [PATCH 10/12] chore(build): cleanup
---
.../store/cacheservice/settings/CacheServiceSettings.scala | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
index c836128b38..be1235b5a9 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/settings/CacheServiceSettings.scala
@@ -18,8 +18,7 @@
* .
*/
-package org.knora.webapi
-package store.cacheservice.settings
+package org.knora.webapi.store.cacheservice.settings
import com.typesafe.config.Config
From 5c99338a7a4986854ec7c6dc07a102716de7025e Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Mon, 14 Jun 2021 13:56:35 +0200
Subject: [PATCH 11/12] chore(build): cleanup
---
.../knora/webapi/app/ApplicationActor.scala | 20 ++++++++++++-------
.../serialization/CacheSerialization.scala | 8 +++-----
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
index 10766d2bd0..1f90bee9f6 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
@@ -30,15 +30,24 @@ import ch.megard.akka.http.cors.scaladsl.CorsDirectives
import ch.megard.akka.http.cors.scaladsl.settings.CorsSettings
import com.typesafe.scalalogging.LazyLogging
import kamon.Kamon
-import org.knora.webapi.core.{Core, LiveActorMaker}
-import org.knora.webapi.exceptions.{InconsistentRepositoryDataException, SipiException, UnexpectedMessageException, UnsupportedValueException}
+import org.knora.webapi.core.LiveActorMaker
+import org.knora.webapi.exceptions.{
+ InconsistentRepositoryDataException,
+ SipiException,
+ UnexpectedMessageException,
+ UnsupportedValueException
+}
import org.knora.webapi.feature.{FeatureFactoryConfig, KnoraSettingsFeatureFactoryConfig}
import org.knora.webapi.http.directives.DSPApiDirectives
import org.knora.webapi.http.version.ServerVersion
import org.knora.webapi.messages.admin.responder.KnoraRequestADM
import org.knora.webapi.messages.app.appmessages._
import org.knora.webapi.messages.store.StoreRequest
-import org.knora.webapi.messages.store.cacheservicemessages.{CacheServiceGetStatus, CacheServiceStatusNOK, CacheServiceStatusOK}
+import org.knora.webapi.messages.store.cacheservicemessages.{
+ CacheServiceGetStatus,
+ CacheServiceStatusNOK,
+ CacheServiceStatusOK
+}
import org.knora.webapi.messages.store.sipimessages.{IIIFServiceGetStatus, IIIFServiceStatusNOK, IIIFServiceStatusOK}
import org.knora.webapi.messages.store.triplestoremessages._
import org.knora.webapi.messages.util.{KnoraSystemInstances, ResponderData}
@@ -53,7 +62,6 @@ import org.knora.webapi.routing.v2._
import org.knora.webapi.settings.{KnoraDispatchers, KnoraSettings, KnoraSettingsImpl, _}
import org.knora.webapi.store.StoreManager
import org.knora.webapi.store.cacheservice.inmem.CacheServiceInMemImpl
-import org.knora.webapi.store.cacheservice.redis.CacheServiceRedisImpl
import org.knora.webapi.store.cacheservice.settings.CacheServiceSettings
import org.knora.webapi.util.cache.CacheUtil
import redis.clients.jedis.exceptions.JedisConnectionException
@@ -75,9 +83,7 @@ trait LiveManagers extends Managers {
* The actor that forwards messages to actors that deal with persistent storage.
*/
lazy val storeManager: ActorRef = context.actorOf(
- Props(
- new StoreManager(appActor = self, cs = CacheServiceInMemImpl)
- with LiveActorMaker)
+ Props(new StoreManager(appActor = self, cs = CacheServiceInMemImpl) with LiveActorMaker)
.withDispatcher(KnoraDispatchers.KnoraActorDispatcher),
name = StoreManagerActorName
)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
index ab0cc37f01..eec7f3238c 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/serialization/CacheSerialization.scala
@@ -18,13 +18,11 @@
* .
*/
-package org.knora.webapi
-package store.cacheservice.serialization
-
-import exceptions.CacheServiceException
-import instrumentation.InstrumentationSupport
+package org.knora.webapi.store.cacheservice.serialization
import com.twitter.chill.MeatLocker
+import org.knora.webapi.exceptions.CacheServiceException
+import org.knora.webapi.instrumentation.InstrumentationSupport
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream}
import scala.concurrent.{ExecutionContext, Future}
From 830b0bd9e30db119c04e3a2d3f3c12c52d6d87d8 Mon Sep 17 00:00:00 2001
From: Ivan Subotic <400790+subotic@users.noreply.github.com>
Date: Tue, 15 Jun 2021 09:12:39 +0200
Subject: [PATCH 12/12] chore(cache-service): cleanup
---
.../org/knora/webapi/settings/KnoraSettings.scala | 3 ---
.../cacheservice/inmem/CacheServiceInMemImpl.scala | 12 ++++++------
.../cacheservice/redis/CacheServiceRedisImpl.scala | 4 ++--
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala b/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
index 7166ed4525..62011d7f41 100644
--- a/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
+++ b/webapi/src/main/scala/org/knora/webapi/settings/KnoraSettings.scala
@@ -270,9 +270,6 @@ class KnoraSettingsImpl(config: Config, log: LoggingAdapter) extends Extension {
val bcryptPasswordStrength: Int = config.getInt("app.bcrypt-password-strength")
- // Cache Service
- // moved, see org.knora.webapi.store.cacheservice.settings
-
// Client test data service
val collectClientTestData: Boolean = if (config.hasPath("app.client-test-data-service.collect-client-test-data")) {
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
index 03fdbc347e..b4621e9d55 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/inmem/CacheServiceInMemImpl.scala
@@ -63,11 +63,11 @@ object CacheServiceInMemImpl extends CacheService with LazyLogging {
* Retrieves the user stored under the identifier (either iri, username,
* or email).
*
- * @param identifier the project identifier.
+ * @param identifier the user identifier.
*/
def getUserADM(identifier: UserIdentifierADM)(implicit ec: ExecutionContext): Future[Option[UserADM]] = {
// The data is stored under the IRI key.
- // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ // Additionally, the USERNAME and EMAIL keys point to the IRI key
val resultFuture: Future[Option[UserADM]] = identifier.hasType match {
case UserIdentifierType.IRI => FastFuture.successful(cache.get(identifier.toIri).map(_.asInstanceOf[UserADM]))
case UserIdentifierType.USERNAME => {
@@ -136,10 +136,10 @@ object CacheServiceInMemImpl extends CacheService with LazyLogging {
def writeStringValue(key: String, value: String)(implicit ec: ExecutionContext): Future[Boolean] = {
if (key.isEmpty)
- throw EmptyKey("The key under which the value should be written is empty. Aborting writing to redis.")
+ throw EmptyKey("The key under which the value should be written is empty. Aborting writing to in-memory cache.")
if (value.isEmpty)
- throw EmptyValue("The string value is empty. Aborting writing to redis.")
+ throw EmptyValue("The string value is empty. Aborting writing to in-memory cache.")
cache(key) = value
FastFuture.successful(true)
@@ -175,7 +175,7 @@ object CacheServiceInMemImpl extends CacheService with LazyLogging {
}
/**
- * Flushes (removes) all stored content from the Redis store.
+ * Flushes (removes) all stored content from the in-memory cache.
*/
def flushDB(requestingUser: UserADM)(implicit ec: ExecutionContext): Future[CacheServiceFlushDBACK] = {
cache = scala.collection.mutable.Map[Any, Any]()
@@ -183,7 +183,7 @@ object CacheServiceInMemImpl extends CacheService with LazyLogging {
}
/**
- * Pings the Redis store to see if it is available.
+ * Pings the in-memory cache to see if it is available.
*/
def ping()(implicit ec: ExecutionContext): Future[CacheServiceStatusResponse] = {
FastFuture.successful(CacheServiceStatusOK)
diff --git a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
index e42f5c036b..da0e2e7b2a 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/cacheservice/redis/CacheServiceRedisImpl.scala
@@ -85,11 +85,11 @@ class CacheServiceRedisImpl(s: CacheServiceSettings) extends CacheService with L
* Retrieves the user stored under the identifier (either iri, username,
* or email).
*
- * @param identifier the project identifier.
+ * @param identifier the user identifier.
*/
def getUserADM(identifier: UserIdentifierADM)(implicit ec: ExecutionContext): Future[Option[UserADM]] = {
// The data is stored under the IRI key.
- // Additionally, the SHORTNAME and SHORTCODE keys point to the IRI key
+ // Additionally, the USERNAME and EMAIL keys point to the IRI key
val resultFuture: Future[Option[UserADM]] = identifier.hasType match {
case UserIdentifierType.IRI =>
for {