aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/xyz/driver/common')
-rw-r--r--src/main/scala/xyz/driver/common/Config.scala22
-rw-r--r--src/main/scala/xyz/driver/common/TimeLogger.scala15
-rw-r--r--src/main/scala/xyz/driver/common/acl/ACL.scala202
-rw-r--r--src/main/scala/xyz/driver/common/auth/AnonymousRequestContext.scala12
-rw-r--r--src/main/scala/xyz/driver/common/auth/AuthenticatedRequestContext.scala32
-rw-r--r--src/main/scala/xyz/driver/common/auth/RequestId.scala15
-rw-r--r--src/main/scala/xyz/driver/common/compat/EitherOps.scala12
-rw-r--r--src/main/scala/xyz/driver/common/compat/Implicits.scala7
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueue.scala88
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueueRepositoryAdapter.scala136
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/Cron.scala97
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/InMemoryBridgeUploadQueue.scala38
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/MdcExecutionContext.scala35
-rw-r--r--src/main/scala/xyz/driver/common/concurrent/MdcThreadFactory.scala33
-rw-r--r--src/main/scala/xyz/driver/common/db/DbCommand.scala15
-rw-r--r--src/main/scala/xyz/driver/common/db/DbCommandFactory.scala14
-rw-r--r--src/main/scala/xyz/driver/common/db/EntityExtractorDerivation.scala71
-rw-r--r--src/main/scala/xyz/driver/common/db/EntityNotFoundException.scala10
-rw-r--r--src/main/scala/xyz/driver/common/db/MysqlQueryBuilder.scala90
-rw-r--r--src/main/scala/xyz/driver/common/db/Pagination.scala20
-rw-r--r--src/main/scala/xyz/driver/common/db/QueryBuilder.scala344
-rw-r--r--src/main/scala/xyz/driver/common/db/SearchFilterExpr.scala210
-rw-r--r--src/main/scala/xyz/driver/common/db/Sorting.scala62
-rw-r--r--src/main/scala/xyz/driver/common/db/SqlContext.scala184
-rw-r--r--src/main/scala/xyz/driver/common/db/Transactions.scala23
-rw-r--r--src/main/scala/xyz/driver/common/db/repositories/BridgeUploadQueueRepository.scala24
-rw-r--r--src/main/scala/xyz/driver/common/db/repositories/Repository.scala4
-rw-r--r--src/main/scala/xyz/driver/common/db/repositories/RepositoryLogging.scala62
-rw-r--r--src/main/scala/xyz/driver/common/domain/CaseId.scala10
-rw-r--r--src/main/scala/xyz/driver/common/domain/Category.scala21
-rw-r--r--src/main/scala/xyz/driver/common/domain/Email.scala3
-rw-r--r--src/main/scala/xyz/driver/common/domain/FuzzyValue.scala17
-rw-r--r--src/main/scala/xyz/driver/common/domain/Id.scala51
-rw-r--r--src/main/scala/xyz/driver/common/domain/Label.scala15
-rw-r--r--src/main/scala/xyz/driver/common/domain/PasswordHash.scala42
-rw-r--r--src/main/scala/xyz/driver/common/domain/RecordRequestId.scala16
-rw-r--r--src/main/scala/xyz/driver/common/domain/TextJson.scala14
-rw-r--r--src/main/scala/xyz/driver/common/domain/User.scala74
-rw-r--r--src/main/scala/xyz/driver/common/error/DomainError.scala31
-rw-r--r--src/main/scala/xyz/driver/common/error/ExceptionFormatter.scala19
-rw-r--r--src/main/scala/xyz/driver/common/error/FailedValidationException.scala5
-rw-r--r--src/main/scala/xyz/driver/common/error/IncorrectIdException.scala3
-rw-r--r--src/main/scala/xyz/driver/common/http/AsyncHttpClientFetcher.scala90
-rw-r--r--src/main/scala/xyz/driver/common/http/AsyncHttpClientUploader.scala116
-rw-r--r--src/main/scala/xyz/driver/common/http/package.scala9
-rw-r--r--src/main/scala/xyz/driver/common/logging/DefaultPhiLogger.scala17
-rw-r--r--src/main/scala/xyz/driver/common/logging/Implicits.scala62
-rw-r--r--src/main/scala/xyz/driver/common/logging/PhiLogger.scala15
-rw-r--r--src/main/scala/xyz/driver/common/logging/PhiLogging.scala20
-rw-r--r--src/main/scala/xyz/driver/common/logging/PhiString.scala6
-rw-r--r--src/main/scala/xyz/driver/common/logging/PhiStringContext.scala8
-rw-r--r--src/main/scala/xyz/driver/common/logging/Unsafe.scala6
-rw-r--r--src/main/scala/xyz/driver/common/logging/package.scala3
-rw-r--r--src/main/scala/xyz/driver/common/pdf/PdfRenderer.scala13
-rw-r--r--src/main/scala/xyz/driver/common/pdf/WkHtmlToPdfRenderer.scala106
-rw-r--r--src/main/scala/xyz/driver/common/resources/ResourcesStorage.scala39
-rw-r--r--src/main/scala/xyz/driver/common/utils/Computation.scala110
-rw-r--r--src/main/scala/xyz/driver/common/utils/FutureUtils.scala19
-rw-r--r--src/main/scala/xyz/driver/common/utils/Implicits.scala22
-rw-r--r--src/main/scala/xyz/driver/common/utils/JsonSerializer.scala27
-rw-r--r--src/main/scala/xyz/driver/common/utils/MapOps.scala10
-rw-r--r--src/main/scala/xyz/driver/common/utils/RandomUtils.scala20
-rw-r--r--src/main/scala/xyz/driver/common/utils/ServiceUtils.scala32
-rw-r--r--src/main/scala/xyz/driver/common/utils/Utils.scala23
-rw-r--r--src/main/scala/xyz/driver/common/validation/ValidationError.scala3
-rw-r--r--src/main/scala/xyz/driver/common/validation/Validators.scala41
66 files changed, 0 insertions, 3015 deletions
diff --git a/src/main/scala/xyz/driver/common/Config.scala b/src/main/scala/xyz/driver/common/Config.scala
deleted file mode 100644
index d37a20a..0000000
--- a/src/main/scala/xyz/driver/common/Config.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-package xyz.driver.common
-
-import pureconfig._
-
-import scala.util.{Failure, Success, Try}
-
-object Config {
-
- implicit def productHint[T]: ProductHint[T] = ProductHint(ConfigFieldMapping(CamelCase, CamelCase))
-
- def loadConfig[Config](implicit reader: ConfigReader[Config]): Try[Config] = pureconfig.loadConfig match {
- case Right(x) => Success(x)
- case Left(e) => Failure(new RuntimeException(e.toString))
- }
-
- def loadConfig[Config](namespace: String)
- (implicit reader: ConfigReader[Config]): Try[Config] = pureconfig.loadConfig(namespace) match {
- case Right(x) => Success(x)
- case Left(e) => Failure(new RuntimeException(e.toString))
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/TimeLogger.scala b/src/main/scala/xyz/driver/common/TimeLogger.scala
deleted file mode 100644
index 154847c..0000000
--- a/src/main/scala/xyz/driver/common/TimeLogger.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package xyz.driver.common
-
-import java.time.{LocalDateTime, ZoneId}
-
-import xyz.driver.common.domain.{LongId, User}
-import xyz.driver.common.logging._
-
-object TimeLogger extends PhiLogging {
-
- def logTime(userId: LongId[User], label: String, obj: String): Unit = {
- val now = LocalDateTime.now(ZoneId.of("Z"))
- logger.info(phi"User id=$userId performed an action at ${Unsafe(label)}=$now with a ${Unsafe(obj)} ")
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/acl/ACL.scala b/src/main/scala/xyz/driver/common/acl/ACL.scala
deleted file mode 100644
index 35c2661..0000000
--- a/src/main/scala/xyz/driver/common/acl/ACL.scala
+++ /dev/null
@@ -1,202 +0,0 @@
-package xyz.driver.common.acl
-
-import xyz.driver.common.logging._
-import xyz.driver.common.auth.AuthenticatedRequestContext
-
-/**
- * @see https://driverinc.atlassian.net/wiki/display/RA/User+permissions#UserPermissions-AccessControlList
- */
-object ACL extends PhiLogging {
-
- import xyz.driver.common.domain.User.Role
- import Role._
-
- type AclCheck = Role => Boolean
-
- val Forbid: AclCheck = _ => false
-
- val Allow: AclCheck = _ => true
-
- // Common
-
- object User extends BaseACL(
- label = "user",
- create = Set(RecordAdmin, TrialAdmin, TreatmentMatchingAdmin),
- read = Allow,
- update = Allow,
- delete = Set(RecordAdmin, TrialAdmin, TreatmentMatchingAdmin)
- )
-
- object Label extends BaseACL(
- label = "label",
- read = RepRoles ++ TcRoles ++ TreatmentMatchingRoles
- )
-
- // REP
-
- object MedicalRecord extends BaseACL(
- label = "medical record",
- read = RepRoles + RoutesCurator + TreatmentMatchingAdmin,
- update = RepRoles - DocumentExtractor
- )
-
- object Document extends BaseACL(
- label = "document",
- create = Set(RecordOrganizer, RecordAdmin),
- read = RepRoles - RecordCleaner + RoutesCurator + TreatmentMatchingAdmin,
- update = RepRoles - RecordCleaner,
- delete = Set(RecordOrganizer, RecordAdmin)
- )
-
- object ExtractedData extends BaseACL(
- label = "extracted data",
- create = Set(DocumentExtractor, RecordAdmin),
- read = Set(DocumentExtractor, RecordAdmin, RoutesCurator, TreatmentMatchingAdmin),
- update = Set(DocumentExtractor, RecordAdmin),
- delete = Set(DocumentExtractor, RecordAdmin)
- )
-
- object Keyword extends BaseACL(
- label = "keyword",
- read = Set(DocumentExtractor, RecordAdmin)
- )
-
- object ProviderType extends BaseACL(
- label = "provider type",
- read = RepRoles + RoutesCurator + TreatmentMatchingAdmin
- )
-
- object DocumentType extends BaseACL(
- label = "document type",
- read = RepRoles + RoutesCurator + TreatmentMatchingAdmin
- )
-
- object Message extends BaseACL(
- label = "message",
- create = RepRoles ++ TreatmentMatchingRoles ++ TcRoles,
- read = RepRoles ++ TreatmentMatchingRoles ++ TcRoles,
- update = RepRoles ++ TreatmentMatchingRoles ++ TcRoles,
- delete = RepRoles ++ TreatmentMatchingRoles ++ TcRoles
- )
-
- // TC
-
- object Trial extends BaseACL(
- label = "trial",
- read = TcRoles + RoutesCurator + TreatmentMatchingAdmin,
- update = TcRoles
- )
-
- object StudyDesign extends BaseACL(
- label = "study design",
- read = Set(TrialSummarizer, TrialAdmin)
- )
-
- object Hypothesis extends BaseACL(
- label = "hypothesis",
- read = Set(TrialSummarizer, TrialAdmin) ++ TreatmentMatchingRoles
- )
-
- object Criterion extends BaseACL(
- label = "criterion",
- create = Set(CriteriaCurator, TrialAdmin),
- read = Set(CriteriaCurator, TrialAdmin, RoutesCurator, TreatmentMatchingAdmin),
- update = Set(CriteriaCurator, TrialAdmin),
- delete = Set(CriteriaCurator, TrialAdmin)
- )
-
- object Arm extends BaseACL(
- label = "arm",
- create = Set(TrialSummarizer, TrialAdmin),
- read = TcRoles,
- update = Set(TrialSummarizer, TrialAdmin),
- delete = Set(TrialSummarizer, TrialAdmin)
- )
-
- object Category extends BaseACL(
- label = "category",
- read = Set(DocumentExtractor, RecordAdmin, CriteriaCurator, TrialAdmin)
- )
-
- object Intervention extends BaseACL(
- label = "intervention",
- read = Set(TrialSummarizer, TrialAdmin),
- update = Set(TrialSummarizer, TrialAdmin)
- )
-
- object InterventionType extends BaseACL(
- label = "intervention type",
- read = Set(TrialSummarizer, TrialAdmin)
- )
-
- // EV
-
- object Patient extends BaseACL(
- label = "patient",
- read = TreatmentMatchingRoles,
- update = TreatmentMatchingRoles
- )
-
- object PatientLabel extends BaseACL(
- label = "patient label",
- read = TreatmentMatchingRoles,
- update = TreatmentMatchingRoles
- )
-
- object PatientCriterion extends BaseACL(
- label = "patient criterion",
- read = TreatmentMatchingRoles,
- update = TreatmentMatchingRoles
- )
-
- object PatientLabelEvidence extends BaseACL(
- label = "patient label evidence",
- read = TreatmentMatchingRoles
- )
-
- object EligibleTrial extends BaseACL(
- label = "eligible trial",
- read = Set(RoutesCurator, TreatmentMatchingAdmin),
- update = Set(RoutesCurator, TreatmentMatchingAdmin)
- )
-
- object PatientHypothesis extends BaseACL(
- label = "patient hypothesis",
- read = Set(RoutesCurator, TreatmentMatchingAdmin),
- update = Set(RoutesCurator, TreatmentMatchingAdmin)
- )
-
- // Utility code
-
- abstract class BaseACL(label: String,
- create: AclCheck = Forbid,
- read: AclCheck = Forbid,
- update: AclCheck = Forbid,
- delete: AclCheck = Forbid) {
-
- def isCreateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = {
- check("create", create)(requestContext.executor.role)
- }
-
- def isReadAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = {
- check("read", read)(requestContext.executor.role)
- }
-
- def isUpdateAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = {
- check("update", update)(requestContext.executor.role)
- }
-
- def isDeleteAllow()(implicit requestContext: AuthenticatedRequestContext): Boolean = {
- check("delete", delete)(requestContext.executor.role)
- }
-
- private def check(action: String, isAllowed: AclCheck)(executorRole: Role): Boolean = {
- loggedError(
- isAllowed(executorRole),
- phi"$executorRole has no access to ${Unsafe(action)} a ${Unsafe(label)}"
- )
- }
-
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/auth/AnonymousRequestContext.scala b/src/main/scala/xyz/driver/common/auth/AnonymousRequestContext.scala
deleted file mode 100644
index 2e4b55c..0000000
--- a/src/main/scala/xyz/driver/common/auth/AnonymousRequestContext.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package xyz.driver.common.auth
-
-class AnonymousRequestContext(val requestId: RequestId) {
-
- override def equals(that: Any): Boolean = {
- that.getClass == classOf[AnonymousRequestContext] &&
- that.asInstanceOf[AnonymousRequestContext].requestId == requestId
- }
-
- override def hashCode(): Int = requestId.hashCode()
-
-}
diff --git a/src/main/scala/xyz/driver/common/auth/AuthenticatedRequestContext.scala b/src/main/scala/xyz/driver/common/auth/AuthenticatedRequestContext.scala
deleted file mode 100644
index b211e12..0000000
--- a/src/main/scala/xyz/driver/common/auth/AuthenticatedRequestContext.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-package xyz.driver.common.auth
-
-import xyz.driver.common.logging._
-import xyz.driver.common.domain.User
-
-class AuthenticatedRequestContext(val executor: User,
- override val requestId: RequestId) extends AnonymousRequestContext(requestId) {
-
- override def equals(that: Any): Boolean = {
- that.getClass == this.getClass && {
- val another = that.asInstanceOf[AuthenticatedRequestContext]
- another.executor == executor && another.requestId == requestId
- }
- }
-
- override def hashCode(): Int = {
- val initial = 37
- val first = initial * 17 + executor.hashCode()
- first * 17 + requestId.hashCode()
- }
-
-}
-
-object AuthenticatedRequestContext {
-
- def apply(executor: User) = new AuthenticatedRequestContext(executor, RequestId())
-
- implicit def toPhiString(x: AuthenticatedRequestContext): PhiString = {
- phi"AuthenticatedRequestContext(executor=${x.executor}, requestId=${x.requestId})"
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/auth/RequestId.scala b/src/main/scala/xyz/driver/common/auth/RequestId.scala
deleted file mode 100644
index 771145c..0000000
--- a/src/main/scala/xyz/driver/common/auth/RequestId.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package xyz.driver.common.auth
-
-import xyz.driver.common.logging._
-import xyz.driver.common.auth.RequestId._
-import xyz.driver.common.utils.RandomUtils
-
-final case class RequestId(value: String = RandomUtils.randomString(IdLength))
-
-object RequestId {
-
- private val IdLength = 20
-
- implicit def toPhiString(x: RequestId): PhiString = phi"RequestId(${Unsafe(x.value)})"
-
-}
diff --git a/src/main/scala/xyz/driver/common/compat/EitherOps.scala b/src/main/scala/xyz/driver/common/compat/EitherOps.scala
deleted file mode 100644
index b3b45e6..0000000
--- a/src/main/scala/xyz/driver/common/compat/EitherOps.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-package xyz.driver.common.compat
-
-final class EitherOps[A, B](val self: Either[A, B]) extends AnyVal {
-
- def map[B2](f: B => B2): Either[A, B2] = flatMap { x => Right(f(x)) }
-
- def flatMap[B2](f: B => Either[A, B2]): Either[A, B2] = self match {
- case Left(x) => Left(x)
- case Right(x) => f(x)
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/compat/Implicits.scala b/src/main/scala/xyz/driver/common/compat/Implicits.scala
deleted file mode 100644
index 860989b..0000000
--- a/src/main/scala/xyz/driver/common/compat/Implicits.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package xyz.driver.common.compat
-
-object Implicits {
-
- implicit def toEitherOps[A, B](self: Either[A, B]): EitherOps[A, B] = new EitherOps(self)
-
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueue.scala b/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueue.scala
deleted file mode 100644
index 6ecb299..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueue.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-package xyz.driver.common.concurrent
-
-import java.time.LocalDateTime
-
-import xyz.driver.common.concurrent.BridgeUploadQueue.Item
-import xyz.driver.common.domain.LongId
-import xyz.driver.common.logging._
-
-import scala.concurrent.Future
-
-object BridgeUploadQueue {
-
- /**
- * @param kind For example documents
- * @param tag For example, a patient's id: 1
- * @param attempts Which attempt
- * @param created When the task was created
- * @param nextAttempt Time of the next attempt
- */
- final case class Item(id: LongId[Item],
- kind: String,
- tag: String,
- created: LocalDateTime,
- attempts: Int,
- nextAttempt: LocalDateTime,
- completed: Boolean,
- dependencyKind: Option[String],
- dependencyTag: Option[String]) {
-
- def dependency: Option[Dependency] = {
- dependencyKind.zip(dependencyTag)
- .headOption
- .map(Function.tupled(Dependency.apply))
- }
-
- }
-
- object Item {
-
- implicit def toPhiString(x: Item): PhiString = {
- import x._
- phi"BridgeUploadQueue.Item(id=$id, kind=${Unsafe(kind)}, tag=${Unsafe(tag)}, " +
- phi"attempts=${Unsafe(attempts)}, start=$created, nextAttempt=$nextAttempt, completed=$completed, " +
- phi"dependency=$dependency)"
- }
-
- def apply(kind: String, tag: String, dependency: Option[Dependency] = None): Item = {
- val now = LocalDateTime.now()
-
- Item(
- id = LongId(0),
- kind = kind,
- tag = tag,
- created = now,
- attempts = 0,
- nextAttempt = now,
- completed = false,
- dependencyKind = dependency.map(_.kind),
- dependencyTag = dependency.map(_.tag)
- )
- }
-
- }
-
- final case class Dependency(kind: String, tag: String)
-
- object Dependency {
-
- implicit def toPhiString(x: Dependency): PhiString = {
- import x._
- phi"Dependency(kind=${Unsafe(kind)}, tag=${Unsafe(tag)})"
- }
-
- }
-
-}
-
-trait BridgeUploadQueue {
-
- def add(item: Item): Future[Unit]
-
- def get(kind: String): Future[Option[Item]]
-
- def remove(item: LongId[Item]): Future[Unit]
-
- def tryRetry(item: Item): Future[Option[Item]]
-
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueueRepositoryAdapter.scala b/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueueRepositoryAdapter.scala
deleted file mode 100644
index c6a2144..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/BridgeUploadQueueRepositoryAdapter.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-package xyz.driver.common.concurrent
-
-import java.time.LocalDateTime
-import java.time.temporal.ChronoUnit
-
-import xyz.driver.common.concurrent.BridgeUploadQueue.Item
-import xyz.driver.common.concurrent.BridgeUploadQueueRepositoryAdapter.Strategy
-import xyz.driver.common.db.Transactions
-import xyz.driver.common.db.repositories.BridgeUploadQueueRepository
-import xyz.driver.common.domain.LongId
-import xyz.driver.common.logging._
-
-import scala.concurrent.duration.{Duration, FiniteDuration}
-import scala.concurrent.{ExecutionContext, Future}
-
-object BridgeUploadQueueRepositoryAdapter {
-
- sealed trait Strategy {
-
- def onComplete: Strategy.OnComplete
-
- def on(attempt: Int): Strategy.OnAttempt
-
- }
-
- object Strategy {
-
- /**
- * Works forever, but has a limit for intervals.
- */
- final case class LimitExponential(startInterval: FiniteDuration,
- intervalFactor: Double,
- maxInterval: FiniteDuration,
- onComplete: OnComplete) extends Strategy {
-
- override def on(attempt: Int): OnAttempt = {
- OnAttempt.Continue(intervalFor(attempt).min(maxInterval))
- }
-
- private def intervalFor(attempt: Int): Duration = {
- startInterval * Math.pow(intervalFactor, attempt.toDouble)
- }
- }
-
- /**
- * Used only in tests.
- */
- case object Ignore extends Strategy {
-
- override val onComplete = OnComplete.Delete
-
- override def on(attempt: Int) = OnAttempt.Complete
-
- }
-
- /**
- * Used only in tests.
- */
- final case class Constant(interval: FiniteDuration) extends Strategy {
-
- override val onComplete = OnComplete.Delete
-
- override def on(attempt: Int) = OnAttempt.Continue(interval)
-
- }
-
- sealed trait OnComplete
- object OnComplete {
- case object Delete extends OnComplete
- case object Mark extends OnComplete
-
- implicit def toPhiString(x: OnAttempt): PhiString = Unsafe(x.toString)
- }
-
- sealed trait OnAttempt
- object OnAttempt {
- case object Complete extends OnAttempt
- case class Continue(interval: Duration) extends OnAttempt
-
- implicit def toPhiString(x: OnAttempt): PhiString = Unsafe(x.toString)
- }
- }
-}
-
-class BridgeUploadQueueRepositoryAdapter(strategy: Strategy,
- repository: BridgeUploadQueueRepository,
- transactions: Transactions)
- (implicit executionContext: ExecutionContext)
- extends BridgeUploadQueue with PhiLogging {
-
- override def add(item: Item): Future[Unit] = transactions.run { _ =>
- repository.add(item)
- }
-
- override def get(kind: String): Future[Option[Item]] = {
- repository.getOne(kind)
- }
-
- override def remove(item: LongId[Item]): Future[Unit] = transactions.run { _ =>
- import Strategy.OnComplete._
-
- strategy.onComplete match {
- case Delete => repository.delete(item)
- case Mark =>
- repository.getById(item) match {
- case Some(x) => repository.update(x.copy(completed = true))
- case None => throw new RuntimeException(s"Can not find the $item task")
- }
- }
- }
-
- override def tryRetry(item: Item): Future[Option[Item]] = transactions.run { _ =>
- import Strategy.OnAttempt._
-
- logger.trace(phi"tryRetry($item)")
-
- val newAttempts = item.attempts + 1
- val action = strategy.on(newAttempts)
- logger.debug(phi"Action for ${Unsafe(newAttempts)}: $action")
-
- action match {
- case Continue(newInterval) =>
- val draftItem = item.copy(
- attempts = newAttempts,
- nextAttempt = LocalDateTime.now().plus(newInterval.toMillis, ChronoUnit.MILLIS)
- )
-
- logger.debug(draftItem)
- Some(repository.update(draftItem))
-
- case Complete =>
- repository.delete(item.id)
- None
- }
- }
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/Cron.scala b/src/main/scala/xyz/driver/common/concurrent/Cron.scala
deleted file mode 100644
index 9dd3155..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/Cron.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-package xyz.driver.common.concurrent
-
-import java.io.Closeable
-import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.{Timer, TimerTask}
-
-import com.typesafe.scalalogging.StrictLogging
-import org.slf4j.MDC
-import xyz.driver.common.error.ExceptionFormatter
-import xyz.driver.common.utils.RandomUtils
-
-import scala.concurrent.duration.FiniteDuration
-import scala.concurrent.{ExecutionContext, Future}
-import scala.util.{Failure, Success, Try}
-
-class Cron(settings: Cron.Settings) extends Closeable with StrictLogging {
-
- import Cron._
-
- private val timer = new Timer("cronTimer", true)
-
- private val jobs = ConcurrentHashMap.newKeySet[String]()
-
- def register(name: String)(job: () => Future[Unit])(implicit ec: ExecutionContext): Unit = {
- logger.trace("register({})", name)
- val disableList = settings.disable.split(",").map(_.trim).toList
- if (disableList.contains(name)) logger.info("The task '{}' is disabled", name)
- else {
- settings.intervals.get(name) match {
- case None =>
- logger.error("Can not find an interval for task '{}', check the settings", name)
- throw new IllegalArgumentException(s"Can not find an interval for task '$name', check the settings")
-
- case Some(period) =>
- logger.info("register a new task '{}' with a period of {}ms", name, period.toMillis.asInstanceOf[AnyRef])
- timer.schedule(new SingletonTask(name, job), 0, period.toMillis)
- }
- }
-
- jobs.add(name)
- }
-
- /**
- * Checks unused jobs
- */
- def verify(): Unit = {
- import scala.collection.JavaConversions.asScalaSet
-
- val unusedJobs = settings.intervals.keySet -- jobs.toSet
- unusedJobs.foreach { job =>
- logger.warn(s"The job '$job' is listed, but not registered or ignored")
- }
- }
-
- override def close(): Unit = {
- timer.cancel()
- }
-
-}
-
-object Cron {
-
- case class Settings(disable: String, intervals: Map[String, FiniteDuration])
-
- private class SingletonTask(taskName: String,
- job: () => Future[Unit])
- (implicit ec: ExecutionContext)
- extends TimerTask with StrictLogging {
-
- private val isWorking = new AtomicBoolean(false)
-
- override def run(): Unit = {
- if (isWorking.compareAndSet(false, true)) {
- MDC.put("userId", "cron")
- MDC.put("requestId", RandomUtils.randomString(15))
-
- logger.info("Start '{}'", taskName)
- Try {
- job()
- .andThen {
- case Success(_) => logger.info("'{}' is completed", taskName)
- case Failure(e) => logger.error(s"Job '{}' is failed: ${ExceptionFormatter.format(e)}", taskName)
- }
- .onComplete(_ => isWorking.set(false))
- } match {
- case Success(_) =>
- case Failure(e) =>
- logger.error("Can't start '{}'", taskName, e)
- }
- } else {
- logger.debug("The previous job '{}' is in progress", taskName)
- }
- }
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/InMemoryBridgeUploadQueue.scala b/src/main/scala/xyz/driver/common/concurrent/InMemoryBridgeUploadQueue.scala
deleted file mode 100644
index b19be42..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/InMemoryBridgeUploadQueue.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-package xyz.driver.common.concurrent
-
-import java.util.concurrent.LinkedBlockingQueue
-
-import xyz.driver.common.concurrent.BridgeUploadQueue.Item
-import xyz.driver.common.domain.LongId
-import xyz.driver.common.logging.PhiLogging
-
-import scala.collection.JavaConverters._
-import scala.concurrent.Future
-
-/**
- * Use it only for tests
- */
-class InMemoryBridgeUploadQueue extends BridgeUploadQueue with PhiLogging {
-
- private val queue = new LinkedBlockingQueue[Item]()
-
- override def add(item: Item): Future[Unit] = {
- queue.add(item)
- done
- }
-
- override def tryRetry(item: Item): Future[Option[Item]] = Future.successful(Some(item))
-
- override def get(kind: String): Future[Option[Item]] = {
- val r = queue.iterator().asScala.find(_.kind == kind)
- Future.successful(r)
- }
-
- override def remove(item: LongId[Item]): Future[Unit] = {
- queue.remove(item)
- done
- }
-
- private val done = Future.successful(())
-
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/MdcExecutionContext.scala b/src/main/scala/xyz/driver/common/concurrent/MdcExecutionContext.scala
deleted file mode 100644
index cd2b394..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/MdcExecutionContext.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package xyz.driver.common.concurrent
-
-import org.slf4j.MDC
-
-import scala.concurrent.{ExecutionContext, ExecutionContextExecutor}
-
-object MdcExecutionContext {
- def from(orig: ExecutionContext): ExecutionContext = new MdcExecutionContext(orig)
-}
-
-class MdcExecutionContext(orig: ExecutionContext) extends ExecutionContextExecutor {
-
- def execute(runnable: Runnable): Unit = {
- val parentMdcContext = MDC.getCopyOfContextMap
-
- orig.execute(new Runnable {
- def run(): Unit = {
- val saveMdcContext = MDC.getCopyOfContextMap
- setContextMap(parentMdcContext)
-
- try {
- runnable.run()
- } finally {
- setContextMap(saveMdcContext)
- }
- }
- })
- }
-
- private[this] def setContextMap(context: java.util.Map[String, String]): Unit =
- Option(context).fold(MDC.clear())(MDC.setContextMap)
-
- def reportFailure(t: Throwable): Unit = orig.reportFailure(t)
-
-}
diff --git a/src/main/scala/xyz/driver/common/concurrent/MdcThreadFactory.scala b/src/main/scala/xyz/driver/common/concurrent/MdcThreadFactory.scala
deleted file mode 100644
index 9e59a64..0000000
--- a/src/main/scala/xyz/driver/common/concurrent/MdcThreadFactory.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-package xyz.driver.common.concurrent
-
-import java.util.concurrent.ThreadFactory
-
-import org.slf4j.MDC
-
-object MdcThreadFactory {
- def from(orig: ThreadFactory): ThreadFactory = new MdcThreadFactory(orig)
-}
-
-class MdcThreadFactory(orig: ThreadFactory) extends ThreadFactory {
-
- override def newThread(runnable: Runnable): Thread = {
- val parentMdcContext = MDC.getCopyOfContextMap
-
- orig.newThread(new Runnable {
- def run(): Unit = {
- val saveMdcContext = MDC.getCopyOfContextMap
- setContextMap(parentMdcContext)
-
- try {
- runnable.run()
- } finally {
- setContextMap(saveMdcContext)
- }
- }
- })
- }
-
- private[this] def setContextMap(context: java.util.Map[String, String]): Unit =
- Option(context).fold(MDC.clear())(MDC.setContextMap)
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/DbCommand.scala b/src/main/scala/xyz/driver/common/db/DbCommand.scala
deleted file mode 100644
index fec8b9f..0000000
--- a/src/main/scala/xyz/driver/common/db/DbCommand.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package xyz.driver.common.db
-
-import scala.concurrent.Future
-
-trait DbCommand {
- def runSync(): Unit
- def runAsync(transactions: Transactions): Future[Unit]
-}
-
-object DbCommand {
- val Empty: DbCommand = new DbCommand {
- override def runSync(): Unit = {}
- override def runAsync(transactions: Transactions): Future[Unit] = Future.successful(())
- }
-}
diff --git a/src/main/scala/xyz/driver/common/db/DbCommandFactory.scala b/src/main/scala/xyz/driver/common/db/DbCommandFactory.scala
deleted file mode 100644
index 84c1383..0000000
--- a/src/main/scala/xyz/driver/common/db/DbCommandFactory.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package xyz.driver.common.db
-
-import scala.concurrent.{ExecutionContext, Future}
-
-trait DbCommandFactory[T] {
- def createCommand(orig: T)(implicit ec: ExecutionContext): Future[DbCommand]
-}
-
-object DbCommandFactory {
- def empty[T]: DbCommandFactory[T] = new DbCommandFactory[T] {
- override def createCommand(orig: T)(implicit ec: ExecutionContext): Future[DbCommand] = Future.successful(DbCommand.Empty)
- }
-}
-
diff --git a/src/main/scala/xyz/driver/common/db/EntityExtractorDerivation.scala b/src/main/scala/xyz/driver/common/db/EntityExtractorDerivation.scala
deleted file mode 100644
index 0396ea5..0000000
--- a/src/main/scala/xyz/driver/common/db/EntityExtractorDerivation.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-package xyz.driver.common.db
-
-import java.sql.ResultSet
-
-import io.getquill.NamingStrategy
-import io.getquill.dsl.EncodingDsl
-
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox
-
-trait EntityExtractorDerivation[Naming <: NamingStrategy] {
- this: EncodingDsl =>
-
- /**
- * Simple Quill extractor derivation for [[T]]
- * Only case classes available. Type parameters is not supported
- *
- * @tparam T
- * @return
- */
- def entityExtractor[T]: (ResultSet => T) = macro EntityExtractorDerivation.impl[T]
-}
-
-object EntityExtractorDerivation {
- def impl[T: c.WeakTypeTag](c: blackbox.Context): c.Tree = {
- import c.universe._
- val namingStrategy = c.prefix.actualType
- .baseType(c.weakTypeOf[EntityExtractorDerivation[NamingStrategy]].typeSymbol)
- .typeArgs
- .head
- .typeSymbol
- .companion
- val functionBody = {
- val tpe = weakTypeOf[T]
- val resultOpt = tpe.decls.collectFirst {
- // Find first constructor of T
- case cons: MethodSymbol if cons.isConstructor =>
- // Create param list for constructor
- val params = cons.paramLists.flatten.map { param =>
- val t = param.typeSignature
- val paramName = param.name.toString
- val col = q"$namingStrategy.column($paramName)"
- // Resolve implicit decoders (from SqlContext) and apply ResultSet for each
- val d = q"implicitly[${c.prefix}.Decoder[$t]]"
- // Minus 1 cause Quill JDBC decoders make plus one.
- // ¯\_(ツ)_/¯
- val i = q"row.findColumn($col) - 1"
- val decoderName = TermName(paramName + "Decoder")
- val valueName = TermName(paramName + "Value")
- (
- q"val $decoderName = $d",
- q"val $valueName = $decoderName($i, row)",
- valueName
- )
- }
- // Call constructor with param list
- q"""
- ..${params.map(_._1)}
- ..${params.map(_._2)}
- new $tpe(..${params.map(_._3)})
- """
- }
- resultOpt match {
- case Some(result) => result
- case None => c.abort(c.enclosingPosition,
- s"Can not derive extractor for $tpe. Constructor not found.")
- }
- }
- q"(row: java.sql.ResultSet) => $functionBody"
- }
-}
diff --git a/src/main/scala/xyz/driver/common/db/EntityNotFoundException.scala b/src/main/scala/xyz/driver/common/db/EntityNotFoundException.scala
deleted file mode 100644
index d4c11ac..0000000
--- a/src/main/scala/xyz/driver/common/db/EntityNotFoundException.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package xyz.driver.common.db
-
-import xyz.driver.common.domain.Id
-
-class EntityNotFoundException private(id: String, tableName: String)
- extends RuntimeException(s"Entity with id $id is not found in $tableName table") {
-
- def this(id: Id[_], tableName: String) = this(id.toString, tableName)
- def this(id: Long, tableName: String) = this(id.toString, tableName)
-}
diff --git a/src/main/scala/xyz/driver/common/db/MysqlQueryBuilder.scala b/src/main/scala/xyz/driver/common/db/MysqlQueryBuilder.scala
deleted file mode 100644
index d6b53d9..0000000
--- a/src/main/scala/xyz/driver/common/db/MysqlQueryBuilder.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-package xyz.driver.common.db
-
-import java.sql.ResultSet
-
-import io.getquill.{MySQLDialect, MysqlEscape}
-
-import scala.collection.breakOut
-import scala.concurrent.{ExecutionContext, Future}
-
-object MysqlQueryBuilder {
- import xyz.driver.common.db.QueryBuilder._
-
- def apply[T](tableName: String,
- lastUpdateFieldName: Option[String],
- nullableFields: Set[String],
- links: Set[TableLink],
- runner: Runner[T],
- countRunner: CountRunner)
- (implicit ec: ExecutionContext): MysqlQueryBuilder[T] = {
- val parameters = MysqlQueryBuilderParameters(
- tableData = TableData(tableName, lastUpdateFieldName, nullableFields),
- links = links.map(x => x.foreignTableName -> x)(breakOut)
- )
- new MysqlQueryBuilder[T](parameters)(runner, countRunner, ec)
- }
-
- def apply[T](tableName: String,
- lastUpdateFieldName: Option[String],
- nullableFields: Set[String],
- links: Set[TableLink],
- extractor: (ResultSet) => T)
- (implicit sqlContext: SqlContext): MysqlQueryBuilder[T] = {
-
- val runner = (parameters: QueryBuilderParameters) => {
- Future {
- val (sql, binder) = parameters.toSql(namingStrategy = MysqlEscape)
- sqlContext.executeQuery[T](sql, binder, { resultSet =>
- extractor(resultSet)
- })
- }(sqlContext.executionContext)
- }
-
- val countRunner = (parameters: QueryBuilderParameters) => {
- Future {
- val (sql, binder) = parameters.toSql(countQuery = true, namingStrategy = MysqlEscape)
- sqlContext.executeQuery[CountResult](sql, binder, { resultSet =>
- val count = resultSet.getInt(1)
- val lastUpdate = if (parameters.tableData.lastUpdateFieldName.isDefined) {
- Option(sqlContext.localDateTimeDecoder.decoder(2, resultSet))
- } else None
-
- (count, lastUpdate)
- }).head
- }(sqlContext.executionContext)
- }
-
- apply[T](
- tableName = tableName,
- lastUpdateFieldName = lastUpdateFieldName,
- nullableFields = nullableFields,
- links = links,
- runner = runner,
- countRunner = countRunner
- )(sqlContext.executionContext)
- }
-}
-
-class MysqlQueryBuilder[T](parameters: MysqlQueryBuilderParameters)
- (implicit runner: QueryBuilder.Runner[T],
- countRunner: QueryBuilder.CountRunner,
- ec: ExecutionContext)
- extends QueryBuilder[T, MySQLDialect, MysqlEscape](parameters) {
-
- def withFilter(newFilter: SearchFilterExpr): QueryBuilder[T, MySQLDialect, MysqlEscape] = {
- new MysqlQueryBuilder[T](parameters.copy(filter = newFilter))
- }
-
- def withSorting(newSorting: Sorting): QueryBuilder[T, MySQLDialect, MysqlEscape] = {
- new MysqlQueryBuilder[T](parameters.copy(sorting = newSorting))
- }
-
- def withPagination(newPagination: Pagination): QueryBuilder[T, MySQLDialect, MysqlEscape] = {
- new MysqlQueryBuilder[T](parameters.copy(pagination = Some(newPagination)))
- }
-
- def resetPagination: QueryBuilder[T, MySQLDialect, MysqlEscape] = {
- new MysqlQueryBuilder[T](parameters.copy(pagination = None))
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/Pagination.scala b/src/main/scala/xyz/driver/common/db/Pagination.scala
deleted file mode 100644
index d4a96d3..0000000
--- a/src/main/scala/xyz/driver/common/db/Pagination.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package xyz.driver.common.db
-
-import xyz.driver.common.logging._
-
-/**
- * @param pageNumber Starts with 1
- */
-case class Pagination(pageSize: Int, pageNumber: Int)
-
-object Pagination {
-
- // @see https://driverinc.atlassian.net/wiki/display/RA/REST+API+Specification#RESTAPISpecification-CommonRequestQueryParametersForWebServices
- val Default = Pagination(pageSize = 100, pageNumber = 1)
-
- implicit def toPhiString(x: Pagination): PhiString = {
- import x._
- phi"Pagination(pageSize=${Unsafe(pageSize)}, pageNumber=${Unsafe(pageNumber)})"
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/QueryBuilder.scala b/src/main/scala/xyz/driver/common/db/QueryBuilder.scala
deleted file mode 100644
index f0beca6..0000000
--- a/src/main/scala/xyz/driver/common/db/QueryBuilder.scala
+++ /dev/null
@@ -1,344 +0,0 @@
-package xyz.driver.common.db
-
-import java.sql.PreparedStatement
-import java.time.LocalDateTime
-
-import io.getquill.NamingStrategy
-import io.getquill.context.sql.idiom.SqlIdiom
-import xyz.driver.common.db.Sorting.{Dimension, Sequential}
-import xyz.driver.common.db.SortingOrder.{Ascending, Descending}
-
-import scala.collection.mutable.ListBuffer
-import scala.concurrent.{ExecutionContext, Future}
-
-object QueryBuilder {
-
- type Runner[T] = (QueryBuilderParameters) => Future[Seq[T]]
-
- type CountResult = (Int, Option[LocalDateTime])
-
- type CountRunner = (QueryBuilderParameters) => Future[CountResult]
-
- /**
- * Binder for PreparedStatement
- */
- type Binder = PreparedStatement => PreparedStatement
-
- case class TableData(tableName: String,
- lastUpdateFieldName: Option[String] = None,
- nullableFields: Set[String] = Set.empty)
-
- val AllFields = Set("*")
-
-}
-
-case class TableLink(keyColumnName: String,
- foreignTableName: String,
- foreignKeyColumnName: String)
-
-object QueryBuilderParameters {
- val AllFields = Set("*")
-}
-
-sealed trait QueryBuilderParameters {
-
- def tableData: QueryBuilder.TableData
- def links: Map[String, TableLink]
- def filter: SearchFilterExpr
- def sorting: Sorting
- def pagination: Option[Pagination]
-
- def findLink(tableName: String): TableLink = links.get(tableName) match {
- case None => throw new IllegalArgumentException(s"Cannot find a link for `$tableName`")
- case Some(link) => link
- }
-
- def toSql(countQuery: Boolean = false, namingStrategy: NamingStrategy): (String, QueryBuilder.Binder) = {
- toSql(countQuery, QueryBuilderParameters.AllFields, namingStrategy)
- }
-
- def toSql(countQuery: Boolean,
- fields: Set[String],
- namingStrategy: NamingStrategy): (String, QueryBuilder.Binder) = {
- val escapedTableName = namingStrategy.table(tableData.tableName)
- val fieldsSql: String = if (countQuery) {
- "count(*)" + (tableData.lastUpdateFieldName match {
- case Some(lastUpdateField) => s", max($escapedTableName.${namingStrategy.column(lastUpdateField)})"
- case None => ""
- })
- } else {
- if (fields == QueryBuilderParameters.AllFields) {
- s"$escapedTableName.*"
- } else {
- fields
- .map { field =>
- s"$escapedTableName.${namingStrategy.column(field)}"
- }
- .mkString(", ")
- }
- }
- val (where, bindings) = filterToSql(escapedTableName, filter, namingStrategy)
- val orderBy = sortingToSql(escapedTableName, sorting, namingStrategy)
-
- val limitSql = limitToSql()
-
- val sql = new StringBuilder()
- sql.append("select ")
- sql.append(fieldsSql)
- sql.append("\nfrom ")
- sql.append(escapedTableName)
-
- val filtersTableLinks: Seq[TableLink] = {
- import SearchFilterExpr._
- def aux(expr: SearchFilterExpr): Seq[TableLink] = expr match {
- case Atom.TableName(tableName) => List(findLink(tableName))
- case Intersection(xs) => xs.flatMap(aux)
- case Union(xs) => xs.flatMap(aux)
- case _ => Nil
- }
- aux(filter)
- }
-
- val sortingTableLinks: Seq[TableLink] = Sorting.collect(sorting) {
- case Dimension(Some(foreignTableName), _, _) => findLink(foreignTableName)
- }
-
- // Combine links from sorting and filter without duplicates
- val foreignTableLinks = (filtersTableLinks ++ sortingTableLinks).distinct
-
- foreignTableLinks.foreach {
- case TableLink(keyColumnName, foreignTableName, foreignKeyColumnName) =>
- val escapedForeignTableName = namingStrategy.table(foreignTableName)
-
- sql.append("\ninner join ")
- sql.append(escapedForeignTableName)
- sql.append(" on ")
-
- sql.append(escapedTableName)
- sql.append('.')
- sql.append(namingStrategy.column(keyColumnName))
-
- sql.append(" = ")
-
- sql.append(escapedForeignTableName)
- sql.append('.')
- sql.append(namingStrategy.column(foreignKeyColumnName))
- }
-
- if (where.nonEmpty) {
- sql.append("\nwhere ")
- sql.append(where)
- }
-
- if (orderBy.nonEmpty && !countQuery) {
- sql.append("\norder by ")
- sql.append(orderBy)
- }
-
- if (limitSql.nonEmpty && !countQuery) {
- sql.append("\n")
- sql.append(limitSql)
- }
-
- (sql.toString, binder(bindings))
- }
-
- /**
- * Converts filter expression to SQL expression.
- *
- * @return Returns SQL string and list of values for binding in prepared statement.
- */
- protected def filterToSql(escapedTableName: String,
- filter: SearchFilterExpr,
- namingStrategy: NamingStrategy): (String, List[AnyRef]) = {
- import SearchFilterBinaryOperation._
- import SearchFilterExpr._
-
- def isNull(string: AnyRef) = Option(string).isEmpty || string.toString.toLowerCase == "null"
-
- def placeholder(field: String) = "?"
-
- def escapeDimension(dimension: SearchFilterExpr.Dimension) = {
- val tableName = dimension.tableName.fold(escapedTableName)(namingStrategy.table)
- s"$tableName.${namingStrategy.column(dimension.name)}"
- }
-
- def filterToSqlMultiple(operands: Seq[SearchFilterExpr]) = operands.collect {
- case x if !SearchFilterExpr.isEmpty(x) => filterToSql(escapedTableName, x, namingStrategy)
- }
-
- filter match {
- case x if isEmpty(x) =>
- ("", List.empty)
-
- case AllowAll =>
- ("1", List.empty)
-
- case DenyAll =>
- ("0", List.empty)
-
- case Atom.Binary(dimension, Eq, value) if isNull(value) =>
- (s"${escapeDimension(dimension)} is NULL", List.empty)
-
- case Atom.Binary(dimension, NotEq, value) if isNull(value) =>
- (s"${escapeDimension(dimension)} is not NULL", List.empty)
-
- case Atom.Binary(dimension, NotEq, value) if tableData.nullableFields.contains(dimension.name) =>
- // In MySQL NULL <> Any === NULL
- // So, to handle NotEq for nullable fields we need to use more complex SQL expression.
- // http://dev.mysql.com/doc/refman/5.7/en/working-with-null.html
- val escapedColumn = escapeDimension(dimension)
- val sql = s"($escapedColumn is null or $escapedColumn != ${placeholder(dimension.name)})"
- (sql, List(value))
-
- case Atom.Binary(dimension, op, value) =>
- val operator = op match {
- case Eq => "="
- case NotEq => "!="
- case Like => "like"
- case Gt => ">"
- case GtEq => ">="
- case Lt => "<"
- case LtEq => "<="
- }
- (s"${escapeDimension(dimension)} $operator ${placeholder(dimension.name)}", List(value))
-
- case Atom.NAry(dimension, op, values) =>
- val sqlOp = op match {
- case SearchFilterNAryOperation.In => "in"
- case SearchFilterNAryOperation.NotIn => "not in"
- }
-
- val bindings = ListBuffer[AnyRef]()
- val sqlPlaceholder = placeholder(dimension.name)
- val formattedValues = values.map { value =>
- bindings += value
- sqlPlaceholder
- }.mkString(", ")
- (s"${escapeDimension(dimension)} $sqlOp ($formattedValues)", bindings.toList)
-
- case Intersection(operands) =>
- val (sql, bindings) = filterToSqlMultiple(operands).unzip
- (sql.mkString("(", " and ", ")"), bindings.flatten.toList)
-
- case Union(operands) =>
- val (sql, bindings) = filterToSqlMultiple(operands).unzip
- (sql.mkString("(", " or ", ")"), bindings.flatten.toList)
- }
- }
-
- protected def limitToSql(): String
-
- /**
- * @param escapedMainTableName Should be escaped
- */
- protected def sortingToSql(escapedMainTableName: String,
- sorting: Sorting,
- namingStrategy: NamingStrategy): String = {
- sorting match {
- case Dimension(optSortingTableName, field, order) =>
- val sortingTableName = optSortingTableName.map(namingStrategy.table).getOrElse(escapedMainTableName)
- val fullName = s"$sortingTableName.${namingStrategy.column(field)}"
-
- s"$fullName ${orderToSql(order)}"
-
- case Sequential(xs) =>
- xs.map(sortingToSql(escapedMainTableName, _, namingStrategy)).mkString(", ")
- }
- }
-
- protected def orderToSql(x: SortingOrder): String = x match {
- case Ascending => "asc"
- case Descending => "desc"
- }
-
- protected def binder(bindings: List[AnyRef])
- (bind: PreparedStatement): PreparedStatement = {
- bindings.zipWithIndex.foreach { case (binding, index) =>
- bind.setObject(index + 1, binding)
- }
-
- bind
- }
-
-}
-
-case class PostgresQueryBuilderParameters(tableData: QueryBuilder.TableData,
- links: Map[String, TableLink] = Map.empty,
- filter: SearchFilterExpr = SearchFilterExpr.Empty,
- sorting: Sorting = Sorting.Empty,
- pagination: Option[Pagination] = None) extends QueryBuilderParameters {
-
- def limitToSql(): String = {
- pagination.map { pagination =>
- val startFrom = (pagination.pageNumber - 1) * pagination.pageSize
- s"limit ${pagination.pageSize} OFFSET $startFrom"
- } getOrElse ""
- }
-
-}
-
-/**
- * @param links Links to another tables grouped by foreignTableName
- */
-case class MysqlQueryBuilderParameters(tableData: QueryBuilder.TableData,
- links: Map[String, TableLink] = Map.empty,
- filter: SearchFilterExpr = SearchFilterExpr.Empty,
- sorting: Sorting = Sorting.Empty,
- pagination: Option[Pagination] = None) extends QueryBuilderParameters {
-
- def limitToSql(): String = pagination.map { pagination =>
- val startFrom = (pagination.pageNumber - 1) * pagination.pageSize
- s"limit $startFrom, ${pagination.pageSize}"
- }.getOrElse("")
-
-}
-
-abstract class QueryBuilder[T, D <: SqlIdiom, N <: NamingStrategy](val parameters: QueryBuilderParameters)
- (implicit runner: QueryBuilder.Runner[T],
- countRunner: QueryBuilder.CountRunner,
- ec: ExecutionContext) {
-
- def run: Future[Seq[T]] = runner(parameters)
-
- def runCount: Future[QueryBuilder.CountResult] = countRunner(parameters)
-
- /**
- * Runs the query and returns total found rows without considering of pagination.
- */
- def runWithCount: Future[(Seq[T], Int, Option[LocalDateTime])] = {
- val countFuture = runCount
- val selectAllFuture = run
- for {
- (total, lastUpdate) <- countFuture
- all <- selectAllFuture
- } yield (all, total, lastUpdate)
- }
-
- def withFilter(newFilter: SearchFilterExpr): QueryBuilder[T, D, N]
-
- def withFilter(filter: Option[SearchFilterExpr]): QueryBuilder[T, D, N] = {
- filter.fold(this)(withFilter)
- }
-
- def resetFilter: QueryBuilder[T, D, N] = withFilter(SearchFilterExpr.Empty)
-
-
- def withSorting(newSorting: Sorting): QueryBuilder[T, D, N]
-
- def withSorting(sorting: Option[Sorting]): QueryBuilder[T, D, N] = {
- sorting.fold(this)(withSorting)
- }
-
- def resetSorting: QueryBuilder[T, D, N] = withSorting(Sorting.Empty)
-
-
- def withPagination(newPagination: Pagination): QueryBuilder[T, D, N]
-
- def withPagination(pagination: Option[Pagination]): QueryBuilder[T, D, N] = {
- pagination.fold(this)(withPagination)
- }
-
- def resetPagination: QueryBuilder[T, D, N]
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/SearchFilterExpr.scala b/src/main/scala/xyz/driver/common/db/SearchFilterExpr.scala
deleted file mode 100644
index 06b21cd..0000000
--- a/src/main/scala/xyz/driver/common/db/SearchFilterExpr.scala
+++ /dev/null
@@ -1,210 +0,0 @@
-package xyz.driver.common.db
-
-import xyz.driver.common.logging._
-
-sealed trait SearchFilterExpr {
- def find(p: SearchFilterExpr => Boolean): Option[SearchFilterExpr]
- def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr
-}
-
-object SearchFilterExpr {
-
- val Empty = Intersection.Empty
- val Forbid = Atom.Binary(
- dimension = Dimension(None, "true"),
- op = SearchFilterBinaryOperation.Eq,
- value = "false"
- )
-
- case class Dimension(tableName: Option[String], name: String) {
- def isForeign: Boolean = tableName.isDefined
- }
-
- sealed trait Atom extends SearchFilterExpr {
- override def find(p: SearchFilterExpr => Boolean): Option[SearchFilterExpr] = {
- if (p(this)) Some(this)
- else None
- }
-
- override def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr = {
- if (f.isDefinedAt(this)) f(this)
- else this
- }
- }
-
- object Atom {
- case class Binary(dimension: Dimension, op: SearchFilterBinaryOperation, value: AnyRef) extends Atom
- object Binary {
- def apply(field: String, op: SearchFilterBinaryOperation, value: AnyRef): Binary =
- Binary(Dimension(None, field), op, value)
- }
-
- case class NAry(dimension: Dimension, op: SearchFilterNAryOperation, values: Seq[AnyRef]) extends Atom
- object NAry {
- def apply(field: String, op: SearchFilterNAryOperation, values: Seq[AnyRef]): NAry =
- NAry(Dimension(None, field), op, values)
- }
-
- /** dimension.tableName extractor */
- object TableName {
- def unapply(value: Atom): Option[String] = value match {
- case Binary(Dimension(tableNameOpt, _), _, _) => tableNameOpt
- case NAry(Dimension(tableNameOpt, _), _, _) => tableNameOpt
- }
- }
- }
-
- case class Intersection private(operands: Seq[SearchFilterExpr])
- extends SearchFilterExpr with SearchFilterExprSeqOps {
-
- override def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr = {
- if (f.isDefinedAt(this)) f(this)
- else {
- this.copy(operands.map(_.replace(f)))
- }
- }
-
- }
-
- object Intersection {
-
- val Empty = Intersection(Seq())
-
- def create(operands: SearchFilterExpr*): SearchFilterExpr = {
- val filtered = operands.filterNot(SearchFilterExpr.isEmpty)
- filtered.size match {
- case 0 => Empty
- case 1 => filtered.head
- case _ => Intersection(filtered)
- }
- }
- }
-
-
- case class Union private(operands: Seq[SearchFilterExpr]) extends SearchFilterExpr with SearchFilterExprSeqOps {
-
- override def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr = {
- if (f.isDefinedAt(this)) f(this)
- else {
- this.copy(operands.map(_.replace(f)))
- }
- }
-
- }
-
- object Union {
-
- val Empty = Union(Seq())
-
- def create(operands: SearchFilterExpr*): SearchFilterExpr = {
- val filtered = operands.filterNot(SearchFilterExpr.isEmpty)
- filtered.size match {
- case 0 => Empty
- case 1 => filtered.head
- case _ => Union(filtered)
- }
- }
-
- def create(dimension: Dimension, values: String*): SearchFilterExpr = values.size match {
- case 0 => SearchFilterExpr.Empty
- case 1 => SearchFilterExpr.Atom.Binary(dimension, SearchFilterBinaryOperation.Eq, values.head)
- case _ =>
- val filters = values.map { value =>
- SearchFilterExpr.Atom.Binary(dimension, SearchFilterBinaryOperation.Eq, value)
- }
-
- create(filters: _*)
- }
-
- def create(dimension: Dimension, values: Set[String]): SearchFilterExpr =
- create(dimension, values.toSeq: _*)
-
- // Backwards compatible API
-
- /** Create SearchFilterExpr with empty tableName */
- def create(field: String, values: String*): SearchFilterExpr =
- create(Dimension(None, field), values:_*)
-
- /** Create SearchFilterExpr with empty tableName */
- def create(field: String, values: Set[String]): SearchFilterExpr =
- create(Dimension(None, field), values)
- }
-
-
- case object AllowAll extends SearchFilterExpr {
- override def find(p: SearchFilterExpr => Boolean): Option[SearchFilterExpr] = {
- if (p(this)) Some(this)
- else None
- }
-
- override def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr = {
- if (f.isDefinedAt(this)) f(this)
- else this
- }
- }
-
- case object DenyAll extends SearchFilterExpr {
- override def find(p: SearchFilterExpr => Boolean): Option[SearchFilterExpr] = {
- if (p(this)) Some(this)
- else None
- }
-
- override def replace(f: PartialFunction[SearchFilterExpr, SearchFilterExpr]): SearchFilterExpr = {
- if (f.isDefinedAt(this)) f(this)
- else this
- }
- }
-
- def isEmpty(expr: SearchFilterExpr): Boolean = {
- expr == Intersection.Empty || expr == Union.Empty
- }
-
- sealed trait SearchFilterExprSeqOps {
- this: SearchFilterExpr =>
-
- val operands: Seq[SearchFilterExpr]
-
- override def find(p: SearchFilterExpr => Boolean): Option[SearchFilterExpr] = {
- if (p(this)) Some(this)
- else {
- // Search the first expr among operands, which satisfy p
- // Is's ok to use foldLeft. If there will be performance issues, replace it by recursive loop
- operands.foldLeft(Option.empty[SearchFilterExpr]) {
- case (None, expr) => expr.find(p)
- case (x, _) => x
- }
- }
- }
-
- }
-
- // There is no case, when this is unsafe. At this time.
- implicit def toPhiString(x: SearchFilterExpr): PhiString = {
- if (isEmpty(x)) Unsafe("SearchFilterExpr.Empty")
- else Unsafe(x.toString)
- }
-
-}
-
-sealed trait SearchFilterBinaryOperation
-
-object SearchFilterBinaryOperation {
-
- case object Eq extends SearchFilterBinaryOperation
- case object NotEq extends SearchFilterBinaryOperation
- case object Like extends SearchFilterBinaryOperation
- case object Gt extends SearchFilterBinaryOperation
- case object GtEq extends SearchFilterBinaryOperation
- case object Lt extends SearchFilterBinaryOperation
- case object LtEq extends SearchFilterBinaryOperation
-
-}
-
-sealed trait SearchFilterNAryOperation
-
-object SearchFilterNAryOperation {
-
- case object In extends SearchFilterNAryOperation
- case object NotIn extends SearchFilterNAryOperation
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/Sorting.scala b/src/main/scala/xyz/driver/common/db/Sorting.scala
deleted file mode 100644
index 70c25f2..0000000
--- a/src/main/scala/xyz/driver/common/db/Sorting.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-package xyz.driver.common.db
-
-import xyz.driver.common.logging._
-
-import scala.collection.generic.CanBuildFrom
-
-sealed trait SortingOrder
-object SortingOrder {
-
- case object Ascending extends SortingOrder
- case object Descending extends SortingOrder
-
-}
-
-sealed trait Sorting
-
-object Sorting {
-
- val Empty = Sequential(Seq.empty)
-
- /**
- * @param tableName None if the table is default (same)
- * @param name Dimension name
- * @param order Order
- */
- case class Dimension(tableName: Option[String], name: String, order: SortingOrder) extends Sorting {
- def isForeign: Boolean = tableName.isDefined
- }
-
- case class Sequential(sorting: Seq[Dimension]) extends Sorting {
- override def toString: String = if (isEmpty(this)) "Empty" else super.toString
- }
-
- def isEmpty(input: Sorting): Boolean = {
- input match {
- case Sequential(Seq()) => true
- case _ => false
- }
- }
-
- def filter(sorting: Sorting, p: Dimension => Boolean): Seq[Dimension] = sorting match {
- case x: Dimension if p(x) => Seq(x)
- case x: Dimension => Seq.empty
- case Sequential(xs) => xs.filter(p)
- }
-
- def collect[B, That](sorting: Sorting)
- (f: PartialFunction[Dimension, B])
- (implicit bf: CanBuildFrom[Seq[Dimension], B, That]): That = sorting match {
- case x: Dimension if f.isDefinedAt(x) =>
- val r = bf.apply()
- r += f(x)
- r.result()
-
- case x: Dimension => bf.apply().result()
- case Sequential(xs) => xs.collect(f)
- }
-
- // Contains dimensions and ordering only, thus it is safe.
- implicit def toPhiString(x: Sorting): PhiString = Unsafe(x.toString)
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/SqlContext.scala b/src/main/scala/xyz/driver/common/db/SqlContext.scala
deleted file mode 100644
index 4b9d676..0000000
--- a/src/main/scala/xyz/driver/common/db/SqlContext.scala
+++ /dev/null
@@ -1,184 +0,0 @@
-package xyz.driver.common.db
-
-import java.io.Closeable
-import java.net.URI
-import java.time._
-import java.util.UUID
-import java.util.concurrent.Executors
-import javax.sql.DataSource
-
-import xyz.driver.common.logging.{PhiLogging, Unsafe}
-import xyz.driver.common.concurrent.MdcExecutionContext
-import xyz.driver.common.db.SqlContext.Settings
-import xyz.driver.common.domain._
-import xyz.driver.common.error.IncorrectIdException
-import xyz.driver.common.utils.JsonSerializer
-import com.typesafe.config.Config
-import io.getquill._
-
-import scala.concurrent.ExecutionContext
-import scala.util.control.NonFatal
-import scala.util.{Failure, Success, Try}
-
-object SqlContext extends PhiLogging {
-
- case class DbCredentials(user: String,
- password: String,
- host: String,
- port: Int,
- dbName: String,
- dbCreateFlag: Boolean,
- dbContext: String,
- connectionParams: String,
- url: String)
-
- case class Settings(credentials: DbCredentials,
- connection: Config,
- connectionAttemptsOnStartup: Int,
- threadPoolSize: Int)
-
- def apply(settings: Settings): SqlContext = {
- // Prevent leaking credentials to a log
- Try(JdbcContextConfig(settings.connection).dataSource) match {
- case Success(dataSource) => new SqlContext(dataSource, settings)
- case Failure(NonFatal(e)) =>
- logger.error(phi"Can not load dataSource, error: ${Unsafe(e.getClass.getName)}")
- throw new IllegalArgumentException("Can not load dataSource from config. Check your database and config")
- }
- }
-
-}
-
-class SqlContext(dataSource: DataSource with Closeable, settings: Settings)
- extends MysqlJdbcContext[MysqlEscape](dataSource)
- with EntityExtractorDerivation[Literal] {
-
- private val tpe = Executors.newFixedThreadPool(settings.threadPoolSize)
-
- implicit val executionContext: ExecutionContext = {
- val orig = ExecutionContext.fromExecutor(tpe)
- MdcExecutionContext.from(orig)
- }
-
- override def close(): Unit = {
- super.close()
- tpe.shutdownNow()
- }
-
- // ///////// Encodes/Decoders ///////////
-
- /**
- * Overrode, because Quill JDBC optionDecoder pass null inside decoders.
- * If custom decoder don't have special null handler, it will failed.
- *
- * @see https://github.com/getquill/quill/issues/535
- */
- implicit override def optionDecoder[T](implicit d: Decoder[T]): Decoder[Option[T]] =
- decoder(
- sqlType = d.sqlType,
- row => index => {
- try {
- val res = d(index - 1, row)
- if (row.wasNull) {
- None
- }
- else {
- Some(res)
- }
- } catch {
- case _: NullPointerException => None
- case _: IncorrectIdException => None
- }
- }
- )
-
- implicit def encodeStringId[T] = MappedEncoding[StringId[T], String](_.id)
- implicit def decodeStringId[T] = MappedEncoding[String, StringId[T]] {
- case "" => throw IncorrectIdException("'' is an invalid Id value")
- case x => StringId(x)
- }
-
- def decodeOptStringId[T] = MappedEncoding[Option[String], Option[StringId[T]]] {
- case None | Some("") => None
- case Some(x) => Some(StringId(x))
- }
-
- implicit def encodeLongId[T] = MappedEncoding[LongId[T], Long](_.id)
- implicit def decodeLongId[T] = MappedEncoding[Long, LongId[T]] {
- case 0 => throw IncorrectIdException("0 is an invalid Id value")
- case x => LongId(x)
- }
-
- // TODO Dirty hack, see REP-475
- def decodeOptLongId[T] = MappedEncoding[Option[Long], Option[LongId[T]]] {
- case None | Some(0) => None
- case Some(x) => Some(LongId(x))
- }
-
- implicit def encodeUuidId[T] = MappedEncoding[UuidId[T], String](_.toString)
- implicit def decodeUuidId[T] = MappedEncoding[String, UuidId[T]] {
- case "" => throw IncorrectIdException("'' is an invalid Id value")
- case x => UuidId(x)
- }
-
- def decodeOptUuidId[T] = MappedEncoding[Option[String], Option[UuidId[T]]] {
- case None | Some("") => None
- case Some(x) => Some(UuidId(x))
- }
-
- implicit def encodeTextJson[T: Manifest] = MappedEncoding[TextJson[T], String](x => JsonSerializer.serialize(x.content))
- implicit def decodeTextJson[T: Manifest] = MappedEncoding[String, TextJson[T]] { x =>
- TextJson(JsonSerializer.deserialize[T](x))
- }
-
- implicit val encodeUserRole = MappedEncoding[User.Role, Int](_.bit)
- implicit val decodeUserRole = MappedEncoding[Int, User.Role] {
- // 0 is treated as null for numeric types
- case 0 => throw new NullPointerException("0 means no roles. A user must have a role")
- case x => User.Role(x)
- }
-
- implicit val encodeEmail = MappedEncoding[Email, String](_.value.toString)
- implicit val decodeEmail = MappedEncoding[String, Email](Email)
-
- implicit val encodePasswordHash = MappedEncoding[PasswordHash, Array[Byte]](_.value)
- implicit val decodePasswordHash = MappedEncoding[Array[Byte], PasswordHash](PasswordHash(_))
-
- implicit val encodeUri = MappedEncoding[URI, String](_.toString)
- implicit val decodeUri = MappedEncoding[String, URI](URI.create)
-
- implicit val encodeCaseId = MappedEncoding[CaseId, String](_.id.toString)
- implicit val decodeCaseId = MappedEncoding[String, CaseId](CaseId(_))
-
- implicit val encodeFuzzyValue = {
- MappedEncoding[FuzzyValue, String] {
- case FuzzyValue.No => "No"
- case FuzzyValue.Yes => "Yes"
- case FuzzyValue.Maybe => "Maybe"
- }
- }
- implicit val decodeFuzzyValue = MappedEncoding[String, FuzzyValue] {
- case "Yes" => FuzzyValue.Yes
- case "No" => FuzzyValue.No
- case "Maybe" => FuzzyValue.Maybe
- case x =>
- Option(x).fold {
- throw new NullPointerException("FuzzyValue is null") // See catch in optionDecoder
- } { _ =>
- throw new IllegalStateException(s"Unknown fuzzy value: $x")
- }
- }
-
-
- implicit val encodeRecordRequestId = MappedEncoding[RecordRequestId, String](_.id.toString)
- implicit val decodeRecordRequestId = MappedEncoding[String, RecordRequestId] { x =>
- RecordRequestId(UUID.fromString(x))
- }
-
- final implicit class LocalDateTimeDbOps(val left: LocalDateTime) {
-
- // scalastyle:off
- def <=(right: LocalDateTime): Quoted[Boolean] = quote(infix"$left <= $right".as[Boolean])
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/db/Transactions.scala b/src/main/scala/xyz/driver/common/db/Transactions.scala
deleted file mode 100644
index 2f5a2cc..0000000
--- a/src/main/scala/xyz/driver/common/db/Transactions.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package xyz.driver.common.db
-
-import xyz.driver.common.logging.PhiLogging
-
-import scala.concurrent.Future
-import scala.util.{Failure, Success, Try}
-
-class Transactions()(implicit context: SqlContext) extends PhiLogging {
- def run[T](f: SqlContext => T): Future[T] = {
- import context.executionContext
-
- Future(context.transaction(f(context))).andThen {
- case Failure(e) => logger.error(phi"Can't run a transaction: $e")
- }
- }
-
- def runSync[T](f: SqlContext => T): Unit = {
- Try(context.transaction(f(context))) match {
- case Success(_) =>
- case Failure(e) => logger.error(phi"Can't run a transaction: $e")
- }
- }
-}
diff --git a/src/main/scala/xyz/driver/common/db/repositories/BridgeUploadQueueRepository.scala b/src/main/scala/xyz/driver/common/db/repositories/BridgeUploadQueueRepository.scala
deleted file mode 100644
index e0d6ff2..0000000
--- a/src/main/scala/xyz/driver/common/db/repositories/BridgeUploadQueueRepository.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-package xyz.driver.common.db.repositories
-
-import xyz.driver.common.concurrent.BridgeUploadQueue
-import xyz.driver.common.domain.LongId
-
-import scala.concurrent.Future
-
-trait BridgeUploadQueueRepository extends Repository {
-
- type EntityT = BridgeUploadQueue.Item
- type IdT = LongId[EntityT]
-
- def add(draft: EntityT): EntityT
-
- def getById(id: LongId[EntityT]): Option[EntityT]
-
- def isCompleted(kind: String, tag: String): Future[Boolean]
-
- def getOne(kind: String): Future[Option[BridgeUploadQueue.Item]]
-
- def update(entity: EntityT): EntityT
-
- def delete(id: IdT): Unit
-}
diff --git a/src/main/scala/xyz/driver/common/db/repositories/Repository.scala b/src/main/scala/xyz/driver/common/db/repositories/Repository.scala
deleted file mode 100644
index ae2a3e6..0000000
--- a/src/main/scala/xyz/driver/common/db/repositories/Repository.scala
+++ /dev/null
@@ -1,4 +0,0 @@
-package xyz.driver.common.db.repositories
-
-// For further usage and migration to Postgres and slick
-trait Repository extends RepositoryLogging
diff --git a/src/main/scala/xyz/driver/common/db/repositories/RepositoryLogging.scala b/src/main/scala/xyz/driver/common/db/repositories/RepositoryLogging.scala
deleted file mode 100644
index cb2c438..0000000
--- a/src/main/scala/xyz/driver/common/db/repositories/RepositoryLogging.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-package xyz.driver.common.db.repositories
-
-import xyz.driver.common.logging._
-
-trait RepositoryLogging extends PhiLogging {
-
- protected def logCreatedOne[T](x: T)(implicit toPhiString: T => PhiString): T = {
- logger.info(phi"An entity was created: $x")
- x
- }
-
- protected def logCreatedMultiple[T <: Iterable[_]](xs: T)(implicit toPhiString: T => PhiString): T = {
- if (xs.nonEmpty) {
- logger.info(phi"Entities were created: $xs")
- }
- xs
- }
-
- protected def logUpdatedOne(rowsAffected: Long): Long = {
- rowsAffected match {
- case 0 => logger.trace(phi"The entity is up to date")
- case 1 => logger.info(phi"The entity was updated")
- case x => logger.warn(phi"The ${Unsafe(x)} entities were updated")
- }
- rowsAffected
- }
-
- protected def logUpdatedOneUnimportant(rowsAffected: Long): Long = {
- rowsAffected match {
- case 0 => logger.trace(phi"The entity is up to date")
- case 1 => logger.trace(phi"The entity was updated")
- case x => logger.warn(phi"The ${Unsafe(x)} entities were updated")
- }
- rowsAffected
- }
-
- protected def logUpdatedMultiple(rowsAffected: Long): Long = {
- rowsAffected match {
- case 0 => logger.trace(phi"All entities are up to date")
- case x => logger.info(phi"The ${Unsafe(x)} entities were updated")
- }
- rowsAffected
- }
-
- protected def logDeletedOne(rowsAffected: Long): Long = {
- rowsAffected match {
- case 0 => logger.trace(phi"The entity does not exist")
- case 1 => logger.info(phi"The entity was deleted")
- case x => logger.warn(phi"Deleted ${Unsafe(x)} entities, expected one")
- }
- rowsAffected
- }
-
- protected def logDeletedMultiple(rowsAffected: Long): Long = {
- rowsAffected match {
- case 0 => logger.trace(phi"Entities do not exist")
- case x => logger.info(phi"Deleted ${Unsafe(x)} entities")
- }
- rowsAffected
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/domain/CaseId.scala b/src/main/scala/xyz/driver/common/domain/CaseId.scala
deleted file mode 100644
index bb11f90..0000000
--- a/src/main/scala/xyz/driver/common/domain/CaseId.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package xyz.driver.common.domain
-
-import java.util.UUID
-
-case class CaseId(id: String)
-
-object CaseId {
-
- def apply() = new CaseId(UUID.randomUUID().toString)
-}
diff --git a/src/main/scala/xyz/driver/common/domain/Category.scala b/src/main/scala/xyz/driver/common/domain/Category.scala
deleted file mode 100644
index e130367..0000000
--- a/src/main/scala/xyz/driver/common/domain/Category.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package xyz.driver.common.domain
-
-import xyz.driver.common.logging._
-
-case class Category(id: LongId[Category], name: String)
-
-object Category {
- implicit def toPhiString(x: Category): PhiString = {
- import x._
- phi"Category(id=$id, name=${Unsafe(name)})"
- }
-}
-
-case class CategoryWithLabels(category: Category, labels: List[Label])
-
-object CategoryWithLabels {
- implicit def toPhiString(x: CategoryWithLabels): PhiString = {
- import x._
- phi"CategoryWithLabels(category=$category, labels=$labels)"
- }
-}
diff --git a/src/main/scala/xyz/driver/common/domain/Email.scala b/src/main/scala/xyz/driver/common/domain/Email.scala
deleted file mode 100644
index c3bcf3f..0000000
--- a/src/main/scala/xyz/driver/common/domain/Email.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package xyz.driver.common.domain
-
-case class Email(value: String)
diff --git a/src/main/scala/xyz/driver/common/domain/FuzzyValue.scala b/src/main/scala/xyz/driver/common/domain/FuzzyValue.scala
deleted file mode 100644
index 584f8f7..0000000
--- a/src/main/scala/xyz/driver/common/domain/FuzzyValue.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package xyz.driver.common.domain
-
-import xyz.driver.common.logging._
-import xyz.driver.common.utils.Utils
-
-sealed trait FuzzyValue
-object FuzzyValue {
- case object Yes extends FuzzyValue
- case object No extends FuzzyValue
- case object Maybe extends FuzzyValue
-
- val All: Set[FuzzyValue] = Set(Yes, No, Maybe)
-
- def fromBoolean(x: Boolean): FuzzyValue = if (x) Yes else No
-
- implicit def toPhiString(x: FuzzyValue): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
-}
diff --git a/src/main/scala/xyz/driver/common/domain/Id.scala b/src/main/scala/xyz/driver/common/domain/Id.scala
deleted file mode 100644
index 9f9604e..0000000
--- a/src/main/scala/xyz/driver/common/domain/Id.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-package xyz.driver.common.domain
-
-import java.util.UUID
-
-import xyz.driver.common.logging._
-
-sealed trait Id[+T]
-
-case class CompoundId[Id1 <: Id[_], Id2 <: Id[_]](part1: Id1, part2: Id2) extends Id[(Id1, Id2)]
-
-case class LongId[+T](id: Long) extends Id[T] {
- override def toString: String = id.toString
-
- def is(longId: Long): Boolean = {
- id == longId
- }
-}
-
-object LongId {
- implicit def toPhiString[T](x: LongId[T]): PhiString = Unsafe(s"LongId(${x.id})")
-}
-
-case class StringId[+T](id: String) extends Id[T] {
- override def toString: String = id
-
- def is(stringId: String): Boolean = {
- id == stringId
- }
-}
-
-object StringId {
- implicit def toPhiString[T](x: StringId[T]): PhiString = Unsafe(s"StringId(${x.id})")
-}
-
-case class UuidId[+T](id: UUID) extends Id[T] {
- override def toString: String = id.toString
-}
-
-object UuidId {
-
- /**
- * @note May fail, if `string` is invalid UUID.
- */
- def apply[T](string: String): UuidId[T] = new UuidId[T](UUID.fromString(string))
-
- def apply[T](): UuidId[T] = new UuidId[T](UUID.randomUUID())
-
- implicit def ordering[T] = Ordering.by[UuidId[T], String](_.toString)
-
- implicit def toPhiString[T](x: UuidId[T]): PhiString = Unsafe(s"UuidId(${x.id})")
-}
diff --git a/src/main/scala/xyz/driver/common/domain/Label.scala b/src/main/scala/xyz/driver/common/domain/Label.scala
deleted file mode 100644
index 2214216..0000000
--- a/src/main/scala/xyz/driver/common/domain/Label.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package xyz.driver.common.domain
-
-import xyz.driver.common.logging._
-
-case class Label(id: LongId[Label],
- categoryId: LongId[Category],
- name: String,
- description: String)
-
-object Label {
- implicit def toPhiString(x: Label): PhiString = {
- import x._
- phi"Label($id, categoryId=${Unsafe(categoryId)}, name=${Unsafe(name)}, description=${Unsafe(description)})"
- }
-}
diff --git a/src/main/scala/xyz/driver/common/domain/PasswordHash.scala b/src/main/scala/xyz/driver/common/domain/PasswordHash.scala
deleted file mode 100644
index 7b25799..0000000
--- a/src/main/scala/xyz/driver/common/domain/PasswordHash.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-package xyz.driver.common.domain
-
-import java.nio.charset.Charset
-
-import org.mindrot.jbcrypt.BCrypt
-
-case class PasswordHash(value: Array[Byte]) {
-
- lazy val hashString: String = new String(value, Charset.forName("UTF-8"))
-
- override def toString: String = {
- s"${this.getClass.getSimpleName}($hashString)"
- }
-
- override def equals(that: Any): Boolean = {
- that match {
- case thatHash: PasswordHash => java.util.Arrays.equals(this.value, thatHash.value)
- case _ => false
- }
- }
-
- override def hashCode(): Int = {
- 42 + java.util.Arrays.hashCode(this.value)
- }
-
- def is(password: String): Boolean = {
- BCrypt.checkpw(password, hashString)
- }
-
-}
-
-object PasswordHash {
-
- def apply(password: String): PasswordHash = {
- new PasswordHash(getHash(password))
- }
-
- private def getHash(str: String): Array[Byte] = {
- BCrypt.hashpw(str, BCrypt.gensalt()).getBytes(Charset.forName("UTF-8"))
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/domain/RecordRequestId.scala b/src/main/scala/xyz/driver/common/domain/RecordRequestId.scala
deleted file mode 100644
index 901ff66..0000000
--- a/src/main/scala/xyz/driver/common/domain/RecordRequestId.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-package xyz.driver.common.domain
-
-import java.util.UUID
-
-import xyz.driver.common.logging._
-
-case class RecordRequestId(id: UUID) {
- override def toString: String = id.toString
-}
-
-object RecordRequestId {
-
- def apply() = new RecordRequestId(UUID.randomUUID())
-
- implicit def toPhiString(x: RecordRequestId): PhiString = phi"${x.id}"
-}
diff --git a/src/main/scala/xyz/driver/common/domain/TextJson.scala b/src/main/scala/xyz/driver/common/domain/TextJson.scala
deleted file mode 100644
index af18723..0000000
--- a/src/main/scala/xyz/driver/common/domain/TextJson.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package xyz.driver.common.domain
-
-import xyz.driver.common.logging._
-
-case class TextJson[+T](content: T) {
- def map[U](f: T => U): TextJson[U] = copy(f(content))
-}
-
-object TextJson {
-
- implicit def toPhiString[T](x: TextJson[T])(implicit inner: T => PhiString): PhiString = {
- phi"TextJson(${x.content})"
- }
-}
diff --git a/src/main/scala/xyz/driver/common/domain/User.scala b/src/main/scala/xyz/driver/common/domain/User.scala
deleted file mode 100644
index 83d861f..0000000
--- a/src/main/scala/xyz/driver/common/domain/User.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-package xyz.driver.common.domain
-
-import java.time.LocalDateTime
-
-import xyz.driver.common.logging._
-import xyz.driver.common.domain.User.Role
-import xyz.driver.common.utils.Utils
-
-case class User(id: LongId[User],
- email: Email,
- name: String,
- role: Role,
- passwordHash: PasswordHash,
- latestActivity: Option[LocalDateTime],
- deleted: Option[LocalDateTime])
-
-object User {
-
- sealed trait Role extends Product with Serializable {
-
- /**
- * Bit representation of this role
- */
- def bit: Int
-
- def is(that: Role): Boolean = this == that
-
- def oneOf(roles: Role*): Boolean = roles.contains(this)
-
- def oneOf(roles: Set[Role]): Boolean = roles.contains(this)
- }
-
- object Role extends PhiLogging {
- case object RecordAdmin extends Role {val bit = 1 << 0}
- case object RecordCleaner extends Role {val bit = 1 << 1}
- case object RecordOrganizer extends Role {val bit = 1 << 2}
- case object DocumentExtractor extends Role {val bit = 1 << 3}
- case object TrialSummarizer extends Role {val bit = 1 << 4}
- case object CriteriaCurator extends Role {val bit = 1 << 5}
- case object TrialAdmin extends Role {val bit = 1 << 6}
- case object EligibilityVerifier extends Role{val bit = 1 << 7}
- case object TreatmentMatchingAdmin extends Role{val bit = 1 << 8}
- case object RoutesCurator extends Role{val bit = 1 << 9}
-
- val RepRoles = Set[Role](RecordAdmin, RecordCleaner, RecordOrganizer, DocumentExtractor)
-
- val TcRoles = Set[Role](TrialSummarizer, CriteriaCurator, TrialAdmin)
-
- val TreatmentMatchingRoles = Set[Role](RoutesCurator, EligibilityVerifier, TreatmentMatchingAdmin)
-
- val All = RepRoles ++ TcRoles ++ TreatmentMatchingRoles
-
- def apply(bitMask: Int): Role = {
- def extractRole(role: Role): Set[Role] =
- if ((bitMask & role.bit) != 0) Set(role) else Set.empty[Role]
-
- val roles = All.flatMap(extractRole)
- roles.size match {
- case 1 => roles.head
- case _ =>
- logger.error(phi"Can't convert a bit mask ${Unsafe(bitMask)} to any role")
- throw new IllegalArgumentException()
- }
- }
-
- implicit def toPhiString(x: Role): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
- }
-
- implicit def toPhiString(x: User): PhiString = {
- import x._
- phi"User(id=$id, role=$role)"
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/error/DomainError.scala b/src/main/scala/xyz/driver/common/error/DomainError.scala
deleted file mode 100644
index d277543..0000000
--- a/src/main/scala/xyz/driver/common/error/DomainError.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-package xyz.driver.common.error
-
-import xyz.driver.common.logging.{PhiString, Unsafe}
-import xyz.driver.common.utils.Utils
-
-trait DomainError {
-
- protected def userMessage: String
-
- def getMessage: String = userMessage
-
-}
-
-object DomainError {
-
- // 404 error
- trait NotFoundError extends DomainError
-
- // 401 error
- trait AuthenticationError extends DomainError
-
- // 403 error
- trait AuthorizationError extends DomainError
-
- implicit def toPhiString(x: DomainError): PhiString = {
- // userMessage possibly can contain a personal information,
- // so we should prevent it to be printed in logs.
- Unsafe(Utils.getClassSimpleName(x.getClass))
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/error/ExceptionFormatter.scala b/src/main/scala/xyz/driver/common/error/ExceptionFormatter.scala
deleted file mode 100644
index 33dd94c..0000000
--- a/src/main/scala/xyz/driver/common/error/ExceptionFormatter.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package xyz.driver.common.error
-
-import java.io.{ByteArrayOutputStream, PrintStream}
-
-object ExceptionFormatter {
-
- def format(e: Throwable): String = s"$e\n${printStackTrace(e)}"
-
- def printStackTrace(e: Throwable): String = {
- val baos = new ByteArrayOutputStream()
- val ps = new PrintStream(baos)
-
- e.printStackTrace(ps)
-
- ps.close()
- baos.toString()
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/error/FailedValidationException.scala b/src/main/scala/xyz/driver/common/error/FailedValidationException.scala
deleted file mode 100644
index 018ce58..0000000
--- a/src/main/scala/xyz/driver/common/error/FailedValidationException.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-package xyz.driver.common.error
-
-import xyz.driver.common.validation.ValidationError
-
-class FailedValidationException(val error: ValidationError) extends RuntimeException("The validation is failed")
diff --git a/src/main/scala/xyz/driver/common/error/IncorrectIdException.scala b/src/main/scala/xyz/driver/common/error/IncorrectIdException.scala
deleted file mode 100644
index a91065c..0000000
--- a/src/main/scala/xyz/driver/common/error/IncorrectIdException.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package xyz.driver.common.error
-
-case class IncorrectIdException(message: String) extends Exception(message)
diff --git a/src/main/scala/xyz/driver/common/http/AsyncHttpClientFetcher.scala b/src/main/scala/xyz/driver/common/http/AsyncHttpClientFetcher.scala
deleted file mode 100644
index 5d54f0d..0000000
--- a/src/main/scala/xyz/driver/common/http/AsyncHttpClientFetcher.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-package xyz.driver.common.http
-
-import java.io.Closeable
-import java.net.URL
-import java.util.concurrent.{ExecutorService, Executors}
-
-import com.typesafe.scalalogging.StrictLogging
-import org.asynchttpclient._
-import org.slf4j.MDC
-import xyz.driver.common.concurrent.MdcThreadFactory
-import xyz.driver.common.utils.RandomUtils
-
-import scala.concurrent.duration.FiniteDuration
-import scala.concurrent.{ExecutionContext, Future, Promise}
-
-class AsyncHttpClientFetcher(settings: AsyncHttpClientFetcher.Settings)
- extends HttpFetcher with Closeable with StrictLogging {
-
- private val es: ExecutorService = {
- val threadFactory = MdcThreadFactory.from(Executors.defaultThreadFactory())
- Executors.newSingleThreadExecutor(threadFactory)
- }
-
- private implicit val executionContext = ExecutionContext.fromExecutor(es)
-
- private def httpClientConfig: DefaultAsyncHttpClientConfig = {
- val builder = new DefaultAsyncHttpClientConfig.Builder()
- builder.setConnectTimeout(settings.connectTimeout.toMillis.toInt)
- builder.setReadTimeout(settings.readTimeout.toMillis.toInt)
- // builder.setThreadFactory(threadFactory) // Doesn't help to push MDC context into AsyncCompletionHandler
- builder.build()
- }
-
- private val httpClient = new DefaultAsyncHttpClient(httpClientConfig)
-
- override def apply(url: URL): Future[Array[Byte]] = {
- val fingerPrint = RandomUtils.randomString(10)
-
- // log all outcome connections
- logger.info("{}, apply({})", fingerPrint, url)
- val promise = Promise[Response]()
-
- httpClient.prepareGet(url.toString).execute(new AsyncCompletionHandler[Response] {
- override def onCompleted(response: Response): Response = {
- promise.success(response)
- response
- }
-
- override def onThrowable(t: Throwable): Unit = {
- promise.failure(t)
- super.onThrowable(t)
- }
- })
-
- // Promises have their own ExecutionContext
- // So, we have to hack it.
- val parentMdcContext = MDC.getCopyOfContextMap
- promise.future.flatMap { response =>
- setContextMap(parentMdcContext)
-
- if (response.getStatusCode == 200) {
- // DO NOT LOG body, it could be PHI
- // logger.trace(response.getResponseBody())
- val bytes = response.getResponseBodyAsBytes
- logger.debug("{}, size is {}B", fingerPrint, bytes.size.asInstanceOf[AnyRef])
- Future.successful(bytes)
- } else {
- logger.error("{}, HTTP {}", fingerPrint, response.getStatusCode.asInstanceOf[AnyRef])
- logger.trace(response.getResponseBody().take(100))
- Future.failed(new IllegalStateException("An unexpected response from the server"))
- }
- }
- }
-
- private[this] def setContextMap(context: java.util.Map[String, String]): Unit =
- Option(context).fold(MDC.clear())(MDC.setContextMap)
-
- override def close(): Unit = {
- httpClient.close()
- es.shutdown()
- }
-
-}
-
-object AsyncHttpClientFetcher {
-
- case class Settings(connectTimeout: FiniteDuration,
- readTimeout: FiniteDuration)
-
-}
diff --git a/src/main/scala/xyz/driver/common/http/AsyncHttpClientUploader.scala b/src/main/scala/xyz/driver/common/http/AsyncHttpClientUploader.scala
deleted file mode 100644
index 97c96cd..0000000
--- a/src/main/scala/xyz/driver/common/http/AsyncHttpClientUploader.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-package xyz.driver.common.http
-
-import java.io.Closeable
-import java.net.URI
-import java.util.concurrent.{ExecutorService, Executors}
-
-import xyz.driver.common.concurrent.MdcThreadFactory
-import xyz.driver.common.http.AsyncHttpClientUploader._
-import xyz.driver.common.utils.RandomUtils
-import com.typesafe.scalalogging.StrictLogging
-import org.asynchttpclient._
-import org.slf4j.MDC
-
-import scala.concurrent.duration.FiniteDuration
-import scala.concurrent.{ExecutionContext, Future, Promise}
-
-class AsyncHttpClientUploader(settings: Settings) extends Closeable with StrictLogging {
-
- private val es: ExecutorService = {
- val threadFactory = MdcThreadFactory.from(Executors.defaultThreadFactory())
- Executors.newSingleThreadExecutor(threadFactory)
- }
-
- private implicit val executionContext = ExecutionContext.fromExecutor(es)
-
- private def httpClientConfig: DefaultAsyncHttpClientConfig = {
- val builder = new DefaultAsyncHttpClientConfig.Builder()
- builder.setConnectTimeout(settings.connectTimeout.toMillis.toInt)
- builder.setRequestTimeout(settings.requestTimeout.toMillis.toInt)
- // builder.setThreadFactory(threadFactory) // Doesn't help to push MDC context into AsyncCompletionHandler
- builder.build()
- }
-
- private val httpClient = new DefaultAsyncHttpClient(httpClientConfig)
-
- def run(method: Method, uri: URI, contentType: String, data: String): Future[Unit] = {
- // log all outcome connections
- val fingerPrint = RandomUtils.randomString(10)
- logger.info("{}, apply(method={}, uri={}, contentType={})", fingerPrint, method, uri, contentType)
- val promise = Promise[Response]()
-
- val q = new RequestBuilder(method.toString)
- .setUrl(uri.toString)
- .setBody(data)
-
- settings.defaultHeaders.foreach {
- case (k, v) =>
- q.setHeader(k, v)
- }
-
- q.addHeader("Content-Type", contentType)
-
- httpClient.prepareRequest(q).execute(new AsyncCompletionHandler[Unit] {
- override def onCompleted(response: Response): Unit = {
- promise.success(response)
- }
-
- override def onThrowable(t: Throwable): Unit = {
- promise.failure(t)
- super.onThrowable(t)
- }
- })
-
- // see AsyncHttpClientFetcher
- val parentMdcContext = MDC.getCopyOfContextMap
- promise.future.flatMap { response =>
- setContextMap(parentMdcContext)
-
- val statusCode = response.getStatusCode
- // https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success
- if (statusCode >= 200 && statusCode < 300) {
- logger.debug("{}, success", fingerPrint)
- Future.successful(())
- } else {
- logger.error(
- "{}, HTTP {}, BODY:\n{}",
- fingerPrint,
- response.getStatusCode.asInstanceOf[AnyRef],
- response.getResponseBody.take(100)
- )
- Future.failed(new IllegalStateException("An unexpected response from the server"))
- }
- }
- }
-
- private[this] def setContextMap(context: java.util.Map[String, String]): Unit =
- Option(context).fold(MDC.clear())(MDC.setContextMap)
-
- override def close(): Unit = {
- httpClient.close()
- es.shutdown()
- }
-
-}
-
-object AsyncHttpClientUploader {
-
- case class Settings(connectTimeout: FiniteDuration,
- requestTimeout: FiniteDuration,
- defaultHeaders: Map[String, String] = Map.empty)
-
- sealed trait Method
-
- object Method {
-
- case object Put extends Method {
- override val toString = "PUT"
- }
-
- case object Post extends Method {
- override val toString = "POST"
- }
-
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/http/package.scala b/src/main/scala/xyz/driver/common/http/package.scala
deleted file mode 100644
index 3aff80c..0000000
--- a/src/main/scala/xyz/driver/common/http/package.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package xyz.driver.common
-
-import java.net.URL
-
-import scala.concurrent.Future
-
-package object http {
- type HttpFetcher = URL => Future[Array[Byte]]
-}
diff --git a/src/main/scala/xyz/driver/common/logging/DefaultPhiLogger.scala b/src/main/scala/xyz/driver/common/logging/DefaultPhiLogger.scala
deleted file mode 100644
index ca25c44..0000000
--- a/src/main/scala/xyz/driver/common/logging/DefaultPhiLogger.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-package xyz.driver.common.logging
-
-import org.slf4j.{Logger => Underlying}
-
-class DefaultPhiLogger private[logging](underlying: Underlying) extends PhiLogger {
-
- def error(message: PhiString): Unit = underlying.error(message.text)
-
- def warn(message: PhiString): Unit = underlying.warn(message.text)
-
- def info(message: PhiString): Unit = underlying.info(message.text)
-
- def debug(message: PhiString): Unit = underlying.debug(message.text)
-
- def trace(message: PhiString): Unit = underlying.trace(message.text)
-
-}
diff --git a/src/main/scala/xyz/driver/common/logging/Implicits.scala b/src/main/scala/xyz/driver/common/logging/Implicits.scala
deleted file mode 100644
index e486cc1..0000000
--- a/src/main/scala/xyz/driver/common/logging/Implicits.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-package xyz.driver.common.logging
-
-import java.io.File
-import java.net.{URI, URL}
-import java.nio.file.Path
-import java.time.LocalDateTime
-import java.util.UUID
-
-import scala.concurrent.duration.Duration
-
-trait Implicits {
-
- // DO NOT ADD!
- // phi"$fullName" is easier to write, than phi"${Unsafe(fullName)}"
- // If you wrote the second version, it means that you know, what you doing.
- // implicit def toPhiString(s: String): PhiString = Unsafe(s)
-
- implicit def toPhiStringContext(sc: StringContext): PhiStringContext = new PhiStringContext(sc)
-
- implicit def booleanToPhiString(x: Boolean): PhiString = Unsafe(x.toString)
-
- implicit def uriToPhiString(x: URI): PhiString = Unsafe(x.toString)
-
- implicit def urlToPhiString(x: URL): PhiString = Unsafe(x.toString)
-
- implicit def pathToPhiString(x: Path): PhiString = Unsafe(x.toString)
-
- implicit def fileToPhiString(x: File): PhiString = Unsafe(x.toString)
-
- implicit def localDateTimeToPhiString(x: LocalDateTime): PhiString = Unsafe(x.toString)
-
- implicit def durationToPhiString(x: Duration): PhiString = Unsafe(x.toString)
-
- implicit def uuidToPhiString(x: UUID): PhiString = Unsafe(x.toString)
-
- implicit def tuple2ToPhiString[T1, T2](x: (T1, T2))
- (implicit inner1: T1 => PhiString,
- inner2: T2 => PhiString): PhiString = x match {
- case (a, b) => phi"($a, $b)"
- }
-
- implicit def tuple3ToPhiString[T1, T2, T3](x: (T1, T2, T3))
- (implicit inner1: T1 => PhiString,
- inner2: T2 => PhiString,
- inner3: T3 => PhiString): PhiString = x match {
- case (a, b, c) => phi"($a, $b, $c)"
- }
-
- implicit def optionToPhiString[T](opt: Option[T])(implicit inner: T => PhiString): PhiString = opt match {
- case None => phi"None"
- case Some(x) => phi"Some($x)"
- }
-
- implicit def iterableToPhiString[T](xs: Iterable[T])(implicit inner: T => PhiString): PhiString = {
- Unsafe(xs.map(inner(_).text).mkString("Col(", ", ", ")"))
- }
-
- implicit def throwableToPhiString(x: Throwable): PhiString = {
- Unsafe(Option(x.getMessage).getOrElse(x.getClass.getName))
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/logging/PhiLogger.scala b/src/main/scala/xyz/driver/common/logging/PhiLogger.scala
deleted file mode 100644
index c8907a8..0000000
--- a/src/main/scala/xyz/driver/common/logging/PhiLogger.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package xyz.driver.common.logging
-
-trait PhiLogger {
-
- def error(message: PhiString): Unit
-
- def warn(message: PhiString): Unit
-
- def info(message: PhiString): Unit
-
- def debug(message: PhiString): Unit
-
- def trace(message: PhiString): Unit
-
-}
diff --git a/src/main/scala/xyz/driver/common/logging/PhiLogging.scala b/src/main/scala/xyz/driver/common/logging/PhiLogging.scala
deleted file mode 100644
index b8cdcf0..0000000
--- a/src/main/scala/xyz/driver/common/logging/PhiLogging.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package xyz.driver.common.logging
-
-import org.slf4j.LoggerFactory
-
-trait PhiLogging extends Implicits {
-
- protected val logger: PhiLogger = new DefaultPhiLogger(LoggerFactory.getLogger(getClass.getName))
-
- /**
- * Logs the failMessage on an error level, if isSuccessful is false.
- * @return isSuccessful
- */
- protected def loggedError(isSuccessful: Boolean, failMessage: PhiString): Boolean = {
- if (!isSuccessful) {
- logger.error(failMessage)
- }
- isSuccessful
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/logging/PhiString.scala b/src/main/scala/xyz/driver/common/logging/PhiString.scala
deleted file mode 100644
index ce1b90c..0000000
--- a/src/main/scala/xyz/driver/common/logging/PhiString.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package xyz.driver.common.logging
-
-class PhiString(private[logging] val text: String) {
- // scalastyle:off
- @inline def +(that: PhiString) = new PhiString(this.text + that.text)
-}
diff --git a/src/main/scala/xyz/driver/common/logging/PhiStringContext.scala b/src/main/scala/xyz/driver/common/logging/PhiStringContext.scala
deleted file mode 100644
index 8b3c9d0..0000000
--- a/src/main/scala/xyz/driver/common/logging/PhiStringContext.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package xyz.driver.common.logging
-
-final class PhiStringContext(val sc: StringContext) extends AnyVal {
- def phi(args: PhiString*): PhiString = {
- val phiArgs = args.map(_.text)
- new PhiString(sc.s(phiArgs: _*))
- }
-}
diff --git a/src/main/scala/xyz/driver/common/logging/Unsafe.scala b/src/main/scala/xyz/driver/common/logging/Unsafe.scala
deleted file mode 100644
index c605c85..0000000
--- a/src/main/scala/xyz/driver/common/logging/Unsafe.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package xyz.driver.common.logging
-
-/**
- * Use it with care!
- */
-case class Unsafe[T](private[logging] val value: T) extends PhiString(Option(value).map(_.toString).getOrElse("<null>"))
diff --git a/src/main/scala/xyz/driver/common/logging/package.scala b/src/main/scala/xyz/driver/common/logging/package.scala
deleted file mode 100644
index 479f59e..0000000
--- a/src/main/scala/xyz/driver/common/logging/package.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package xyz.driver.common
-
-package object logging extends Implicits
diff --git a/src/main/scala/xyz/driver/common/pdf/PdfRenderer.scala b/src/main/scala/xyz/driver/common/pdf/PdfRenderer.scala
deleted file mode 100644
index 9882f5d..0000000
--- a/src/main/scala/xyz/driver/common/pdf/PdfRenderer.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package xyz.driver.common.pdf
-
-import java.nio.file.Path
-
-trait PdfRenderer {
-
- def render(html: String, documentName: String, force: Boolean = false): Path
-
- def delete(documentName: String): Unit
-
- def getPath(fileName: String): Path
-
-}
diff --git a/src/main/scala/xyz/driver/common/pdf/WkHtmlToPdfRenderer.scala b/src/main/scala/xyz/driver/common/pdf/WkHtmlToPdfRenderer.scala
deleted file mode 100644
index 0e0b338..0000000
--- a/src/main/scala/xyz/driver/common/pdf/WkHtmlToPdfRenderer.scala
+++ /dev/null
@@ -1,106 +0,0 @@
-package xyz.driver.common.pdf
-
-import java.io.IOException
-import java.nio.file._
-
-import io.github.cloudify.scala.spdf._
-import xyz.driver.common.logging._
-import xyz.driver.common.pdf.WkHtmlToPdfRenderer.Settings
-
-object WkHtmlToPdfRenderer {
-
- final case class Settings(downloadsDir: String) {
-
- lazy val downloadsPath: Path = getPathFrom(downloadsDir)
-
- private def getPathFrom(x: String): Path = {
- val dirPath = if (x.startsWith("/")) Paths.get(x)
- else {
- val workingDir = Paths.get(".")
- workingDir.resolve(x)
- }
-
- dirPath.toAbsolutePath.normalize()
- }
-
- }
-
-}
-
-class WkHtmlToPdfRenderer(settings: Settings) extends PdfRenderer with PhiLogging {
-
- private val pdf = Pdf(new PdfConfig {
- disableJavascript := true
- disableExternalLinks := true
- disableInternalLinks := true
- printMediaType := Some(true)
- orientation := Portrait
- pageSize := "A4"
- lowQuality := true
- })
-
- override def render(html: String, documentName: String, force: Boolean = false): Path = {
- checkedCreate(html, documentName, force)
- }
-
- override def delete(documentName: String): Unit = {
- logger.trace(phi"delete(${Unsafe(documentName)})")
-
- val file = getPath(documentName)
- logger.debug(phi"File: $file")
- if (Files.deleteIfExists(file)) {
- logger.info(phi"Deleted")
- } else {
- logger.warn(phi"Doesn't exist")
- }
- }
-
- override def getPath(documentName: String): Path = {
- settings.downloadsPath.resolve(s"$documentName.pdf").toAbsolutePath
- }
-
- protected def checkedCreate[SourceT: SourceDocumentLike](src: SourceT, fileName: String, force: Boolean): Path = {
- logger.trace(phi"checkedCreate(fileName=${Unsafe(fileName)}, force=$force)")
-
- val dest = getPath(fileName)
- logger.debug(phi"Destination file: $dest")
-
- if (force || !dest.toFile.exists()) {
- logger.trace(phi"Force refresh the file")
- val newDocPath = forceCreate(src, dest)
- logger.info(phi"Updated")
- newDocPath
- } else if (dest.toFile.exists()) {
- logger.trace(phi"Already exists")
- dest
- } else {
- logger.trace(phi"The file does not exist")
- val newDocPath = forceCreate(src, dest)
- logger.info(phi"Created")
- newDocPath
- }
- }
-
- protected def forceCreate[SourceT: SourceDocumentLike](src: SourceT, dest: Path): Path = {
- logger.trace(phi"forceCreate[${Unsafe(src.getClass.getName)}](dest=$dest)")
-
- val destTemp = Files.createTempFile("driver", ".pdf")
- val destTempFile = destTemp.toFile
-
- Files.createDirectories(dest.getParent)
-
- val retCode = pdf.run(src, destTempFile)
- lazy val pdfSize = destTempFile.length()
- if (retCode != 0) {
- // Try to google "wkhtmltopdf returns {retCode}"
- throw new IOException(s"Can create the document, the return code is $retCode")
- } else if (pdfSize == 0) {
- // Anything could happen, e.g. https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2540
- throw new IOException("The pdf is empty")
- } else {
- logger.debug(phi"Size: ${Unsafe(pdfSize)}B")
- Files.move(destTemp, dest, StandardCopyOption.REPLACE_EXISTING)
- dest
- }
- }
-}
diff --git a/src/main/scala/xyz/driver/common/resources/ResourcesStorage.scala b/src/main/scala/xyz/driver/common/resources/ResourcesStorage.scala
deleted file mode 100644
index f52d992..0000000
--- a/src/main/scala/xyz/driver/common/resources/ResourcesStorage.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-package xyz.driver.common.resources
-
-import scala.io.{Codec, Source}
-
-trait ResourcesStorage {
-
- /**
- * @param resourcePath Don't forget / at start
- */
- def getFirstLine(resourcePath: String): String
-
-}
-
-object RealResourcesStorage extends ResourcesStorage {
-
- def getFirstLine(resourcePath: String): String = {
- val resourceUrl = getClass.getResource(resourcePath)
- Option(resourceUrl) match {
- case Some(url) =>
- val source = Source.fromURL(resourceUrl)(Codec.UTF8)
- try {
- val lines = source.getLines()
- if (lines.isEmpty) throw new RuntimeException(s"'$resourcePath' is empty")
- else lines.next()
- } finally {
- source.close()
- }
- case None =>
- throw new RuntimeException(s"Can not find the '$resourcePath'!")
- }
- }
-
-}
-
-object FakeResourcesStorage extends ResourcesStorage {
-
- def getFirstLine(resourcePath: String): String = ""
-
-}
diff --git a/src/main/scala/xyz/driver/common/utils/Computation.scala b/src/main/scala/xyz/driver/common/utils/Computation.scala
deleted file mode 100644
index a435afe..0000000
--- a/src/main/scala/xyz/driver/common/utils/Computation.scala
+++ /dev/null
@@ -1,110 +0,0 @@
-package xyz.driver.common.utils
-
-import scala.concurrent.{ExecutionContext, Future}
-
-/**
- * Takes care of computations
- *
- * Success(either) - the computation will be continued.
- * Failure(error) - the computation was failed with unhandled error.
- *
- * Either[Result, T]:
- * Left(result) is a final and handled result, another computations (map, flatMap) will be ignored.
- * Right(T) is a current result. Functions in map/flatMap will continue the computation.
- *
- * Example:
- * {{{
- * import scala.concurrent.ExecutionContext.Implicits.global
- * import scala.concurrent.{ExecutionContext, Future}
- * import com.drivergrp.server.com.drivergrp.server.common.utils.Computation
- *
- * def successful = for {
- * x <- Computation.continue(1)
- * y <- Computation.continue(2)
- * } yield s"\$x + \$y"
- *
- * // Prints "Success(1 + 2)"
- * successful.join.onComplete(print)
- *
- * def failed = for {
- * x <- Computation.abort("Failed on x")
- * _ = print("Second step")
- * y <- Computation.continue(2)
- * } yield s"\$x + \$y"
- *
- * // Prints "Success(Failed on x)"
- * failed.join.onComplete(print)
- * }}}
- *
- * TODO: Make future private
- *
- * @param future The final flow in a future.
- * @tparam R Type of result for aborted computation.
- * @tparam T Type of result for continued computation.
- */
-final case class Computation[+R, +T](future: Future[Either[R, T]]) {
-
- def flatMap[R2, T2](f: T => Computation[R2, T2])(implicit ec: ExecutionContext, ev: R <:< R2): Computation[R2, T2] = {
- Computation(future.flatMap {
- case Left(x) => Future.successful(Left(x))
- case Right(x) => f(x).future
- })
- }
-
- def processExceptions[R2](f: PartialFunction[Throwable, R2])
- (implicit ev1: R <:< R2,
- ec: ExecutionContext): Computation[R2, T] = {
- val strategy = f.andThen(x => Left(x): Either[R2, T])
- val castedFuture: Future[Either[R2, T]] = future.map {
- case Left(x) => Left(x)
- case Right(x) => Right(x)
- }
- Computation(castedFuture.recover(strategy))
- }
-
- def map[T2](f: T => T2)(implicit ec: ExecutionContext): Computation[R, T2] = flatMap { a =>
- Computation.continue(f(a))
- }
-
- def andThen(f: T => Any)(implicit ec: ExecutionContext): Computation[R, T] = map { a =>
- f(a)
- a
- }
-
- def filter(f: T => Boolean)(implicit ec: ExecutionContext): Computation[R, T] = map { a =>
- if (f(a)) a
- else throw new NoSuchElementException("When filtering")
- }
-
- def withFilter(f: T => Boolean)(implicit ec: ExecutionContext): Computation[R, T] = filter(f)
-
- def foreach[T2](f: T => T2)(implicit ec: ExecutionContext): Unit = future.foreach {
- case Right(x) => f(x)
- case _ =>
- }
-
- def toFuture[R2](resultFormatter: T => R2)(implicit ec: ExecutionContext, ev: R <:< R2): Future[R2] = future.map {
- case Left(x) => x
- case Right(x) => resultFormatter(x)
- }
-
- def toFuture[R2](implicit ec: ExecutionContext, ev1: R <:< R2, ev2: T <:< R2): Future[R2] = future.map {
- case Left(x) => x
- case Right(x) => x
- }
-
-}
-
-object Computation {
-
- def continue[T](x: T): Computation[Nothing, T] = Computation(Future.successful(Right(x)))
-
- def abort[R](result: R): Computation[R, Nothing] = Computation(Future.successful(Left(result)))
-
- def fail(exception: Throwable): Computation[Nothing, Nothing] = Computation(Future.failed(exception))
-
- def fromFuture[T](input: Future[T])(implicit ec: ExecutionContext): Computation[Nothing, T] = Computation {
- input.map { x => Right(x) }
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/utils/FutureUtils.scala b/src/main/scala/xyz/driver/common/utils/FutureUtils.scala
deleted file mode 100644
index 6933c63..0000000
--- a/src/main/scala/xyz/driver/common/utils/FutureUtils.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package xyz.driver.common.utils
-
-import scala.concurrent.{ExecutionContext, Future}
-import scala.util.Try
-
-object FutureUtils {
-
- def executeSynchronously[T](f: ExecutionContext => Future[T]): Try[T] = {
- val future = f {
- new ExecutionContext {
- override def reportFailure(cause: Throwable): Unit = cause.printStackTrace()
-
- override def execute(runnable: Runnable): Unit = runnable.run()
- }
- }
- future.value.get
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/utils/Implicits.scala b/src/main/scala/xyz/driver/common/utils/Implicits.scala
deleted file mode 100644
index bdccaac..0000000
--- a/src/main/scala/xyz/driver/common/utils/Implicits.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-package xyz.driver.common.utils
-
-import scala.collection.generic.CanBuildFrom
-
-object Implicits {
-
- final class ConditionalAppend[U, T[U] <: TraversableOnce[U]](val c: T[U]) extends AnyVal {
- def condAppend(cond: => Boolean, value: U)(implicit cbf: CanBuildFrom[T[U], U, T[U]]): T[U] = {
- val col = cbf()
- if (cond) {
- ((col ++= c) += value).result
- } else {
- c.asInstanceOf[T[U]]
- }
- }
- }
-
- implicit def traversableConditionalAppend[U, T[U] <: TraversableOnce[U]](c: T[U]): ConditionalAppend[U, T] =
- new ConditionalAppend[U, T](c)
-
- implicit def toMapOps[K, V](x: Map[K, V]): MapOps[K, V] = new MapOps(x)
-}
diff --git a/src/main/scala/xyz/driver/common/utils/JsonSerializer.scala b/src/main/scala/xyz/driver/common/utils/JsonSerializer.scala
deleted file mode 100644
index 936a983..0000000
--- a/src/main/scala/xyz/driver/common/utils/JsonSerializer.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-package xyz.driver.common.utils
-
-import java.text.SimpleDateFormat
-
-import com.fasterxml.jackson.annotation.JsonInclude
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
-import com.fasterxml.jackson.module.scala.DefaultScalaModule
-import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
-
-object JsonSerializer {
-
- private val mapper = new ObjectMapper() with ScalaObjectMapper
- mapper.registerModule(DefaultScalaModule)
- mapper.registerModule(new JavaTimeModule)
- mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
-
- def serialize(value: Any): String = {
- mapper.writeValueAsString(value)
- }
-
- def deserialize[T](value: String)(implicit m: Manifest[T]): T = {
- mapper.readValue(value)
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/utils/MapOps.scala b/src/main/scala/xyz/driver/common/utils/MapOps.scala
deleted file mode 100644
index 759fdea..0000000
--- a/src/main/scala/xyz/driver/common/utils/MapOps.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package xyz.driver.common.utils
-
-final class MapOps[K, V](val self: Map[K, V]) extends AnyVal {
- def swap: Map[V, Set[K]] = {
- self
- .toList
- .groupBy { case (_, v) => v }
- .mapValues(_.map { case (k, _) => k }.toSet)
- }
-}
diff --git a/src/main/scala/xyz/driver/common/utils/RandomUtils.scala b/src/main/scala/xyz/driver/common/utils/RandomUtils.scala
deleted file mode 100644
index d4cd4dc..0000000
--- a/src/main/scala/xyz/driver/common/utils/RandomUtils.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package xyz.driver.common.utils
-
-import java.util.concurrent.ThreadLocalRandom
-
-import scala.collection._
-
-object RandomUtils {
-
- private def Random = ThreadLocalRandom.current()
-
- private val chars: Seq[Char] = ('0' to '9') ++ ('a' to 'z')
-
- def randomString(len: Int): String = {
- (0 until len).map({ _ =>
- val i = Random.nextInt(0, chars.size)
- chars(i)
- })(breakOut)
- }
-
-}
diff --git a/src/main/scala/xyz/driver/common/utils/ServiceUtils.scala b/src/main/scala/xyz/driver/common/utils/ServiceUtils.scala
deleted file mode 100644
index dd309fb..0000000
--- a/src/main/scala/xyz/driver/common/utils/ServiceUtils.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-package xyz.driver.common.utils
-
-import xyz.driver.common.db.SearchFilterBinaryOperation.Eq
-import xyz.driver.common.db.SearchFilterExpr
-import xyz.driver.common.db.SearchFilterExpr.{Atom, Dimension}
-import xyz.driver.common.logging._
-
-import scala.util.{Failure, Success, Try}
-
-
-object ServiceUtils extends PhiLogging {
- def findEqFilter(filter: SearchFilterExpr, fieldName: String): Option[SearchFilterExpr] = {
- findEqFilter(filter, Dimension(None, fieldName))
- }
-
- def findEqFilter(filter: SearchFilterExpr, dimension: Dimension): Option[SearchFilterExpr] = {
- filter.find {
- case Atom.Binary(dimension, Eq, _) => true
- case _ => false
- }
- }
-
- def convertIdInFilterToLong(value: AnyRef): Option[Long] = {
- Try(value.toString.toLong) match {
- case Success(id) =>
- Option(id)
- case Failure(e) =>
- logger.error(phi"Incorrect id format in filter $e")
- None
- }
- }
-}
diff --git a/src/main/scala/xyz/driver/common/utils/Utils.scala b/src/main/scala/xyz/driver/common/utils/Utils.scala
deleted file mode 100644
index 39f1294..0000000
--- a/src/main/scala/xyz/driver/common/utils/Utils.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package xyz.driver.common.utils
-
-import java.time.LocalDateTime
-
-object Utils {
-
- implicit val localDateTimeOrdering: Ordering[LocalDateTime] = Ordering.fromLessThan(_ isBefore _)
-
- /**
- * Hack to avoid scala compiler bug with getSimpleName
- * @see https://issues.scala-lang.org/browse/SI-2034
- */
- def getClassSimpleName(klass: Class[_]): String = {
- try {
- klass.getSimpleName
- } catch {
- case _: InternalError =>
- val fullName = klass.getName.stripSuffix("$")
- val fullClassName = fullName.substring(fullName.lastIndexOf(".") + 1)
- fullClassName.substring(fullClassName.lastIndexOf("$") + 1)
- }
- }
-}
diff --git a/src/main/scala/xyz/driver/common/validation/ValidationError.scala b/src/main/scala/xyz/driver/common/validation/ValidationError.scala
deleted file mode 100644
index 6db445d..0000000
--- a/src/main/scala/xyz/driver/common/validation/ValidationError.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-package xyz.driver.common.validation
-
-final case class ValidationError(message: String)
diff --git a/src/main/scala/xyz/driver/common/validation/Validators.scala b/src/main/scala/xyz/driver/common/validation/Validators.scala
deleted file mode 100644
index 8d807f4..0000000
--- a/src/main/scala/xyz/driver/common/validation/Validators.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-package xyz.driver.common.validation
-
-import xyz.driver.common.logging._
-import xyz.driver.common.utils.JsonSerializer
-
-import scala.util.control.NonFatal
-
-object Validators extends PhiLogging {
-
- type Validator[Input, Refined] = Input => Either[ValidationError, Refined]
-
- def generic[T, R](message: String)(f: PartialFunction[T, R]): Validator[T, R] = { value =>
- if (f.isDefinedAt(value)) Right(f(value))
- else Left(ValidationError(message))
- }
-
- def nonEmpty[T](field: String): Validator[Option[T], T] = generic(s"$field is empty") {
- case Some(x) => x
- }
-
- def nonEmptyString(field: String): Validator[String, String] = generic(s"$field is empty") {
- case x if x.nonEmpty => x
- }
-
- def deserializableTo[Refined](field: String)
- (value: String)
- (implicit m: Manifest[Refined]): Either[ValidationError, Refined] = {
- try {
- Right(JsonSerializer.deserialize[Refined](value))
- } catch {
- case NonFatal(e) =>
- logger.error(phi"Can not deserialize the ${Unsafe(field)}: $e")
- Left(ValidationError(s"$field is invalid"))
- }
- }
-
- def success[T](result: T): Either[Nothing, T] = Right(result)
-
- def fail(message: String): Either[ValidationError, Nothing] = Left(ValidationError(message))
-
-}