From bcdbe1e7d2f48731bf2f8e0fa3b2c045823add79 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 19 Aug 2024 15:07:37 +0200 Subject: [PATCH] Skip default composite views during import (#5109) * Skip default composite views during import --------- Co-authored-by: Simon Dumas --- .../ship/views/CompositeViewProcessor.scala | 49 ++++++++++++------- .../nexus/ship/ShipIntegrationSpec.scala | 45 ----------------- 2 files changed, 31 insertions(+), 63 deletions(-) diff --git a/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/views/CompositeViewProcessor.scala b/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/views/CompositeViewProcessor.scala index 297da2c06e..ee4e1172c5 100644 --- a/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/views/CompositeViewProcessor.scala +++ b/ship/src/main/scala/ch/epfl/bluebrain/nexus/ship/views/CompositeViewProcessor.scala @@ -6,6 +6,8 @@ import ch.epfl.bluebrain.nexus.delta.plugins.compositeviews.CompositeViews import ch.epfl.bluebrain.nexus.delta.plugins.compositeviews.model.CompositeViewEvent import ch.epfl.bluebrain.nexus.delta.plugins.compositeviews.model.CompositeViewEvent._ import ch.epfl.bluebrain.nexus.delta.plugins.compositeviews.model.CompositeViewRejection.{IncorrectRev, ResourceAlreadyExists} +import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri +import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary.nxv 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 @@ -14,7 +16,7 @@ import ch.epfl.bluebrain.nexus.delta.sourcing.Transactors import ch.epfl.bluebrain.nexus.delta.sourcing.config.EventLogConfig import ch.epfl.bluebrain.nexus.delta.sourcing.model.EntityType import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject -import ch.epfl.bluebrain.nexus.ship.views.CompositeViewProcessor.logger +import ch.epfl.bluebrain.nexus.ship.views.CompositeViewProcessor.{defaultViewId, logger} import ch.epfl.bluebrain.nexus.ship.{EventClock, EventProcessor, ImportStatus, ProjectMapper} import io.circe.Decoder @@ -38,30 +40,41 @@ class CompositeViewProcessor(views: UUID => IO[CompositeViews], projectMapper: P val cRev = event.rev - 1 val project = projectMapper.map(event.project) - event match { - case e: CompositeViewCreated => views(event.uuid).flatMap(_.create(project, e.source)) - case e: CompositeViewUpdated => views(event.uuid).flatMap(_.update(e.id, project, cRev, e.source)) - case e: CompositeViewDeprecated => views(event.uuid).flatMap(_.deprecate(e.id, project, cRev)) - case e: CompositeViewUndeprecated => views(event.uuid).flatMap(_.undeprecate(e.id, project, cRev)) - case _: CompositeViewTagAdded => IO.unit // TODO: Can/should we tag? + if (event.id == defaultViewId) { + logger + .info( + s"Skipping default search views, they are updated independently to avoid putting pressure on the system at unexpected times" + ) + .as(ImportStatus.Success) + } else { + val io = event match { + case e: CompositeViewCreated => views(event.uuid).flatMap(_.create(project, e.source)) + case e: CompositeViewUpdated => views(event.uuid).flatMap(_.update(e.id, project, cRev, e.source)) + case e: CompositeViewDeprecated => views(event.uuid).flatMap(_.deprecate(e.id, project, cRev)) + case e: CompositeViewUndeprecated => views(event.uuid).flatMap(_.undeprecate(e.id, project, cRev)) + case _: CompositeViewTagAdded => IO.unit // TODO: Can/should we tag? + } + io.redeemWith( + { + case a: ResourceAlreadyExists => logger.warn(a)("The resource already exists").as(ImportStatus.Dropped) + case i: IncorrectRev => + logger + .warn(i)(s"An incorrect revision has been provided for '${event.id}' in project '${event.project}'") + .as(ImportStatus.Dropped) + case other => IO.raiseError(other) + }, + _ => IO.pure(ImportStatus.Success) + ) } - }.redeemWith( - { - case a: ResourceAlreadyExists => logger.warn(a)("The resource already exists").as(ImportStatus.Dropped) - case i: IncorrectRev => - logger - .warn(i)(s"An incorrect revision has been provided for '${event.id}' in project '${event.project}'") - .as(ImportStatus.Dropped) - case other => IO.raiseError(other) - }, - _ => IO.pure(ImportStatus.Success) - ) + } } object CompositeViewProcessor { private val logger = Logger[CompositeViewProcessor] + private val defaultViewId: Iri = nxv + "searchView" + def apply( fetchContext: FetchContext, rcr: ResolverContextResolution, diff --git a/ship/src/test/scala/ch/epfl/bluebrain/nexus/ship/ShipIntegrationSpec.scala b/ship/src/test/scala/ch/epfl/bluebrain/nexus/ship/ShipIntegrationSpec.scala index f2e7df71b1..6d41615fde 100644 --- a/ship/src/test/scala/ch/epfl/bluebrain/nexus/ship/ShipIntegrationSpec.scala +++ b/ship/src/test/scala/ch/epfl/bluebrain/nexus/ship/ShipIntegrationSpec.scala @@ -185,29 +185,6 @@ class ShipIntegrationSpec extends BaseIntegrationSpec { thereShouldBeAView(project, bgView, patchedSource) } - "transfer a search view" in { - val (project, _, _) = thereIsAProject() - val (searchView, searchViewJson) = thereIsASearchView(project) - - whenTheExportIsRunOnProject(project) - theOldProjectIsDeleted(project) - - weRunTheImporter(project) - weFixThePermissions(project) - - thereShouldBeAViewIgnoringUUID(project, searchView, searchViewJson) - } - - def thereIsASearchView(project: ProjectRef): (Iri, Json) = { - val searchView = nxv + "searchView" - val encodedView = UrlUtils.encode(searchView.toString) - val (viewJson, status) = deltaClient - .getJsonAndStatus(s"/views/${project.organization}/${project.project}/$encodedView", writer) - .accepted - status shouldEqual StatusCodes.OK - searchView -> viewJson - } - def thereShouldBeAView(project: ProjectRef, view: Iri, expectedJson: Json): Assertion = { val encodedIri = UrlUtils.encode(view.toString) deltaClient @@ -220,28 +197,6 @@ class ShipIntegrationSpec extends BaseIntegrationSpec { .accepted } - def thereShouldBeAViewIgnoringUUID(project: ProjectRef, view: Iri, originalJson: Json): Assertion = { - val encodedIri = UrlUtils.encode(view.toString) - - import io.circe.optics.JsonPath.root - val ignoreSourceUUID = root.sources.each.at("_uuid").replace(None) - val ignoreProjectionUUID = root.projections.each.at("_uuid").replace(None) - val ignoreUUID = root.at("_uuid").replace(None) - - val filter = ignoreUUID andThen ignoreSourceUUID andThen ignoreProjectionUUID - - root.sources.`null` - - deltaClient - .get[Json](s"/views/${project.organization}/${project.project}/$encodedIri", writer) { (json, response) => - { - response.status shouldEqual StatusCodes.OK - filter(json) shouldEqual filter(originalJson) - } - } - .accepted - } - def thereIsABlazegraphView(project: ProjectRef): (Iri, Json) = { val simpleBgView = json"""{ "@type": "SparqlView",