Skip to content

Commit

Permalink
Remove tags from state, reject lookup by tag
Browse files Browse the repository at this point in the history
  • Loading branch information
dantb committed Jan 19, 2024
1 parent 0590852 commit 00941e3
Show file tree
Hide file tree
Showing 20 changed files with 39 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
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
import ch.epfl.bluebrain.nexus.delta.sourcing.ScopedEntityDefinition.Tagger
import ch.epfl.bluebrain.nexus.delta.sourcing._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{EntityType, ProjectRef}
Expand Down Expand Up @@ -233,10 +232,8 @@ final class Storages private (
notFound = StorageNotFound(iri, project)
state <- id match {
case Latest(_) => log.stateOr(project, iri, notFound)
case Revision(_, rev) =>
log.stateOr(project, iri, rev, notFound, RevisionNotFound)
case Tag(_, tag) =>
log.stateOr(project, iri, tag, notFound, TagNotFound(tag))
case Revision(_, rev) => log.stateOr(project, iri, rev, notFound, RevisionNotFound)
case t: Tag => IO.raiseError(FetchByTagNotSupported(t))
}
} yield state.toResource
}.span("fetchStorage")
Expand Down Expand Up @@ -325,7 +322,6 @@ object Storages {
e.project,
e.value,
e.source,
Tags.empty,
e.rev,
deprecated = false,
e.instant,
Expand All @@ -339,10 +335,6 @@ object Storages {
s.copy(rev = e.rev, value = e.value, source = e.source, updatedAt = e.instant, updatedBy = e.subject)
}

def tagAdded(e: StorageTagAdded): Option[StorageState] = state.map { s =>
s.copy(rev = e.rev, tags = s.tags + (e.tag -> e.targetRev), updatedAt = e.instant, updatedBy = e.subject)
}

def deprecated(e: StorageDeprecated): Option[StorageState] = state.map { s =>
s.copy(rev = e.rev, deprecated = true, updatedAt = e.instant, updatedBy = e.subject)
}
Expand All @@ -354,7 +346,7 @@ object Storages {
event match {
case e: StorageCreated => created(e)
case e: StorageUpdated => updated(e)
case e: StorageTagAdded => tagAdded(e)
case _: StorageTagAdded => None
case e: StorageDeprecated => deprecated(e)
case e: StorageUndeprecated => undeprecated(e)
}
Expand Down Expand Up @@ -465,21 +457,11 @@ object Storages {
fetchPermissions: IO[Set[Permission]],
clock: Clock[IO]
): ScopedEntityDefinition[Iri, StorageState, StorageCommand, StorageEvent, StorageRejection] =
ScopedEntityDefinition(
ScopedEntityDefinition.untagged(
entityType,
StateMachine(None, evaluate(access, fetchPermissions, config, clock)(_, _), next),
StorageEvent.serializer,
StorageState.serializer,
Tagger[StorageEvent](
{
case r: StorageTagAdded => Some(r.tag -> r.targetRev)
case _ => None
},
{ _ =>
None
}
),
_ => None,
onUniqueViolation = (id: Iri, c: StorageCommand) =>
c match {
case c: CreateStorage => ResourceAlreadyExists(id, c.project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.ContextValue
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.encoder.JsonLdEncoder
import ch.epfl.bluebrain.nexus.delta.sdk.jsonld.JsonLdContent
import ch.epfl.bluebrain.nexus.delta.sdk.model.{BaseUri, IdSegmentRef, Tags}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{BaseUri, IdSegmentRef}
import ch.epfl.bluebrain.nexus.delta.sdk.{OrderingFields, ResourceShift}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import io.circe.syntax._
Expand All @@ -35,12 +35,6 @@ sealed trait Storage extends Product with Serializable {
*/
def project: ProjectRef

/**
* @return
* the tag -> rev mapping
*/
def tags: Tags

/**
* @return
* the original json document provided at creation or update
Expand Down Expand Up @@ -77,7 +71,6 @@ object Storage {
id: Iri,
project: ProjectRef,
value: DiskStorageValue,
tags: Tags,
source: Json
) extends Storage {
override val default: Boolean = value.default
Expand All @@ -97,7 +90,6 @@ object Storage {
id: Iri,
project: ProjectRef,
value: S3StorageValue,
tags: Tags,
source: Json
) extends Storage {

Expand All @@ -122,7 +114,6 @@ object Storage {
id: Iri,
project: ProjectRef,
value: RemoteDiskStorageValue,
tags: Tags,
source: Json
) extends Storage {
override val default: Boolean = value.default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import ch.epfl.bluebrain.nexus.delta.rdf.{RdfError, Vocabulary}
import ch.epfl.bluebrain.nexus.delta.sdk.jsonld.JsonLdRejection
import ch.epfl.bluebrain.nexus.delta.sdk.jsonld.JsonLdRejection.UnexpectedId
import ch.epfl.bluebrain.nexus.delta.sdk.marshalling.HttpResponseFields
import ch.epfl.bluebrain.nexus.delta.sdk.model.IdSegmentRef
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContext.ContextRejection
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Tag.UserTag
import io.circe.syntax._
import io.circe.{Encoder, JsonObject}

Expand Down Expand Up @@ -47,14 +47,10 @@ object StorageRejection {
final case class RevisionNotFound(provided: Int, current: Int)
extends StorageFetchRejection(s"Revision requested '$provided' not found, last known revision is '$current'.")

/**
* Rejection returned when a subject intends to retrieve a storage at a specific tag, but the provided tag does not
* exist.
*
* @param tag
* the provided tag
*/
final case class TagNotFound(tag: UserTag) extends StorageFetchRejection(s"Tag requested '$tag' not found.")
final case class FetchByTagNotSupported(tag: IdSegmentRef.Tag)
extends StorageFetchRejection(
s"Fetching storages by tag is no longer supported. Id ${tag.value.asString} and tag ${tag.tag.value}"
)

/**
* Rejection returned when attempting to update/fetch a storage with an id that doesn't exist.
Expand Down Expand Up @@ -235,12 +231,12 @@ object StorageRejection {
implicit final val storageRejectionHttpResponseFields: HttpResponseFields[StorageRejection] =
HttpResponseFields {
case RevisionNotFound(_, _) => StatusCodes.NotFound
case TagNotFound(_) => StatusCodes.NotFound
case StorageNotFound(_, _) => StatusCodes.NotFound
case DefaultStorageNotFound(_) => StatusCodes.NotFound
case ResourceAlreadyExists(_, _) => StatusCodes.Conflict
case IncorrectRev(_, _) => StatusCodes.Conflict
case ProjectContextRejection(rej) => rej.status
case FetchByTagNotSupported(_) => StatusCodes.BadRequest
case StorageNotAccessible(_, _) => StatusCodes.BadRequest
case _ => StatusCodes.BadRequest
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.Storage.{Dis
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageValue.{DiskStorageValue, RemoteDiskStorageValue, S3StorageValue}
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.{schemas, StorageResource}
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.sdk.model.{ResourceF, ResourceUris, Tags}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{ResourceF, ResourceUris}
import ch.epfl.bluebrain.nexus.delta.sourcing.Serializer
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ResourceRef.Latest
Expand Down Expand Up @@ -48,7 +48,6 @@ final case class StorageState(
project: ProjectRef,
value: StorageValue,
source: Json,
tags: Tags,
rev: Int,
deprecated: Boolean,
createdAt: Instant,
Expand All @@ -63,9 +62,9 @@ final case class StorageState(

def storage: Storage =
value match {
case value: DiskStorageValue => DiskStorage(id, project, value, tags, source)
case value: S3StorageValue => S3Storage(id, project, value, tags, source)
case value: RemoteDiskStorageValue => RemoteDiskStorage(id, project, value, tags, source)
case value: DiskStorageValue => DiskStorage(id, project, value, source)
case value: S3StorageValue => S3Storage(id, project, value, source)
case value: RemoteDiskStorageValue => RemoteDiskStorage(id, project, value, source)
}

def toResource: StorageResource =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,22 +162,6 @@ final class StoragesRoutes(
}
}
},
(pathPrefix("tags") & pathEndOrSingleSlash) {
operationName(s"$prefixSegment/storages/{org}/{project}/{id}/tags") {
concat(
// Fetch a storage tags
(get & idSegmentRef(id) & authorizeFor(project, Read)) { id =>
emit(
storages
.fetch(id, project)
.map(_.value.tags)
.attemptNarrow[StorageRejection]
.rejectOn[StorageNotFound]
)
}
)
}
},
(pathPrefix("statistics") & get & pathEndOrSingleSlash) {
authorizeFor(project, Read).apply {
emit(storagesStatistics.get(id, project).attemptNarrow[StorageRejection])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
"capacity": 1000,
"maxFileSize": 50
},
"tags": {
"mytag": 3
},
"createdAt": "1970-01-01T00:00:00Z",
"createdBy": {
"subject": "username",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
"writePermission": "remote/write",
"maxFileSize": 52
},
"tags": {
"mytag": 3
},
"createdAt": "1970-01-01T00:00:00Z",
"createdBy": {
"subject": "username",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
"writePermission": "s3/write",
"maxFileSize": 51
},
"tags": {
"mytag": 3
},
"createdAt": "1970-01-01T00:00:00Z",
"createdBy": {
"subject": "username",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.AclAddress
import ch.epfl.bluebrain.nexus.delta.sdk.acls.{AclCheck, AclSimpleCheck}
import ch.epfl.bluebrain.nexus.delta.sdk.error.ServiceError.AuthorizationFailed
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegment, IdSegmentRef, Tags}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegment, IdSegmentRef}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.User
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{ProjectRef, ResourceRef}
import ch.epfl.bluebrain.nexus.testkit.Generators
Expand Down Expand Up @@ -239,16 +239,16 @@ class BatchCopySuite extends NexusSuite with StorageFixtures with Generators wit

private def genDiskStorageWithCapacity(capacity: Long) = {
val limitedDiskVal = diskVal.copy(capacity = Some(capacity))
DiskStorage(nxv + genString(), genProject().ref, limitedDiskVal, Tags.empty, json"""{"disk": "value"}""")
DiskStorage(nxv + genString(), genProject().ref, limitedDiskVal, json"""{"disk": "value"}""")
}

private def genDiskStorage() = genDiskStorageWithCapacity(1000L)

private def genRemoteStorage() =
RemoteDiskStorage(nxv + genString(), genProject().ref, remoteVal, Tags.empty, json"""{"disk": "value"}""")
RemoteDiskStorage(nxv + genString(), genProject().ref, remoteVal, json"""{"disk": "value"}""")

private def genS3Storage() =
S3Storage(nxv + genString(), genProject().ref, s3Val, Tags.empty, json"""{"disk": "value"}""")
S3Storage(nxv + genString(), genProject().ref, s3Val, json"""{"disk": "value"}""")
}

object BatchCopySuite {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages

import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.{StorageState, StorageValue}
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.sdk.model.Tags
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Subject}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import io.circe.Json
Expand All @@ -18,7 +17,6 @@ object StorageGen {
source: Json = Json.obj(),
rev: Int = 1,
deprecated: Boolean = false,
tags: Tags = Tags.empty,
createdBy: Subject = Anonymous,
updatedBy: Subject = Anonymous
): StorageState = {
Expand All @@ -27,7 +25,6 @@ object StorageGen {
project,
value,
source,
tags,
rev,
deprecated,
Instant.EPOCH,
Expand All @@ -44,10 +41,9 @@ object StorageGen {
source: Json = Json.obj(),
rev: Int = 1,
deprecated: Boolean = false,
tags: Tags = Tags.empty,
createdBy: Subject = Anonymous,
updatedBy: Subject = Anonymous
): StorageResource =
storageState(id, project, value, source, rev, deprecated, tags, createdBy, updatedBy).toResource
storageState(id, project, value, source, rev, deprecated, createdBy, updatedBy).toResource

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.ConfigFixtures
import ch.epfl.bluebrain.nexus.delta.sdk.generators.ProjectGen
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.{Caller, ServiceAccount}
import ch.epfl.bluebrain.nexus.delta.sdk.implicits._
import ch.epfl.bluebrain.nexus.delta.sdk.model.{IdSegmentRef, Tags}
import ch.epfl.bluebrain.nexus.delta.sdk.model.IdSegmentRef
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContextDummy
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Authenticated, Group, User}
Expand Down Expand Up @@ -232,8 +232,7 @@ private class StoragesSpec
remoteFieldsJson,
rev = 2,
createdBy = bob,
updatedBy = bob,
tags = Tags(tag -> 1)
updatedBy = bob
)

"succeed" in {
Expand All @@ -249,9 +248,9 @@ private class StoragesSpec
storages.fetch(IdSegmentRef(rdId, 1), projectRef).accepted shouldEqual resourceRev1
}

"reject if tag does not exist" in {
val otherTag = UserTag.unsafe("other")
storages.fetch(IdSegmentRef(rdId, otherTag), projectRef).rejected shouldEqual TagNotFound(otherTag)
"reject fetch by tag" in {
val id = IdSegmentRef.Tag(rdId, UserTag.unsafe("other"))
storages.fetch(id, projectRef).rejected shouldEqual FetchByTagNotSupported(id)
}

"reject if revision does not exist" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageRejec
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageType.{DiskStorage => DiskStorageType}
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageValue.{DiskStorageValue, RemoteDiskStorageValue, S3StorageValue}
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.{AbsolutePath, DigestAlgorithm}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{BaseUri, Tags}
import ch.epfl.bluebrain.nexus.delta.sdk.model.BaseUri
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.User
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Tag.UserTag
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{Label, ProjectRef}
import ch.epfl.bluebrain.nexus.testkit.scalatest.ce.CatsEffectSpec
import io.circe.Json
Expand Down Expand Up @@ -280,18 +279,6 @@ class StoragesStmSpec extends CatsEffectSpec with StorageFixtures {
current.copy(rev = 2, value = diskVal, source = diskFieldsJson, updatedAt = time2, updatedBy = alice)
}

"from a new StorageTagAdded event" in {
val tag1 = UserTag.unsafe("tag1")
val tag2 = UserTag.unsafe("tag2")
val event = StorageTagAdded(dId, project, DiskStorageType, 1, tag2, 3, time2, alice)
val current = storageState(dId, project, diskVal, tags = Tags(tag1 -> 2), rev = 2)

next(None, event) shouldEqual None

next(Some(current), event).value shouldEqual
current.copy(rev = 3, updatedAt = time2, updatedBy = alice, tags = Tags(tag1 -> 2, tag2 -> 1))
}

"from a new StorageDeprecated event" in {
val event = StorageDeprecated(dId, project, DiskStorageType, 2, time2, alice)
val current = storageState(dId, project, diskVal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ package ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model

import ch.epfl.bluebrain.nexus.delta.kernel.utils.ClassUtils
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.StorageFixtures
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageEvent.{StorageCreated, StorageDeprecated, StorageTagAdded, StorageUndeprecated, StorageUpdated}
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageEvent._
import ch.epfl.bluebrain.nexus.delta.plugins.storage.storages.model.StorageType.{DiskStorage => DiskStorageType}
import ch.epfl.bluebrain.nexus.delta.sdk.SerializationSuite
import ch.epfl.bluebrain.nexus.delta.sdk.model.Tags
import ch.epfl.bluebrain.nexus.delta.sdk.model.metrics.EventMetric._
import ch.epfl.bluebrain.nexus.delta.sdk.sse.SseEncoder.SseData
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Subject, User}
Expand Down Expand Up @@ -94,7 +93,6 @@ class StorageSerializationSuite extends SerializationSuite with StorageFixtures
projectRef,
value,
source,
Tags(UserTag.unsafe("mytag") -> 3),
rev = 1,
deprecated = false,
createdAt = instant,
Expand Down
Loading

0 comments on commit 00941e3

Please sign in to comment.