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

feat(api-v2): Accept custom timestamps in update/delete requests #1686

Merged
merged 11 commits into from Aug 14, 2020
5 changes: 5 additions & 0 deletions docs/03-apis/api-v2/editing-resources.md
Expand Up @@ -330,6 +330,11 @@ The request body is a JSON-LD object containing the following information about
The optional property `knora-api:deleteComment` specifies a comment to be attached to the
resource, explaining why it has been marked as deleted.

The optional property `knora-api:deleteDate`
(an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp))
indicates when the resource was marked as deleted; if not given, the current
time is used.

The response is a JSON-LD document containing the predicate `knora-api:result`
with a confirmation message.

Expand Down
14 changes: 11 additions & 3 deletions docs/03-apis/api-v2/editing-values.md
Expand Up @@ -83,8 +83,9 @@ Permissions for the new value can be given by adding `knora-api:hasPermissions`.
}
}
```

Each value can have an optional custom IRI (of [Knora IRI](knora-iris.md#iris-for-data) form) specified by the `@id` attribute, a custom creation date specified by adding
`knora-api:creationDate` (an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp)), or a custom UUID
`knora-api:valueCreationDate` (an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp)), or a custom UUID
given by `knora-api:valueHasUUID`. Each custom UUID must be [base64url-encoded](rfc:4648#section-5), without padding.
For example:

Expand All @@ -97,7 +98,7 @@ For example:
"@type" : "knora-api:IntValue",
"knora-api:intValueAsInt" : 21,
"knora-api:valueHasUUID" : "IN4R19yYR0ygi3K2VEHpUQ",
"knora-api:creationDate" : {
"knora-api:valueCreationDate" : {
"@type" : "xsd:dateTimeStamp",
"@value" : "2020-06-04T12:58:54.502951Z"
}
Expand All @@ -108,6 +109,7 @@ For example:
"xsd" : "http://www.w3.org/2001/XMLSchema#"
}
```

The format of the object of `knora-api:hasPermissions` is described in
[Permissions](../../02-knora-ontologies/knora-base.md#permissions).

Expand Down Expand Up @@ -386,6 +388,9 @@ To update only the permissions on a value, submit it with the new permissions an
To update a link, the user must have **modify permission** on the containing resource as
well as on the value.

To update a value and give it a custom timestamp, add
`knora-api:valueCreationDate` (an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp)).

The response is a JSON-LD document containing only `@id` and `@type`, returning the IRI
and type of the new value version.

Expand Down Expand Up @@ -431,7 +436,10 @@ the resource to the value, and the value's ID and type. For example:
```

The optional property `knora-api:deleteComment` specifies a comment to be attached to the
value, explaining why it has been marked as deleted.
value, explaining why it has been marked as deleted

The optional property `knora-api:deleteDate` (an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp))
specifies a custom timestamp indicating when the value was deleted. If not specified, the current time is used.å
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the Swedish character å do at the end of this line? :-D I actually like it giving knora a Scandinavian flavor. Did you know this single character means "a river"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I often find those "rivers" in my code, I think it happens when I accidentally press Option-A instead of Command-S. 😀


The response is a JSON-LD document containing the predicate `knora-api:result`
with a confirmation message.
624 changes: 313 additions & 311 deletions webapi/src/main/scala/org/knora/webapi/messages/util/JsonLDUtil.scala

Large diffs are not rendered by default.

Expand Up @@ -584,13 +584,12 @@ object CreateResourceRequestV2 extends KnoraJsonLDRequestReaderV2[CreateResource
OntologyConstants.KnoraApiV2Complex.CreationDate
)

valueFutures: Map[SmartIri, Seq[Future[CreateValueInNewResourceV2]]] = propertyIriStrs.map {
propertyValueFuturesMap: Map[SmartIri, Seq[Future[CreateValueInNewResourceV2]]] = propertyIriStrs.map {
propertyIriStr =>
val propertyIri: SmartIri = propertyIriStr.toSmartIriWithErr(throw BadRequestException(s"Invalid property IRI: <$propertyIriStr>"))

val valuesArray: JsonLDArray = jsonLDDocument.requireArray(propertyIriStr)

val propertyValues = valuesArray.value.map {
val valueFuturesSeq: Seq[Future[CreateValueInNewResourceV2]] = valuesArray.value.map {
valueJsonLD =>
val valueJsonLDObject = valueJsonLD match {
case jsonLDObject: JsonLDObject => jsonLDObject
Expand All @@ -606,15 +605,22 @@ object CreateResourceRequestV2 extends KnoraJsonLDRequestReaderV2[CreateResource
settings = settings,
log = log
)

maybeCustomValueIri: Option[SmartIri] = valueJsonLDObject.maybeIDAsKnoraDataIri
maybeCustomValueUUID: Option[UUID] = valueJsonLDObject.maybeUUID
maybeCustomValueUUID: Option[UUID] = valueJsonLDObject.maybeUUID(OntologyConstants.KnoraApiV2Complex.ValueHasUUID)

// Get the values's creation date.
// Get the value's creation date.
// TODO: creationDate for values is a bug, and will not be supported in future. Use valueCreationDate instead.
SepidehAlassi marked this conversation as resolved.
Show resolved Hide resolved
maybeCustomValueCreationDate: Option[Instant] = valueJsonLDObject.maybeDatatypeValueInObject(
key = OntologyConstants.KnoraApiV2Complex.ValueCreationDate,
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
validationFun = stringFormatter.xsdDateTimeStampToInstant
).orElse(valueJsonLDObject.maybeDatatypeValueInObject(
key = OntologyConstants.KnoraApiV2Complex.CreationDate,
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
validationFun = stringFormatter.xsdDateTimeStampToInstant
)
))

maybePermissions: Option[String] = valueJsonLDObject.maybeStringWithValidation(OntologyConstants.KnoraApiV2Complex.HasPermissions, stringFormatter.toSparqlEncodedString)
} yield CreateValueInNewResourceV2(
valueContent = valueContent,
Expand All @@ -625,23 +631,22 @@ object CreateResourceRequestV2 extends KnoraJsonLDRequestReaderV2[CreateResource
)
}

propertyIri -> propertyValues
propertyIri -> valueFuturesSeq
}.toMap

values: Map[SmartIri, Seq[CreateValueInNewResourceV2]] <- ActorUtil.sequenceSeqFuturesInMap(valueFutures)
propertyValuesMap: Map[SmartIri, Seq[CreateValueInNewResourceV2]] <- ActorUtil.sequenceSeqFuturesInMap(propertyValueFuturesMap)

// Get information about the project that the resource should be created in.
projectInfoResponse: ProjectGetResponseADM <- (responderManager ? ProjectGetRequestADM(
ProjectIdentifierADM(maybeIri = Some(projectIri.toString)),
requestingUser = requestingUser
)).mapTo[ProjectGetResponseADM]

} yield CreateResourceRequestV2(
createResource = CreateResourceV2(
resourceIri = maybeCustomResourceIri,
resourceClassIri = resourceClassIri,
label = label,
values = values,
values = propertyValuesMap,
projectADM = projectInfoResponse.project,
permissions = permissions,
creationDate = creationDate
Expand Down Expand Up @@ -751,12 +756,15 @@ object UpdateResourceMetadataRequestV2 extends KnoraJsonLDRequestReaderV2[Update
* @param resourceIri the IRI of the resource.
* @param resourceClassIri the IRI of the resource class.
* @param maybeDeleteComment a comment explaining why the resource is being marked as deleted.
* @param maybeDeleteDate a timestamp indicating when the resource was marked as deleted. If not supplied,
* the current time will be used.
* @param maybeLastModificationDate the resource's last modification date, if any.
* @param erase if `true`, the resource will be erased from the triplestore, otherwise it will be marked as deleted.
*/
case class DeleteOrEraseResourceRequestV2(resourceIri: IRI,
resourceClassIri: SmartIri,
maybeDeleteComment: Option[String] = None,
maybeDeleteDate: Option[Instant] = None,
maybeLastModificationDate: Option[Instant] = None,
erase: Boolean = false,
requestingUser: UserADM,
Expand Down Expand Up @@ -812,10 +820,17 @@ object DeleteOrEraseResourceRequestV2 extends KnoraJsonLDRequestReaderV2[DeleteO

val maybeDeleteComment: Option[String] = jsonLDDocument.maybeStringWithValidation(OntologyConstants.KnoraApiV2Complex.DeleteComment, stringFormatter.toSparqlEncodedString)

val maybeDeleteDate: Option[Instant] = jsonLDDocument.maybeDatatypeValueInObject(
key = OntologyConstants.KnoraApiV2Complex.DeleteDate,
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
validationFun = stringFormatter.xsdDateTimeStampToInstant
)

DeleteOrEraseResourceRequestV2(
resourceIri = resourceIri.toString,
resourceClassIri = resourceClassIri,
maybeDeleteComment = maybeDeleteComment,
maybeDeleteDate = maybeDeleteDate,
maybeLastModificationDate = maybeLastModificationDate,
requestingUser = requestingUser,
apiRequestID = apiRequestID
Expand Down