Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(resourceHistoryEvents): route for resource history events (DSP-1…
…749) (#1882)

* feat (resourceHistoryEvents): responder for getting history events of a single resource

* feat (resourceHistoryEvents): add route

* refactor (historyEvents): clean up

* docs (resourceHistoryEvents): add documentation

* refactor(resourceHistoryEvents): clean up
  • Loading branch information
SepidehAlassi committed Jun 24, 2021
1 parent b972212 commit f86de53
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 197 deletions.
49 changes: 37 additions & 12 deletions docs/03-apis/api-v2/reading-and-searching-resources.md
Expand Up @@ -571,28 +571,32 @@ be sorted alphabetically by resource IRI (an arbitrary but consistent order).
The value of `page` is a 0-based integer page number. Paging works as it does
in [Gravsearch](query-language.md)).

### Get the Version History of Resources and Values of a Project
### Get the Full History of a Resource and its Values as Events

To get a list of the changes that have been made to resources and values of a project since their creation ordered by date
use this route:
To get a list of the changes that have been made to a resource and its values since its creation as events ordered by
date:

```
HTTP GET to http://host/v2/resources/projectHistory/projectIRI
HTTP GET to http://host/v2/resources/resourceHistoryEvents/<resourceIRI>
```

The project IRI must be URL-encoded. The response is a list of events describing changes made to the resource and its values,
The resource IRI must be URL-encoded. The response is a list of events describing changes made to the resource and its values,
in chronological order. Each entry has the properties:
`knora-api:eventType` (the type of the operation performed on a specific date. The operation can be either
`createResource`, `deleteResource`, `createValue`, `updateValueContent`, `updateValuePermissions`, or `deleteValue`.),
`createdResource`, `updatedResourceMetadata`, `deletedResource`, `createdValue`, `updatedValueContent`,
`updatedValuePermissions`, or `deletedValue`.),
`knora-api:versionDate` (the date when the change was made),
`knora-api:author` (the IRI of the user who made the change),
`knora-api:eventBody` (the information necessary to make the same request). For example:
`knora-api:eventBody` (the information necessary to make the same request).

For example, the following response contains the list of events describing the version history of the resource
`http://rdfh.ch/0001/thing-with-history` ordered by date:

```jsonld
{
"@graph" : [
{
"knora-api:eventType": "createResource",
"knora-api:eventType": "createdResource",
"knora-api:author": {
"@id": "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q"
},
Expand All @@ -615,7 +619,7 @@ The project IRI must be URL-encoded. The response is a list of events describing
}
},
{
"knora-api:eventType": "createValue",
"knora-api:eventType": "createdValue",
"knora-api:author": {
"@id": "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q"
},
Expand Down Expand Up @@ -643,7 +647,7 @@ The project IRI must be URL-encoded. The response is a list of events describing
}
},
{
"knora-api:eventType": "updateValueContent",
"knora-api:eventType": "updatedValueContent",
"knora-api:author": {
"@id": "http://rdfh.ch/users/BhkfBc3hTeS_IDo-JgXRbQ"
},
Expand All @@ -669,7 +673,7 @@ The project IRI must be URL-encoded. The response is a list of events describing
}
},
{
"knora-api:eventType": "deleteValue",
"knora-api:eventType": "deletedValue",
"knora-api:author": {
"@id": "http://rdfh.ch/users/9XBCrDV3SRa7kS1WwynB4Q"
},
Expand Down Expand Up @@ -699,4 +703,25 @@ The project IRI must be URL-encoded. The response is a list of events describing
"knora-api" : "http://api.knora.org/ontology/knora-api/v2#"
}
}
```
```

Since the history of changes made to the metadata of a resource is not part of resouce's version history, there are no
events describing the changes on metadata elements like its `rdfs:label` or `rdfs:comment`.
The only record depicting a change in a resource's metadata is the `knora-api:lastModificationDate` of the resource. Thus
the event `updatedResourceMetadata` indicates a change in a resource's metadata, its `knora-api:eventBody` contains the
payload needed to update the value of the resource's `lastModificationDate`, see
[modifying metadata of a resource](editing-resources.md#modifying-a-resources-metadata).



### Get the Full History of all Resources of a Project as Events

To get a list of the changes that have been made to the resources and their values of a project as events ordered by
date:

```
HTTP GET to http://host/v2/resources/projectHistoryEvents/<projectIRI>
```

The project IRI must be URL-encoded. The response contains the resource history events of all resources that belong to
the specified project.
Expand Up @@ -148,15 +148,19 @@ case class ResourceVersionHistoryGetRequestV2(resourceIri: IRI,
* Requests the full version history of a resource and its values as events.
*
* @param resourceIri the IRI of the resource.
* @param resourceVersionHistory the version history of the resource and its values.
* @param featureFactoryConfig the feature factory configuration.
* @param requestingUser the user making the request.
*/
case class ResourceFullHistoryGetRequestV2(resourceIri: IRI,
resourceVersionHistory: Seq[ResourceHistoryEntry],
featureFactoryConfig: FeatureFactoryConfig,
requestingUser: UserADM)
extends ResourcesResponderRequestV2
case class ResourceHistoryEventsGetRequestV2(resourceIri: IRI,
featureFactoryConfig: FeatureFactoryConfig,
requestingUser: UserADM)
extends ResourcesResponderRequestV2 {
private val stringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validateAndEscapeIri(resourceIri, throw BadRequestException(s"Invalid resource IRI: $resourceIri"))
if (!stringFormatter.toSmartIri(resourceIri).isKnoraResourceIri) {
throw BadRequestException(s"Given IRI is not a resource IRI: $resourceIri")
}
}

/**
* Requests the version history of all resources of a project.
Expand Down Expand Up @@ -1330,18 +1334,18 @@ case class GraphDataGetResponseV2(nodes: Seq[GraphNodeV2], edges: Seq[GraphEdgeV
}

/**
* Represents the version history of a resource or a values as events.
* Represents the version history of a resource or a value as events.
*
* @param eventType the type of the operation that is one of [[ResourceAndValueEventsUtil]]
* @param versionDate the version date of the event.
* @param author the user which had performed the operation.
* @param eventBody the request body in the form of [[ResourceOrValueEventBody]] needed for the operation indicated
* by eventType.
*/
case class ResourceAndValueHistoryV2(eventType: String,
versionDate: Instant,
author: IRI,
eventBody: ResourceOrValueEventBody)
case class ResourceAndValueHistoryEvent(eventType: String,
versionDate: Instant,
author: IRI,
eventBody: ResourceOrValueEventBody)

abstract class ResourceOrValueEventBody

Expand Down Expand Up @@ -1549,9 +1553,9 @@ case class ValueEventBody(resourceIri: IRI,
}

/**
* Represents the history of the project resources and values.
* Represents the resource and value history events.
*/
case class ResourceAndValueVersionHistoryResponseV2(projectHistory: Seq[ResourceAndValueHistoryV2])
case class ResourceAndValueVersionHistoryResponseV2(historyEvents: Seq[ResourceAndValueHistoryEvent])
extends KnoraJsonLDResponseV2 {

/**
Expand All @@ -1571,7 +1575,7 @@ case class ResourceAndValueVersionHistoryResponseV2(projectHistory: Seq[Resource

// Convert the history entries to an array of JSON-LD objects.

val projectHistoryAsJsonLD: Seq[JsonLDObject] = projectHistory.map { historyEntry: ResourceAndValueHistoryV2 =>
val historyEventsAsJsonLD: Seq[JsonLDObject] = historyEvents.map { historyEntry: ResourceAndValueHistoryEvent =>
// convert event body to JsonLD object
val eventBodyAsJsonLD: JsonLDObject = historyEntry.eventBody match {
case valueEventBody: ValueEventBody => valueEventBody.toJsonLD(targetSchema, settings, schemaOptions)
Expand Down Expand Up @@ -1609,7 +1613,7 @@ case class ResourceAndValueVersionHistoryResponseV2(projectHistory: Seq[Resource

// Make the JSON-LD document.

val body = JsonLDObject(Map(JsonLDKeywords.GRAPH -> JsonLDArray(projectHistoryAsJsonLD)))
val body = JsonLDObject(Map(JsonLDKeywords.GRAPH -> JsonLDArray(historyEventsAsJsonLD)))

JsonLDDocument(body = body, context = context)
}
Expand Down
Expand Up @@ -5,11 +5,11 @@ package org.knora.webapi.messages.v2.responder.resourcemessages
*/
object ResourceAndValueEventsUtil {

val CREATE_RESOURCE_EVENT = "createResource"
val DELETE_RESOURCE_EVENT = "deleteResource"
val UPDATE_RESOURCE_METADATA_EVENT = "updateResourceMetadata"
val CREATE_VALUE_EVENT = "createValue"
val UPDATE_VALUE_CONTENT_EVENT = "updateValueContent"
val UPDATE_VALUE_PERMISSION_EVENT = "updateValuePermission"
val DELETE_VALUE_EVENT = "deleteValue"
val CREATE_RESOURCE_EVENT = "createdResource"
val DELETE_RESOURCE_EVENT = "deletedResource"
val UPDATE_RESOURCE_METADATA_EVENT = "updatedResourceMetadata"
val CREATE_VALUE_EVENT = "createdValue"
val UPDATE_VALUE_CONTENT_EVENT = "updatedValueContent"
val UPDATE_VALUE_PERMISSION_EVENT = "updatedValuePermission"
val DELETE_VALUE_EVENT = "deletedValue"
}

0 comments on commit f86de53

Please sign in to comment.