Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not index schemas anymore #5287

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ final class ResolversRoutes(
val authorizeRead = authorizeFor(project, Read)
val authorizeWrite = authorizeFor(project, Write)
concat(
// List resolvers
pathEndOrSingleSlash {
(get & authorizeRead) {
implicit val searchJsonLdEncoder: JsonLdEncoder[SearchResults[ResolverResource]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import ch.epfl.bluebrain.nexus.delta.sdk.identities.Identities
import ch.epfl.bluebrain.nexus.delta.sdk.implicits._
import ch.epfl.bluebrain.nexus.delta.sdk.marshalling.{OriginalSource, RdfMarshalling}
import ch.epfl.bluebrain.nexus.delta.sdk.model.routes.Tag
import ch.epfl.bluebrain.nexus.delta.sdk.model.search.SearchResults
import ch.epfl.bluebrain.nexus.delta.sdk.model.search.SearchResults.searchResultsJsonLdEncoder
import ch.epfl.bluebrain.nexus.delta.sdk.model.{BaseUri, ResourceF}
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions.schemas.{read => Read, write => Write}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.Schemas
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.SchemaRejection
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.SchemaRejection.SchemaNotFound
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.{Schema, SchemaRejection}
import io.circe.Json

/**
Expand All @@ -38,15 +40,12 @@ import io.circe.Json
* the schemas module
* @param schemeDirectives
* directives related to orgs and projects
* @param indexAction
* the indexing action on write operations
*/
final class SchemasRoutes(
identities: Identities,
aclCheck: AclCheck,
schemas: Schemas,
schemeDirectives: DeltaSchemeDirectives,
indexAction: IndexingAction.Execute[Schema]
schemeDirectives: DeltaSchemeDirectives
)(implicit
baseUri: BaseUri,
cr: RemoteContextResolution,
Expand All @@ -72,13 +71,12 @@ final class SchemasRoutes(
private def emitMetadataOrReject(io: IO[SchemaResource]): Route =
emit(io.map(_.void).attemptNarrow[SchemaRejection].rejectOn[SchemaNotFound])

private def emitSource(io: IO[SchemaResource], annotate: Boolean): Route = {
private def emitSource(io: IO[SchemaResource], annotate: Boolean): Route =
emit(
io.map { resource => OriginalSource(resource, resource.value.source, annotate) }
.attemptNarrow[SchemaRejection]
.rejectOn[SchemaNotFound]
)
}

private def emitTags(io: IO[SchemaResource]): Route =
emit(io.map(_.value.tags).attemptNarrow[SchemaRejection].rejectOn[SchemaNotFound])
Expand All @@ -87,13 +85,22 @@ final class SchemasRoutes(
(baseUriPrefix(baseUri.prefix) & replaceUri("schemas", shacl)) {
pathPrefix("schemas") {
extractCaller { implicit caller =>
(projectRef & indexingMode) { (ref, mode) =>
def index(schema: SchemaResource): IO[Unit] = indexAction(schema.value.project, schema, mode)
projectRef { project =>
val authorizeRead = authorizeFor(project, Read)
val authorizeWrite = authorizeFor(project, Write)
concat(
// List schemas
pathEndOrSingleSlash {
(get & authorizeRead) {
implicit val searchJsonLdEncoder: JsonLdEncoder[SearchResults[ResourceF[Unit]]] =
searchResultsJsonLdEncoder(ContextValue.empty)
emit(schemas.list(project).map(_.map(_.void)).widen[SearchResults[ResourceF[Unit]]])
}
},
// Create a schema without id segment
(pathEndOrSingleSlash & post & noParameter("rev") & entity(as[Json])) { source =>
authorizeFor(ref, Write).apply {
emitMetadata(Created, schemas.create(ref, source).flatTap(index))
authorizeWrite {
emitMetadata(Created, schemas.create(project, source))
}
},
idSegment { id =>
Expand All @@ -102,75 +109,69 @@ final class SchemasRoutes(
concat(
// Create or update a schema
put {
authorizeFor(ref, Write).apply {
authorizeWrite {
(parameter("rev".as[Int].?) & entity(as[Json])) {
case (None, source) =>
// Create a schema with id segment
emitMetadata(Created, schemas.create(id, ref, source).flatTap(index))
emitMetadata(Created, schemas.create(id, project, source))
case (Some(rev), source) =>
// Update a schema
emitMetadata(schemas.update(id, ref, rev, source).flatTap(index))
emitMetadata(schemas.update(id, project, rev, source))
}
}
},
// Deprecate a schema
(delete & parameter("rev".as[Int])) { rev =>
authorizeFor(ref, Write).apply {
emitMetadataOrReject(schemas.deprecate(id, ref, rev).flatTap(index))
authorizeWrite {
emitMetadataOrReject(schemas.deprecate(id, project, rev))
}
},
// Fetch a schema
(get & idSegmentRef(id)) { id =>
emitOrFusionRedirect(
ref,
project,
id,
authorizeFor(ref, Read).apply {
emitFetch(schemas.fetch(id, ref))
authorizeRead {
emitFetch(schemas.fetch(id, project))
}
)
}
)
},
(pathPrefix("undeprecate") & put & pathEndOrSingleSlash & parameter("rev".as[Int])) { rev =>
authorizeFor(ref, Write).apply {
emitMetadataOrReject(schemas.undeprecate(id, ref, rev).flatTap(index))
authorizeWrite {
emitMetadataOrReject(schemas.undeprecate(id, project, rev))
}
},
(pathPrefix("refresh") & put & pathEndOrSingleSlash) {
authorizeFor(ref, Write).apply {
emitMetadata(schemas.refresh(id, ref).flatTap(index))
authorizeWrite {
emitMetadata(schemas.refresh(id, project))
}
},
// Fetch a schema original source
(pathPrefix("source") & get & pathEndOrSingleSlash & idSegmentRef(id) & annotateSource) {
(id, annotate) =>
authorizeFor(ref, Read).apply {
emitSource(schemas.fetch(id, ref), annotate)
authorizeRead {
emitSource(schemas.fetch(id, project), annotate)
}
},
pathPrefix("tags") {
concat(
// Fetch a schema tags
(get & idSegmentRef(id) & pathEndOrSingleSlash & authorizeFor(ref, Read)) { id =>
emitTags(schemas.fetch(id, ref))
(get & idSegmentRef(id) & pathEndOrSingleSlash & authorizeRead) { id =>
emitTags(schemas.fetch(id, project))
},
// Tag a schema
(post & parameter("rev".as[Int]) & pathEndOrSingleSlash) { rev =>
authorizeFor(ref, Write).apply {
authorizeWrite {
entity(as[Tag]) { case Tag(tagRev, tag) =>
emitMetadata(
Created,
schemas.tag(id, ref, tag, tagRev, rev).flatTap(index)
)
emitMetadata(Created, schemas.tag(id, project, tag, tagRev, rev))
}
}
},
// Delete a tag
(tagLabel & delete & parameter("rev".as[Int]) & pathEndOrSingleSlash & authorizeFor(
ref,
Write
)) { (tag, rev) =>
emitMetadataOrReject(schemas.deleteTag(id, ref, tag, rev).flatTap(index))
(tagLabel & delete & parameter("rev".as[Int]) & pathEndOrSingleSlash & authorizeWrite) {
(tag, rev) => emitMetadataOrReject(schemas.deleteTag(id, project, tag, rev))
}
)
}
Expand All @@ -193,13 +194,12 @@ object SchemasRoutes {
identities: Identities,
aclCheck: AclCheck,
schemas: Schemas,
schemeDirectives: DeltaSchemeDirectives,
index: IndexingAction.Execute[Schema]
schemeDirectives: DeltaSchemeDirectives
)(implicit
baseUri: BaseUri,
cr: RemoteContextResolution,
ordering: JsonKeyOrdering,
fusionConfig: FusionConfig
): Route = new SchemasRoutes(identities, aclCheck, schemas, schemeDirectives, index).routes
): Route = new SchemasRoutes(identities, aclCheck, schemas, schemeDirectives).routes

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ 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._
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverEvent
import ch.epfl.bluebrain.nexus.delta.sdk.resources.FetchResource
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.FetchSchema
import ch.epfl.bluebrain.nexus.delta.sdk.sse.SseEncoder
import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors
import izumi.distage.model.definition.{Id, ModuleDef}
Expand Down Expand Up @@ -51,14 +53,18 @@ object ResolversModule extends ModuleDef {

make[MultiResolution].from {
(
aclCheck: AclCheck,
fetchContext: FetchContext,
aclCheck: AclCheck,
resolvers: Resolvers,
shifts: ResourceShifts
fetchResource: FetchResource,
fetchSchema: FetchSchema
) =>
MultiResolution(
fetchContext,
ResolverResolution(aclCheck, resolvers, shifts, excludeDeprecated = false)
aclCheck,
resolvers,
fetchResource,
fetchSchema
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@ import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.{ContextValue, RemoteCon
import ch.epfl.bluebrain.nexus.delta.rdf.shacl.ValidateShacl
import ch.epfl.bluebrain.nexus.delta.rdf.utils.JsonKeyOrdering
import ch.epfl.bluebrain.nexus.delta.routes.{SchemaJobRoutes, SchemasRoutes}
import ch.epfl.bluebrain.nexus.delta.sdk.IndexingAction.AggregateIndexingAction
import ch.epfl.bluebrain.nexus.delta.sdk._
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclCheck
import ch.epfl.bluebrain.nexus.delta.sdk.directives.DeltaSchemeDirectives
import ch.epfl.bluebrain.nexus.delta.sdk.fusion.FusionConfig
import ch.epfl.bluebrain.nexus.delta.sdk.identities.Identities
import ch.epfl.bluebrain.nexus.delta.sdk.model._
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.{FetchResource, Resources, ValidateResource}
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.job.{SchemaValidationCoordinator, SchemaValidationStream}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.{Schema, SchemaEvent}
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.SchemaEvent
import ch.epfl.bluebrain.nexus.delta.sdk.sse.SseEncoder
import ch.epfl.bluebrain.nexus.delta.sourcing.projections.{ProjectionErrors, Projections}
import ch.epfl.bluebrain.nexus.delta.sourcing.stream.Supervisor
Expand Down Expand Up @@ -104,14 +102,12 @@ object SchemasModule extends ModuleDef {
aclCheck: AclCheck,
schemas: Schemas,
schemeDirectives: DeltaSchemeDirectives,
indexingAction: AggregateIndexingAction,
shift: Schema.Shift,
baseUri: BaseUri,
cr: RemoteContextResolution @Id("aggregate"),
ordering: JsonKeyOrdering,
fusionConfig: FusionConfig
) =>
new SchemasRoutes(identities, aclCheck, schemas, schemeDirectives, indexingAction(_, _, _)(shift))(
new SchemasRoutes(identities, aclCheck, schemas, schemeDirectives)(
baseUri,
cr,
ordering,
Expand Down Expand Up @@ -147,12 +143,8 @@ object SchemasModule extends ModuleDef {

many[SseEncoder[_]].add { base: BaseUri => SchemaEvent.sseEncoder(base) }

many[ScopedEventMetricEncoder[_]].add { SchemaEvent.schemaEventMetricEncoder }

many[ApiMappings].add(Schemas.mappings)

many[ResourceToSchemaMappings].add(Schemas.resourcesToSchemas)

many[MetadataContextValue].addEffect(MetadataContextValue.fromFile("contexts/schemas-metadata.json"))

many[RemoteContextResolution].addEffect(
Expand All @@ -172,10 +164,4 @@ object SchemasModule extends ModuleDef {
many[PriorityRoute].add { (route: SchemaJobRoutes) =>
PriorityRoute(pluginsMaxPriority + 8, route.routes, requiresStrictEntity = true)
}

make[Schema.Shift].from { (schemas: Schemas, base: BaseUri) =>
Schema.shift(schemas)(base)
}

many[ResourceShift[_, _, _]].ref[Schema.Shift]
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary
import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary.{contexts, nxv}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
import ch.epfl.bluebrain.nexus.delta.rdf.shacl.ValidateShacl
import ch.epfl.bluebrain.nexus.delta.sdk.IndexingAction
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclSimpleCheck
import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.AclAddress
import ch.epfl.bluebrain.nexus.delta.sdk.directives.DeltaSchemeDirectives
Expand Down Expand Up @@ -85,8 +84,7 @@ class SchemasRoutesSpec extends BaseRouteSpec with IOFromMap with CatsIOValues {
identities,
aclCheck,
SchemasImpl(schemaLog, fetchContext, schemaImports, resolverContextResolution),
groupDirectives,
IndexingAction.noop
groupDirectives
)
)

Expand Down Expand Up @@ -118,6 +116,19 @@ class SchemasRoutesSpec extends BaseRouteSpec with IOFromMap with CatsIOValues {
}
}

"fail to list schemas" in {
Get("/v1/schemas/myorg/myproject") ~> routes ~> check {
status shouldEqual StatusCodes.Forbidden
}
}

"list schemas in the project with the appropriate permission" in {
Get("/v1/schemas/myorg/myproject") ~> asReader ~> routes ~> check {
status shouldEqual StatusCodes.OK
response.asJson.asObject.value("_total").value shouldEqual Json.fromLong(2L)
}
}

"reject the creation of a schema which already exists" in {
Put("/v1/schemas/myorg/myproject/myid", payload.toEntity) ~> asWriter ~> routes ~> check {
status shouldEqual StatusCodes.Conflict
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package ch.epfl.bluebrain.nexus.delta.sdk.resolvers

import cats.effect.IO
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.{ExpandIri, JsonLdContent}
import ch.epfl.bluebrain.nexus.delta.sdk.model.Fetch.Fetch
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.projects.model.ProjectContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResolverRejection.{InvalidResolution, InvalidResolvedResourceId, InvalidResolverResolution}
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.ResourceResolutionReport.ResolverReport
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.model.{MultiResolutionResult, ResourceResolutionReport}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
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.schemas.FetchSchema
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.Schema
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{ProjectRef, ResourceRef}

/**
* Allow to attempt resolutions for the different resource types available
* Allow to attempt resolutions for data resources and schemas
* @param fetchProject
* how to fetch a project
* @param resourceResolution
Expand Down Expand Up @@ -81,6 +87,28 @@ final class MultiResolution(

object MultiResolution {

def apply(
fetchContext: FetchContext,
aclCheck: AclCheck,
resolvers: Resolvers,
fetchResource: FetchResource,
fetchSchema: FetchSchema
): MultiResolution = {
def combinedFetch(resourceRef: ResourceRef, project: ProjectRef): Fetch[JsonLdContent[_, _]] =
fetchResource.fetch(resourceRef, project).flatMap {
case Some(resource) => IO.some(Resource.toJsonLdContent(resource))
case None => fetchSchema.option(resourceRef, project).map(_.map(Schema.toJsonLdContent))
}

val combinedResolution = ResolverResolution(
aclCheck,
resolvers,
combinedFetch,
excludeDeprecated = false
)
apply(fetchContext, combinedResolution)
}

/**
* Create a multi resolution instance
* @param fetchContext
Expand Down
Loading