Skip to content

Commit

Permalink
Break circular dependencies between resources and schemas (#4799)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivergrabinski authored Mar 18, 2024
1 parent 06a20cf commit f6986f9
Show file tree
Hide file tree
Showing 27 changed files with 384 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@ import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ApiMappings
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverResolution.ResourceResolution
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.{ResolverContextResolution, Resolvers, ResourceResolution}
import ch.epfl.bluebrain.nexus.delta.sdk.resources.Resources.{ResourceDefinition, ResourceLog}
import ch.epfl.bluebrain.nexus.delta.sdk.resources._
import ch.epfl.bluebrain.nexus.delta.sdk.resources.model.{Resource, ResourceEvent}
import ch.epfl.bluebrain.nexus.delta.sdk.resources.{DetectChange, Resources, ResourcesConfig, ResourcesImpl, ValidateResource}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.Schemas
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.FetchSchema
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.Schema
import ch.epfl.bluebrain.nexus.delta.sdk.sse.SseEncoder
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.{ScopedEventLog, Transactors}
import izumi.distage.model.definition.{Id, ModuleDef}

/**
* Resources wiring
*/
object ResourcesModule extends ModuleDef {
make[ResourceResolution[Schema]].from { (aclCheck: AclCheck, resolvers: Resolvers, fetchSchema: FetchSchema) =>
ResourceResolution.schemaResource(aclCheck, resolvers, fetchSchema, excludeDeprecated = false)
}

make[ValidateResource].from {
(resourceResolution: ResourceResolution[Schema], rcr: RemoteContextResolution @Id("aggregate")) =>
ValidateResource(resourceResolution)(rcr)
Expand All @@ -40,39 +45,44 @@ object ResourcesModule extends ModuleDef {

make[DetectChange].from { (config: ResourcesConfig) => DetectChange(config.skipUpdateNoChange) }

make[ResourceDefinition].from { (validateResource: ValidateResource, detectChange: DetectChange, clock: Clock[IO]) =>
Resources.definition(validateResource, detectChange, clock)
}

make[ResourceLog].from { (scopedDefinition: ResourceDefinition, config: ResourcesConfig, xas: Transactors) =>
ScopedEventLog(scopedDefinition, config.eventLog, xas)
}

make[FetchResource].from { (scopedLog: ResourceLog) =>
FetchResource(scopedLog)
}

make[Resources].from {
(
validate: ValidateResource,
detectChange: DetectChange,
resourceLog: ResourceLog,
fetchContext: FetchContext,
config: ResourcesConfig,
resolverContextResolution: ResolverContextResolution,
api: JsonLdApi,
xas: Transactors,
clock: Clock[IO],
uuidF: UUIDF
) =>
ResourcesImpl(
validate,
detectChange,
resourceLog,
fetchContext,
resolverContextResolution,
config,
xas,
clock
resolverContextResolution
)(
api,
uuidF
)
}

make[ResolverContextResolution].from {
(aclCheck: AclCheck, resolvers: Resolvers, resources: Resources, rcr: RemoteContextResolution @Id("aggregate")) =>
ResolverContextResolution(aclCheck, resolvers, resources, rcr)
}

make[ResourceResolution[Schema]].from { (aclCheck: AclCheck, resolvers: Resolvers, schemas: Schemas) =>
ResourceResolution.schemaResource(aclCheck, resolvers, schemas, excludeDeprecated = false)
(
aclCheck: AclCheck,
resolvers: Resolvers,
rcr: RemoteContextResolution @Id("aggregate"),
fetchResource: FetchResource
) =>
ResolverContextResolution(aclCheck, resolvers, rcr, fetchResource)
}

make[ResourcesRoutes].from {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import ch.epfl.bluebrain.nexus.delta.sdk.model.metrics.ScopedEventMetricEncoder
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ApiMappings
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.{ResolverContextResolution, Resolvers}
import ch.epfl.bluebrain.nexus.delta.sdk.resources.Resources
import ch.epfl.bluebrain.nexus.delta.sdk.resources.FetchResource
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.Schemas.{SchemaDefinition, SchemaLog}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas._
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.{Schema, SchemaEvent}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.{SchemaImports, Schemas, SchemasImpl, ValidateSchema}
import ch.epfl.bluebrain.nexus.delta.sdk.sse.SseEncoder
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.{ScopedEventLog, Transactors}
import izumi.distage.model.definition.{Id, ModuleDef}

/**
Expand All @@ -40,37 +41,43 @@ object SchemasModule extends ModuleDef {

}

make[SchemaDefinition].from { (validateSchema: ValidateSchema, clock: Clock[IO]) =>
Schemas.definition(validateSchema, clock)
}

make[SchemaLog].from { (scopedDefinition: SchemaDefinition, config: AppConfig, xas: Transactors) =>
ScopedEventLog(scopedDefinition, config.schemas.eventLog, xas)
}

make[FetchSchema].from { (schemaLog: SchemaLog) =>
FetchSchema(schemaLog)
}

make[Schemas].from {
(
schemaLog: SchemaLog,
fetchContext: FetchContext,
schemaImports: SchemaImports,
api: JsonLdApi,
validate: ValidateSchema,
resolverContextResolution: ResolverContextResolution,
config: AppConfig,
xas: Transactors,
clock: Clock[IO],
uuidF: UUIDF
) =>
SchemasImpl(
schemaLog,
fetchContext,
schemaImports,
resolverContextResolution,
validate,
config.schemas,
xas,
clock
resolverContextResolution
)(api, uuidF)
}

make[SchemaImports].from {
(
aclCheck: AclCheck,
resolvers: Resolvers,
resources: Resources,
schemas: Schemas
fetchSchema: FetchSchema,
fetchResource: FetchResource
) =>
SchemaImports(aclCheck, resolvers, schemas, resources)
SchemaImports(aclCheck, resolvers, fetchSchema, fetchResource)
}

make[SchemasRoutes].from {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import munit.catseffect.IOFixture
import munit.{AnyFixture, CatsEffectSuite}

import java.nio.file.{Files, Paths}
import scala.concurrent.duration.Duration

/**
* Test class that allows to check that across core and plugins:
Expand All @@ -26,6 +27,8 @@ import java.nio.file.{Files, Paths}
*/
class MainSuite extends NexusSuite with MainSuite.Fixture {

override val munitIOTimeout: Duration = Duration(60, "s")

private val pluginsParentPath = Paths.get("target/plugins").toAbsolutePath
private val pluginLoaderConfig = PluginLoaderConfig(pluginsParentPath.toString)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ import ch.epfl.bluebrain.nexus.delta.sdk.generators.{ProjectGen, ResourceResolut
import ch.epfl.bluebrain.nexus.delta.sdk.identities.IdentitiesDummy
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.implicits._
import ch.epfl.bluebrain.nexus.delta.sdk.model.Fetch.FetchF
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegmentRef, ResourceUris}
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions.resources
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContextDummy
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ApiMappings
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverResolution.FetchResource
import ch.epfl.bluebrain.nexus.delta.sdk.resources.NexusSource.DecodingOption
import ch.epfl.bluebrain.nexus.delta.sdk.resources.{DetectChange, Resources, ResourcesConfig, ResourcesImpl, ValidateResource}
import ch.epfl.bluebrain.nexus.delta.sdk.resources._
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.Schema
import ch.epfl.bluebrain.nexus.delta.sdk.utils.BaseRouteSpec
import ch.epfl.bluebrain.nexus.delta.sourcing.ScopedEventLog
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Authenticated, Group, Subject, User}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Tag.UserTag
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{ProjectRef, ResourceRef}
Expand Down Expand Up @@ -87,7 +88,7 @@ class ResourcesRoutesSpec extends BaseRouteSpec with CatsIOValues {

private val aclCheck = AclSimpleCheck().accepted

private val fetchSchema: (ResourceRef, ProjectRef) => FetchResource[Schema] = {
private val fetchSchema: (ResourceRef, ProjectRef) => FetchF[Schema] = {
case (ref, _) if ref.iri == schema2.id => IO.pure(Some(SchemaGen.resourceFor(schema2, deprecated = true)))
case (ref, _) if ref.iri == schema1.id => IO.pure(Some(SchemaGen.resourceFor(schema1)))
case (ref, _) if ref.iri == schema3.id => IO.pure(Some(SchemaGen.resourceFor(schema3)))
Expand All @@ -101,14 +102,17 @@ class ResourcesRoutesSpec extends BaseRouteSpec with CatsIOValues {
private val resolverContextResolution: ResolverContextResolution = ResolverContextResolution(rcr)

private def routesWithDecodingOption(implicit decodingOption: DecodingOption): (Route, Resources) = {
val resourceDef = Resources.definition(validator, DetectChange(enabled = true), clock)
val scopedLog = ScopedEventLog(
resourceDef,
ResourcesConfig(eventLogConfig, decodingOption, skipUpdateNoChange = true).eventLog,
xas
)

val resources = ResourcesImpl(
validator,
DetectChange(enabled = true),
scopedLog,
fetchContext,
resolverContextResolution,
ResourcesConfig(eventLogConfig, decodingOption, skipUpdateNoChange = true),
xas,
clock
resolverContextResolution
)
(
Route.seal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions.schemas
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContextDummy
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ApiMappings
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.{SchemaImports, SchemasConfig, SchemasImpl, ValidateSchema}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.{SchemaImports, Schemas, SchemasConfig, SchemasImpl, ValidateSchema}
import ch.epfl.bluebrain.nexus.delta.sdk.utils.BaseRouteSpec
import ch.epfl.bluebrain.nexus.delta.sourcing.ScopedEventLog
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Authenticated, Group, Subject, User}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import ch.epfl.bluebrain.nexus.testkit.ce.IOFromMap
Expand Down Expand Up @@ -78,12 +79,15 @@ class SchemasRoutesSpec extends BaseRouteSpec with IOFromMap with CatsIOValues {

private val config = SchemasConfig(eventLogConfig)

private val schemaDef = Schemas.definition(ValidateSchema.apply, clock)
private lazy val schemaLog = ScopedEventLog(schemaDef, config.eventLog, xas)

private lazy val routes =
Route.seal(
SchemasRoutes(
identities,
aclCheck,
SchemasImpl(fetchContext, schemaImports, resolverContextResolution, ValidateSchema.apply, config, xas, clock),
SchemasImpl(schemaLog, fetchContext, schemaImports, resolverContextResolution),
groupDirectives,
IndexingAction.noop
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ch.epfl.bluebrain.nexus.delta.sdk.model

import cats.effect.IO

object Fetch {

type Fetch[R] = IO[Option[R]]
type FetchF[R] = Fetch[ResourceF[R]]

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution.{logger, ProjectRemoteContext}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverResolution.ResourceResolution
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResourceResolutionReport
import ch.epfl.bluebrain.nexus.delta.sdk.resources.Resources
import ch.epfl.bluebrain.nexus.delta.sdk.resources.FetchResource
import ch.epfl.bluebrain.nexus.delta.sdk.resources.model.Resource
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{ProjectRef, ResourceRef}
Expand Down Expand Up @@ -111,18 +111,18 @@ object ResolverContextResolution {
* how to check acls
* @param resolvers
* a resolvers instance
* @param resources
* a resource instance
* @param rcr
* a previously defined 'RemoteContextResolution'
* @param fetchResource
* how to fetch a resource
*/
def apply(
aclCheck: AclCheck,
resolvers: Resolvers,
resources: Resources,
rcr: RemoteContextResolution
rcr: RemoteContextResolution,
fetchResource: FetchResource
): ResolverContextResolution =
apply(rcr, ResourceResolution.dataResource(aclCheck, resolvers, resources, excludeDeprecated = false))
apply(rcr, ResourceResolution.dataResource(aclCheck, resolvers, fetchResource, excludeDeprecated = false))

/**
* A [[ResolverContextResolution]] that never resolves
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ package ch.epfl.bluebrain.nexus.delta.sdk.resolvers

import cats.effect.IO
import cats.implicits._

import ch.epfl.bluebrain.nexus.delta.kernel.search.Pagination
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclCheck
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.jsonld.JsonLdContent
import ch.epfl.bluebrain.nexus.delta.sdk.model.Fetch.Fetch
import ch.epfl.bluebrain.nexus.delta.sdk.model.ResourceF
import ch.epfl.bluebrain.nexus.delta.sdk.model.search.ResultEntry
import ch.epfl.bluebrain.nexus.delta.sdk.model.search.SearchParams.ResolverSearchParams
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverResolution.{DeprecationCheck, Fetch, ResolverResolutionResult}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverResolution.{DeprecationCheck, ResolverResolutionResult}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.IdentityResolution.{ProvidedIdentities, UseCurrentCaller}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.Resolver.{CrossProjectResolver, InProjectResolver}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverResolutionRejection._
Expand Down Expand Up @@ -227,10 +227,6 @@ object ResolverResolution {
*/
type ResourceResolution[R] = ResolverResolution[ResourceF[R]]

type Fetch[R] = IO[Option[R]]

type FetchResource[R] = IO[Option[ResourceF[R]]]

type ResolverResolutionResult[R] = (ResolverReport, Option[R])

private val resolverSearchParams = ResolverSearchParams(deprecated = Some(false), filter = _ => IO.pure(true))
Expand Down
Loading

0 comments on commit f6986f9

Please sign in to comment.