Skip to content

Commit

Permalink
Correct Resource wiring
Browse files Browse the repository at this point in the history
  • Loading branch information
olivergrabinski committed Mar 21, 2024
1 parent 54cb8f6 commit 30dead3
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ object AclsModule extends ModuleDef {
permissions.fetchPermissionSet,
AclsImpl.findUnknownRealms(xas),
permissions.minimum,
config.acls,
config.acls.eventLog,
xas,
clock
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sdk.realms.Realms
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
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.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Label
import ch.epfl.bluebrain.nexus.delta.sourcing.state.GlobalStateStore
Expand Down Expand Up @@ -108,12 +109,12 @@ object AclsImpl {
fetchPermissionSet: IO[Set[Permission]],
findUnknownRealms: Set[Label] => IO[Unit],
minimum: Set[Permission],
config: AclsConfig,
config: EventLogConfig,
xas: Transactors,
clock: Clock[IO]
): Acls =
new AclsImpl(
GlobalEventLog(Acls.definition(fetchPermissionSet, findUnknownRealms, clock), config.eventLog, xas),
GlobalEventLog(Acls.definition(fetchPermissionSet, findUnknownRealms, clock), config, xas),
minimum
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class AclsImplSpec extends CatsEffectSpec with DoobieScalaTestFixture with Cance
IO.pure(minimumPermissions),
Acls.findUnknownRealms(_, Set(realm, realm2)),
minimumPermissions,
AclsConfig(eventLogConfig),
eventLogConfig,
xas,
clock
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class OrganizationDeleterSuite extends NexusSuite with ConfigFixtures with Proje
private val fields = ProjectFields(None, ApiMappings.empty, None, None)
private lazy val orgs = OrganizationsImpl(ScopeInitializer.noop, eventLogConfig, xas, clock)
private val permission = Permissions.resources.read
private lazy val acls = AclsImpl(IO.pure(Set(permission)), _ => IO.unit, Set(), aclsConfig, xas, clock)
private lazy val acls = AclsImpl(IO.pure(Set(permission)), _ => IO.unit, Set(), aclsConfig.eventLog, xas, clock)

implicit val subject: Subject = Identity.User("Bob", Label.unsafe("realm"))
implicit val uuidF: UUIDF = UUIDF.fixed(UUID.randomUUID())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package ch.epfl.bluebrain.nexus.delta.sdk.projects
import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.sdk.ConfigFixtures
import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.{Acl, AclAddress}
import ch.epfl.bluebrain.nexus.delta.sdk.acls.{Acls, AclsConfig, AclsImpl}
import ch.epfl.bluebrain.nexus.delta.sdk.acls.{Acls, AclsImpl}
import ch.epfl.bluebrain.nexus.delta.sdk.generators.{OrganizationGen, PermissionsGen, ProjectGen}
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.{Caller, ServiceAccount}
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions
Expand All @@ -22,7 +22,7 @@ class OwnerPermissionsScopeInitializationSpec extends CatsEffectSpec with Doobie
IO.pure(PermissionsGen.minimum),
Acls.findUnknownRealms(_, Set(saRealm, usersRealm)),
PermissionsGen.minimum,
AclsConfig(eventLogConfig),
eventLogConfig,
xas,
clock
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class EventClock(instant: Ref[IO, Instant]) extends Clock[IO] {

private def toDuration: IO[FiniteDuration] = instant.get.map { i =>
val seconds = FiniteDuration(i.getEpochSecond, TimeUnit.SECONDS)
val nanos = FiniteDuration(i.getNano, TimeUnit.NANOSECONDS)
val nanos = FiniteDuration(i.getNano, TimeUnit.NANOSECONDS)
seconds + nanos
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ch.epfl.bluebrain.nexus.ship.organizations.OrganizationProvider
import ch.epfl.bluebrain.nexus.ship.projects.ProjectProcessor
import ch.epfl.bluebrain.nexus.ship.resolvers.ResolverProcessor
import ch.epfl.bluebrain.nexus.ship.resources.ResourceProcessor
import ch.epfl.bluebrain.nexus.ship.schemas.SchemaOps
import fs2.Stream
import fs2.io.file.{Files, Path}
import io.circe.parser.decode
Expand Down Expand Up @@ -42,9 +43,10 @@ class RunShip {
_ <- orgProvider.create(config.organizations.values)
events = eventStream(file)
fetchActiveOrg = FetchActiveOrganization(xas)
fetchSchema <- SchemaOps.fetchSchema(config.eventLog, clock, xas)
projectProcessor <- ProjectProcessor(fetchActiveOrg, eventLogConfig, xas)(baseUri)
resolverProcessor <- ResolverProcessor(fetchContext, eventLogConfig, xas)
resourceProcessor <- ResourceProcessor(eventLogConfig, fetchContext, xas)
resourceProcessor <- ResourceProcessor(eventLogConfig, fetchContext, fetchSchema, xas)
report <- EventProcessor.run(events, projectProcessor, resolverProcessor, resourceProcessor)
} yield report
}
Expand Down
23 changes: 23 additions & 0 deletions ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/acls/AclOps.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ch.epfl.bluebrain.nexus.ship.acls

import cats.effect.{Clock, IO}
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclsImpl
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig

object AclOps {

def acls(config: EventLogConfig, clock: Clock[IO], xas: Transactors) = {
val permissionSet = Set(Permission.unsafe("resources/read"))
AclsImpl(
IO.pure(permissionSet),
AclsImpl.findUnknownRealms(xas),
permissionSet,
config,
xas,
clock
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ch.epfl.bluebrain.nexus.ship.resolvers

import cats.effect.IO
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, ResolversImpl}
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig

object ResolverOps {

def resolvers(fetchContext: FetchContext, config: EventLogConfig, clock: Clock[IO], xas: Transactors)(implicit
jsonLdApi: JsonLdApi,
uuidF: UUIDF
) =
ResolversImpl(
fetchContext,
// We rely on the parsed values and not on the original value
ResolverContextResolution.never,
config,
xas,
clock
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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.identities.model.Caller
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.Resolvers
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.IdentityResolution._
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverEvent._
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverRejection.{IncorrectRev, ResourceAlreadyExists}
Expand Down Expand Up @@ -81,14 +81,8 @@ object ResolverProcessor {
)(implicit api: JsonLdApi): IO[ResolverProcessor] =
EventClock.init().map { clock =>
implicit val uuidF: UUIDF = FailingUUID
val resolvers = ResolversImpl(
fetchContext,
// We rely on the parsed values and not on the original value
ResolverContextResolution.never,
config,
xas,
clock
)

val resolvers = ResolverOps.resolvers(fetchContext, config, clock, xas)
new ResolverProcessor(resolvers, clock)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ import cats.implicits.catsSyntaxOptionId
import ch.epfl.bluebrain.nexus.delta.kernel.Logger
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.rdf.jsonld.context.RemoteContextResolution
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.JsonLdAssembly
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegment, IdSegmentRef, ResourceF}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegment, IdSegmentRef}
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution
import ch.epfl.bluebrain.nexus.delta.sdk.resources.ValidationResult.NoValidation
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.{ResolverContextResolution, ResourceResolution}
import ch.epfl.bluebrain.nexus.delta.sdk.resources._
import ch.epfl.bluebrain.nexus.delta.sdk.resources.model.ResourceEvent
import ch.epfl.bluebrain.nexus.delta.sdk.resources.model.ResourceEvent._
import ch.epfl.bluebrain.nexus.delta.sdk.resources.model.ResourceRejection.{IncorrectRev, ResourceAlreadyExists}
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.schemas.FetchSchema
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{EntityType, ProjectRef, ResourceRef}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{EntityType, ResourceRef}
import ch.epfl.bluebrain.nexus.delta.sourcing.{ScopedEventLog, Transactors}
import ch.epfl.bluebrain.nexus.ship.acls.AclOps
import ch.epfl.bluebrain.nexus.ship.resolvers.ResolverOps
import ch.epfl.bluebrain.nexus.ship.resources.ResourceProcessor.logger
import ch.epfl.bluebrain.nexus.ship.{EventClock, EventProcessor, FailingUUID, ImportStatus}
import io.circe.Decoder
Expand Down Expand Up @@ -79,24 +81,25 @@ object ResourceProcessor {
private val logger = Logger[ResourceProcessor]

def apply(
eventLogConfig: EventLogConfig,
config: EventLogConfig,
fetchContext: FetchContext,
fetchSchema: FetchSchema,
xas: Transactors
)(implicit jsonLdApi: JsonLdApi): IO[ResourceProcessor] =
EventClock.init().map { clock =>
implicit val uuidF: UUIDF = FailingUUID

val detectChange = DetectChange(false)

val validate = new ValidateResource {
override def apply(jsonld: JsonLdAssembly, schema: SchemaClaim, enforceSchema: Boolean): IO[ValidationResult] =
IO.pure(NoValidation(ProjectRef.unsafe("org", "proj")))
override def apply(jsonld: JsonLdAssembly, schema: ResourceF[Schema]): IO[ValidationResult] =
IO.pure(NoValidation(ProjectRef.unsafe("org", "proj")))
}
val aclCheck = AclCheck(AclOps.acls(config, clock, xas))
val resolvers = ResolverOps.resolvers(fetchContext, config, clock, xas)
val resourceResolution =
ResourceResolution.schemaResource(aclCheck, resolvers, fetchSchema, excludeDeprecated = false)

val validate = ValidateResource(resourceResolution)(RemoteContextResolution.never)

val resourceDef = Resources.definition(validate, detectChange, clock)
val resourceLog = ScopedEventLog(resourceDef, eventLogConfig, xas)
val resourceLog = ScopedEventLog(resourceDef, config, xas)

val resources = ResourcesImpl(
resourceLog,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ch.epfl.bluebrain.nexus.ship.schemas

import cats.effect.{Clock, IO}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.JsonLdApi
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.RemoteContextResolution
import ch.epfl.bluebrain.nexus.delta.rdf.shacl.ShaclShapesGraph
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.Schemas.SchemaLog
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.{FetchSchema, Schemas, ValidateSchema}
import ch.epfl.bluebrain.nexus.delta.sourcing.{ScopedEventLog, Transactors}
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig

object SchemaOps {

def validateSchema(implicit api: JsonLdApi): IO[ValidateSchema] = {
val rcr = RemoteContextResolution.never
ShaclShapesGraph.shaclShaclShapes.map(ValidateSchema(api, _, rcr))
}

def schemaLog(config: EventLogConfig, clock: Clock[IO], xas: Transactors)(implicit api: JsonLdApi): IO[SchemaLog] =
for {
validate <- validateSchema
schemaDef = Schemas.definition(validate, clock)
} yield ScopedEventLog(schemaDef, config, xas)

def fetchSchema(config: EventLogConfig, clock: Clock[IO], xas: Transactors)(implicit
api: JsonLdApi
): IO[FetchSchema] =
for {
log <- schemaLog(config, clock, xas)
} yield FetchSchema(log)

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class EndToEndTest extends BaseIntegrationSpec {
}

"transfer a generic resource" in {
val (project, _) = thereIsAProject()
val (project, _) = thereIsAProject()
val (resource, resourceJson) = thereIsAResource(project)

whenTheExportIsRunOnProject(project)
Expand All @@ -70,7 +70,6 @@ class EndToEndTest extends BaseIntegrationSpec {
weRunTheImporter(project)
weFixThePermissions(project)

// TODO: This test currently fails because of the dummy ValidateResource implementation in ship
thereShouldBeAResource(project, resource, resourceJson)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ class HttpClient private (baseUrl: Uri, httpExt: HttpExt)(implicit
requestJson(GET, url, None, identity, (a: A, _: HttpResponse) => a, jsonHeaders)
}

def getJsonAndStatus(url: String, identity: Identity)(implicit um: FromEntityUnmarshaller[Json]): IO[(Json, StatusCode)] = {
def getJsonAndStatus(url: String, identity: Identity)(implicit
um: FromEntityUnmarshaller[Json]
): IO[(Json, StatusCode)] = {
requestJsonAndStatus(GET, url, None, identity, jsonHeaders)
}

Expand Down Expand Up @@ -266,12 +268,12 @@ class HttpClient private (baseUrl: Uri, httpExt: HttpExt)(implicit
}

def requestJsonAndStatus(
method: HttpMethod,
url: String,
body: Option[Json],
identity: Identity,
extraHeaders: Seq[HttpHeader]
)(implicit um: FromEntityUnmarshaller[Json]): IO[(Json, StatusCode)] =
method: HttpMethod,
url: String,
body: Option[Json],
identity: Identity,
extraHeaders: Seq[HttpHeader]
)(implicit um: FromEntityUnmarshaller[Json]): IO[(Json, StatusCode)] =
request[Json, Json, (Json, StatusCode)](
method,
url,
Expand Down

0 comments on commit 30dead3

Please sign in to comment.