Skip to content

Commit

Permalink
Make ValidatePriority a trait (#4832)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivergrabinski authored Apr 3, 2024
1 parent b2c5e64 commit a14152a
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ object ResolversModule extends ModuleDef {
ResolversImpl(
fetchContext,
resolverContextResolution,
ValidatePriority.priorityAlreadyExists(xas),
config.resolvers.eventLog,
xas,
clock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,12 @@ class ResolversRoutesSpec extends BaseRouteSpec {
case _ => IO.none
}

private lazy val validatePriority = ValidatePriority.priorityAlreadyExists(xas)

private lazy val resolvers = ResolversImpl(
fetchContext,
resolverContextResolution,
validatePriority,
eventLogConfig,
xas,
clock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ trait Resolvers {

object Resolvers {

type ValidatePriority = (ProjectRef, Iri, Priority) => IO[Unit]

/**
* The resolver entity type.
*/
Expand Down Expand Up @@ -256,7 +254,7 @@ object Resolvers {
IO.raiseWhen(missing.nonEmpty)(InvalidIdentities(missing))
}
case _ => IO.unit
}) >> validatePriority(project, id, value.priority)
}) >> validatePriority.validate(project, id, value.priority)

def create(c: CreateResolver): IO[ResolverCreated] = state match {
// Create a resolver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.Resolvers.{entityType, expandIri}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolversImpl.ResolversLog
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverCommand.{CreateResolver, DeprecateResolver, UpdateResolver}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverRejection.{FetchByTagNotSupported, PriorityAlreadyExists, ResolverNotFound, RevisionNotFound}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverRejection.{FetchByTagNotSupported, ResolverNotFound, RevisionNotFound}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model._
import ch.epfl.bluebrain.nexus.delta.sourcing._
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{Identity, ProjectRef}
import doobie.implicits._
import io.circe.Json

final class ResolversImpl private (
Expand Down Expand Up @@ -157,31 +156,16 @@ object ResolversImpl {
def apply(
fetchContext: FetchContext,
contextResolution: ResolverContextResolution,
validatePriority: ValidatePriority,
config: EventLogConfig,
xas: Transactors,
clock: Clock[IO]
)(implicit
api: JsonLdApi,
uuidF: UUIDF
): Resolvers = {
def priorityAlreadyExists(ref: ProjectRef, self: Iri, priority: Priority): IO[Unit] = {
sql"""SELECT id FROM scoped_states
WHERE type = ${Resolvers.entityType}
AND org = ${ref.organization} AND project = ${ref.project}
AND id != $self
AND (value->'deprecated')::boolean = false
AND (value->'value'->'priority')::int = ${priority.value}"""
.query[Iri]
.option
.transact(xas.read)
.flatMap {
case Some(other) => IO.raiseError(PriorityAlreadyExists(ref, other, priority))
case None => IO.unit
}
}

new ResolversImpl(
ScopedEventLog(Resolvers.definition(priorityAlreadyExists, clock), config, xas),
ScopedEventLog(Resolvers.definition(validatePriority, clock), config, xas),
fetchContext,
new JsonLdSourceResolvingDecoder[ResolverValue](
contexts.resolvers,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ch.epfl.bluebrain.nexus.delta.sdk.resolvers

import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.sdk.implicits._
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.Priority
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverRejection.PriorityAlreadyExists
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import doobie.implicits._

trait ValidatePriority {

/** Validate that a resolver with the given self & priority can be created in the provided project */
def validate(ref: ProjectRef, self: Iri, priority: Priority): IO[Unit]

}

object ValidatePriority {

/** Provides a [[ValidatePriority]] instance that ensure there is no active resolver with the given priority */
def priorityAlreadyExists(xas: Transactors): ValidatePriority = (ref: ProjectRef, self: Iri, priority: Priority) =>
sql"""SELECT id FROM scoped_states
WHERE type = ${Resolvers.entityType}
AND org = ${ref.organization} AND project = ${ref.project}
AND id != $self
AND (value->'deprecated')::boolean = false
AND (value->'value'->'priority')::int = ${priority.value}"""
.query[Iri]
.option
.transact(xas.read)
.flatMap {
case Some(other) => IO.raiseError(PriorityAlreadyExists(ref, other, priority))
case None => IO.unit
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package ch.epfl.bluebrain.nexus.delta.sdk.resolvers
import cats.data.NonEmptyList
import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary.nxv
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.Resolvers.{evaluate, ValidatePriority}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.Resolvers.evaluate
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.IdentityResolution.{ProvidedIdentities, UseCurrentCaller}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.Priority
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverCommand.{CreateResolver, DeprecateResolver, UpdateResolver}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ class ResolversImplSpec extends CatsEffectSpec with DoobieScalaTestFixture with
Set(deprecatedProject.ref)
)

private lazy val validatePriority = ValidatePriority.priorityAlreadyExists(xas)

private lazy val resolvers: Resolvers = ResolversImpl(
fetchContext,
resolverContextResolution,
validatePriority,
eventLogConfig,
xas,
clock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import cats.effect.kernel.Clock
import ch.epfl.bluebrain.nexus.delta.kernel.utils.UUIDF
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.JsonLdApi
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.{ResolverContextResolution, Resolvers, ResolversImpl}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.{ResolverContextResolution, Resolvers, ResolversImpl, ValidatePriority}
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig
import ch.epfl.bluebrain.nexus.ship.FailingUUID
Expand All @@ -16,10 +16,14 @@ object ResolverWiring {
jsonLdApi: JsonLdApi
): Resolvers = {
implicit val uuidF: UUIDF = FailingUUID

val alwaysValidatePriority: ValidatePriority = (_, _, _) => IO.unit

ResolversImpl(
fetchContext,
// We rely on the parsed values and not on the original value
ResolverContextResolution.never,
alwaysValidatePriority,
config,
xas,
clock
Expand Down

0 comments on commit a14152a

Please sign in to comment.