Skip to content

Commit

Permalink
Allow disabling of resource validation in nexus ship (#4908)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivergrabinski authored Apr 26, 2024
1 parent 22805e6 commit fec5236
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 10 deletions.
3 changes: 3 additions & 0 deletions ship/src/main/resources/ship-default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ ship {
# The bucket to which the files will be copied by the Nexus Ship
target-bucket = "nexus-delta-production"

# If true, no resource validation is performed
disable-resource-validation = false

storages {

# S3 compatible storage configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ object RunShip {
remoteContextResolution <- ContextWiring.remoteContextResolution
validateShacl <- ValidateShacl(remoteContextResolution)
(schemaLog, fetchSchema) = SchemaWiring(config.eventLog, eventClock, xas)
(resourceLog, fetchResource) = ResourceWiring(fetchContext, fetchSchema, validateShacl, eventLogConfig, eventClock, xas)
(resourceLog, fetchResource) = ResourceWiring(fetchContext, fetchSchema, validateShacl, config, eventClock, xas)
rcr = ContextWiring.resolverContextResolution(fetchResource, fetchContext, remoteContextResolution, eventLogConfig, eventClock, xas)
schemaImports = SchemaWiring.schemaImports(fetchResource, fetchSchema, fetchContext, eventLogConfig, eventClock, xas)
// Processors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ final case class InputConfig(
serviceAccount: ServiceAccountConfig,
storages: StoragesConfig,
importBucket: BucketName,
targetBucket: BucketName
targetBucket: BucketName,
disableResourceValidation: Boolean
)

object InputConfig {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,90 @@
package ch.epfl.bluebrain.nexus.ship.resources

import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.JsonLdApi
import ch.epfl.bluebrain.nexus.delta.rdf.shacl.ValidateShacl
import ch.epfl.bluebrain.nexus.delta.rdf.shacl.{ValidateShacl, ValidationReport}
import ch.epfl.bluebrain.nexus.delta.sdk.jsonld.JsonLdAssembly
import ch.epfl.bluebrain.nexus.delta.sdk.model.ResourceF
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResourceResolution
import ch.epfl.bluebrain.nexus.delta.sdk.resources.Resources.ResourceLog
import ch.epfl.bluebrain.nexus.delta.sdk.resources.{DetectChange, FetchResource, Resources, ValidateResource}
import ch.epfl.bluebrain.nexus.delta.sdk.resources.SchemaClaim.DefinedSchemaClaim
import ch.epfl.bluebrain.nexus.delta.sdk.resources.ValidationResult.{NoValidation, Validated}
import ch.epfl.bluebrain.nexus.delta.sdk.resources._
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.FetchSchema
import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig
import ch.epfl.bluebrain.nexus.delta.sdk.schemas.model.Schema
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ResourceRef
import ch.epfl.bluebrain.nexus.delta.sourcing.{ScopedEventLog, Transactors}
import ch.epfl.bluebrain.nexus.ship.EventClock
import ch.epfl.bluebrain.nexus.ship.acls.AclWiring.alwaysAuthorize
import ch.epfl.bluebrain.nexus.ship.config.InputConfig
import ch.epfl.bluebrain.nexus.ship.resolvers.ResolverWiring
import io.circe.Json
import io.circe.syntax.KeyOps

object ResourceWiring {

def apply(
fetchContext: FetchContext,
fetchSchema: FetchSchema,
validateShacl: ValidateShacl,
config: EventLogConfig,
config: InputConfig,
clock: EventClock,
xas: Transactors
)(implicit
jsonLdApi: JsonLdApi
): (ResourceLog, FetchResource) = {
val detectChange = DetectChange(false)
val resolvers = ResolverWiring.resolvers(fetchContext, config, clock, xas)
val resolvers = ResolverWiring.resolvers(fetchContext, config.eventLog, clock, xas)
val resourceResolution =
ResourceResolution.schemaResource(alwaysAuthorize, resolvers, fetchSchema, excludeDeprecated = false)
val validate = ValidateResource(resourceResolution, validateShacl)
val resourceDef = Resources.definition(validate, detectChange, clock)

val log = ScopedEventLog(resourceDef, config, xas)
val validation = if (config.disableResourceValidation) alwaysValidateResource(fetchSchema) else validate
val resourceDef = Resources.definition(validation, detectChange, clock)

val log = ScopedEventLog(resourceDef, config.eventLog, xas)
(log, FetchResource(log))
}

private def alwaysValidateResource(fetchSchema: FetchSchema): ValidateResource = new ValidateResource {
val defaultReport: ValidationReport = ValidationReport(conforms = true, 5, Json.obj("conforms" := "true"))

override def apply(jsonld: JsonLdAssembly, schema: SchemaClaim, enforceSchema: Boolean): IO[ValidationResult] =
schema match {
case defined: DefinedSchemaClaim =>
fetchSchema.fetch(defined.schemaRef, schema.project).flatMap {
case Some(value) =>
IO.pure {
Validated(
schema.project,
ResourceRef.Revision(value.id, value.rev),
defaultReport
)
}
case None =>
IO.pure(
Validated(
schema.project,
ResourceRef.Revision(defined.schemaRef.iri, 1),
defaultReport
)
)
}
case other => IO.pure(NoValidation(other.project))
}

override def apply(
jsonld: JsonLdAssembly,
schema: ResourceF[Schema]
): IO[ValidationResult] =
IO.pure(
Validated(
schema.value.project,
ResourceRef.Revision(schema.id, schema.rev),
defaultReport
)
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ trait ShipConfigFixtures extends ConfigFixtures with StorageFixtures with Classp
serviceAccount,
StoragesConfig(eventLogConfig, pagination, config.copy(amazon = Some(amazonConfig))),
importBucket,
targetBucket
targetBucket,
disableResourceValidation = false
)

}

0 comments on commit fec5236

Please sign in to comment.