From 45ddbe7de7dd84c61f23332e1f15c110600d580e Mon Sep 17 00:00:00 2001 From: Emma <194498507+emmaicos@users.noreply.github.com> Date: Wed, 5 Mar 2025 13:00:28 +0100 Subject: [PATCH] Draft to compare with dates from file when deprecating --- .../meta/services/upload/UploadService.scala | 5 +- .../upload/validation/ScopedValidator.scala | 50 ++++++++++++++++--- .../upload/validation/UploadValidator.scala | 12 +++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/UploadService.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/UploadService.scala index 3e4eec51d..b81031fb9 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/UploadService.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/UploadService.scala @@ -155,8 +155,9 @@ class UploadService( }.toSeq.sortBy(sp => sp.id) def completeUpload(hash: Sha256Sum, info: UploadCompletionInfo)(using Envri): Future[Report] = - uploadLock.wrapFuture(hash): - completer.completeUpload(hash, info) + Future.fromTry(validator.validatePreviousTemporalCoverage(hash, info)).flatMap: _ => + uploadLock.wrapFuture(hash): + completer.completeUpload(hash, info) end UploadService diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/ScopedValidator.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/ScopedValidator.scala index 4a489b459..e435f357e 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/ScopedValidator.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/ScopedValidator.scala @@ -18,6 +18,10 @@ import java.net.URI import java.time.Instant import scala.language.strictEquality import scala.util.{Success, Try} +import se.lu.nateko.cp.meta.core.data.UploadCompletionInfo +import se.lu.nateko.cp.meta.core.data.TimeSeriesExtract +import se.lu.nateko.cp.meta.core.data.SpatialTimeSeriesExtract +import se.lu.nateko.cp.meta.core.data.TabularIngestionExtract private class ScopedValidator(vocab: CpVocab, val metaVocab: CpmetaVocab) extends CpmetaReader: @@ -132,9 +136,9 @@ private class ScopedValidator(vocab: CpVocab, val metaVocab: CpmetaVocab) extend .toIndexedSeq .nonEmpty - def compareToPreviousTemporalCoverage(dto: DataObjectDto)(using Envri, DocConn | DobjConn): Try[NotUsed] = + def compareToPreviousTemporalCoverage(dto: DataObjectDto)(using Envri, DobjConn): Try[NotUsed] = - val newIntervalIncludesPrevious = for + val compareInterval = for dataDto <- dto.asOptInstanceOf[DataObjectDto] timeSeries <- dataDto.specificInfo.fold(_ => None, ts => Some(ts)) newTimeInterval <- timeSeries.acquisitionInterval @@ -146,17 +150,47 @@ private class ScopedValidator(vocab: CpVocab, val metaVocab: CpmetaVocab) extend .toIndexedSeq allAquiredByIris = (autoDeprecateIris ++ selectedDeprecateIris).toSet .flatMap(getSingleUri(_, metaVocab.wasAcquiredBy).result) - previousStarts = allAquiredByIris.flatMap(getSingleInstant(_, metaVocab.prov.startedAtTime).result) - previousStops = allAquiredByIris.flatMap(getSingleInstant(_, metaVocab.prov.endedAtTime).result) + .toIndexedSeq + yield - (previousStarts.isEmpty || !newTimeInterval.start.isAfter(previousStarts.min)) - && (previousStops.isEmpty || !newTimeInterval.stop.isBefore(previousStops.max)) + compareToPreviousInterval(allAquiredByIris, newTimeInterval) - if newIntervalIncludesPrevious.getOrElse(true) then ok - else userFail("New temporal coverage must include temporal coverage of the objects being deprecated.") + compareInterval.getOrElse(ok) end compareToPreviousTemporalCoverage + def compareToPreviousTemporalCoverageByIri(iri: IRI, info: UploadCompletionInfo)(using Envri, DobjConn): Try[NotUsed] = + + val compareInterval = for + tabularExtract <- info.ingestionResult match + case Some(timeSeries: TimeSeriesExtract) => Some(timeSeries.tabular) + case Some(spatialTimeSeries: SpatialTimeSeriesExtract) => Some(spatialTimeSeries.tabular) + case Some(tabularIngestion: TabularIngestionExtract) => Some(tabularIngestion) + case _ => None + newTimeInterval = tabularExtract.interval + aquiredBy <- getSingleUri(iri, metaVocab.wasAcquiredBy).result + selectedDeprecateIris = getUriValues(iri, metaVocab.isNextVersionOf) + .toIndexedSeq + .flatMap(getSingleUri(_, metaVocab.wasAcquiredBy).result) + yield + compareToPreviousInterval(selectedDeprecateIris, newTimeInterval) + + compareInterval.getOrElse(ok) + + end compareToPreviousTemporalCoverageByIri + + private def compareToPreviousInterval(allAquiredByIris: Seq[IRI], newTimeInterval: TimeInterval)(using Envri, DobjConn): Try[NotUsed] = + val previousStarts = allAquiredByIris.flatMap(getSingleInstant(_, metaVocab.prov.startedAtTime).result) + val previousStops = allAquiredByIris.flatMap(getSingleInstant(_, metaVocab.prov.endedAtTime).result) + + val newIntervalIncludesPrevious = (previousStarts.isEmpty || !newTimeInterval.start.isAfter(previousStarts.min)) + && (previousStops.isEmpty || !newTimeInterval.stop.isBefore(previousStops.max)) + + if newIntervalIncludesPrevious then ok + else userFail("New temporal coverage must include temporal coverage of the objects being deprecated.") + + end compareToPreviousInterval + def growingIsGrowing( dto: ObjectUploadDto, diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala index 31288211f..d762c1048 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala @@ -20,6 +20,7 @@ import java.time.Instant import scala.collection.mutable.Buffer import scala.language.strictEquality import scala.util.{Failure, Success, Try} +import se.lu.nateko.cp.meta.core.data.UploadCompletionInfo given CanEqual[URI, URI] = CanEqual.derived given CanEqual[IRI, IRI] = CanEqual.derived @@ -45,6 +46,17 @@ class UploadValidator(servers: DataObjectInstanceServers): case doc: DocObjectDto => validateDoc(doc, uploader) yield dto + def validatePreviousTemporalCoverage(hash: Sha256Sum, info: UploadCompletionInfo)(using envri: Envri): Try[NotUsed] = + val objIri = vocab.getStaticObject(hash) + val validation = servers.vanillaGlobal.access: + for + given DobjConn <- metaReader.getLensForDataObj(objIri)(using envri, RdfLens.global) + yield + scoped.compareToPreviousTemporalCoverageByIri(objIri, info) + validation.toTry(new UploadUserErrorException(_)).flatten + + end validatePreviousTemporalCoverage + private def validateDobj(meta: DataObjectDto, uploader: UserId)(using Envri, DocConn): Try[DataObjectDto] = for