Skip to content

Commit 70b0841

Browse files
author
Benjamin Geer
authored
fix(api-v2): Fix ontology deletion (#1584)
1 parent 22727a2 commit 70b0841

2 files changed

Lines changed: 50 additions & 8 deletions

File tree

‎webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala‎

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
7171
*/
7272
private val OntologyCacheKey = "ontologyCacheData"
7373

74+
/**
75+
* The in-memory cache of ontologies.
76+
*
77+
* @param ontologies a map of ontology IRIs to ontologies.
78+
* @param subClassOfRelations a map of subclasses to their base classes.
79+
* @param superClassOfRelations a map of base classes to their subclasses.
80+
* @param subPropertyOfRelations a map of subproperties to their base proeprties.
81+
* @param guiAttributeDefinitions a map of salsah-gui:Guielement individuals to their GUI attribute definitions.
82+
* @param standoffProperties a set of standoff properties.
83+
*/
7484
private case class OntologyCacheData(ontologies: Map[SmartIri, ReadOntologyV2],
7585
subClassOfRelations: Map[SmartIri, Set[SmartIri]],
7686
superClassOfRelations: Map[SmartIri, Set[SmartIri]],
@@ -2618,7 +2628,10 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
26182628
classes = ontology.classes - internalClassIri
26192629
)
26202630

2621-
updatedSubClassOfRelations = cacheData.subClassOfRelations - internalClassIri
2631+
updatedSubClassOfRelations = (cacheData.subClassOfRelations - internalClassIri).map {
2632+
case (subClass, baseClasses) => subClass -> (baseClasses - internalClassIri)
2633+
}
2634+
26222635
updatedSuperClassOfRelations = calculateSuperClassOfRelations(updatedSubClassOfRelations)
26232636

26242637
_ = storeCacheData(cacheData.copy(
@@ -2736,7 +2749,9 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
27362749
properties = ontology.properties -- propertiesToRemoveFromCache
27372750
)
27382751

2739-
updatedSubPropertyOfRelations = cacheData.subPropertyOfRelations -- propertiesToRemoveFromCache
2752+
updatedSubPropertyOfRelations = (cacheData.subPropertyOfRelations -- propertiesToRemoveFromCache).map {
2753+
case (subProperty, baseProperties) => subProperty -> (baseProperties -- propertiesToRemoveFromCache)
2754+
}
27402755

27412756
_ = storeCacheData(cacheData.copy(
27422757
ontologies = cacheData.ontologies + (internalOntologyIri -> updatedOntology),
@@ -2789,7 +2804,7 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
27892804
expectedLastModificationDate = deleteOntologyRequest.lastModificationDate
27902805
)
27912806

2792-
// Check that none of the entities in the ontology are used in data.
2807+
// Check that none of the entities in the ontology are used in data or in other ontologies.
27932808

27942809
ontology = cacheData.ontologies(internalOntologyIri)
27952810

@@ -2827,6 +2842,33 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
28272842
throw UpdateNotPerformedException(s"Ontology ${internalOntologyIri.toOntologySchema(ApiV2Complex)} was not deleted. Please report this as a possible bug.")
28282843
}
28292844

2845+
// Remove the ontology from the cache.
2846+
2847+
updatedSubClassOfRelations = cacheData.subClassOfRelations.filterNot {
2848+
case (subClass, _) => subClass.getOntologyFromEntity == internalOntologyIri
2849+
}.map {
2850+
case (subClass, baseClasses) => subClass -> baseClasses.filterNot(_.getOntologyFromEntity == internalOntologyIri)
2851+
}
2852+
2853+
updatedSuperClassOfRelations = calculateSuperClassOfRelations(updatedSubClassOfRelations)
2854+
2855+
updatedSubPropertyOfRelations = cacheData.subPropertyOfRelations.filterNot {
2856+
case (subProperty, _) => subProperty.getOntologyFromEntity == internalOntologyIri
2857+
}.map {
2858+
case (subProperty, baseProperties) => subProperty -> baseProperties.filterNot(_.getOntologyFromEntity == internalOntologyIri)
2859+
}
2860+
2861+
updatedStandoffProperties = cacheData.standoffProperties.filterNot(_.getOntologyFromEntity == internalOntologyIri)
2862+
2863+
updatedCacheData = cacheData.copy(
2864+
ontologies = cacheData.ontologies - internalOntologyIri,
2865+
subClassOfRelations = updatedSubClassOfRelations,
2866+
superClassOfRelations = updatedSuperClassOfRelations,
2867+
subPropertyOfRelations = updatedSubPropertyOfRelations,
2868+
standoffProperties = updatedStandoffProperties
2869+
)
2870+
2871+
_ = storeCacheData(updatedCacheData)
28302872
} yield SuccessResponseV2(s"Ontology ${internalOntologyIri.toOntologySchema(ApiV2Complex)} has been deleted")
28312873
}
28322874

‎webapi/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
109109
assert(response.ontologies.size == 1)
110110
val metadata = response.ontologies.head
111111
assert(metadata.ontologyIri.toString == "http://www.knora.org/ontology/00FF/foo")
112-
fooIri.set(metadata.ontologyIri.toOntologySchema(ApiV2Complex).toString)
112+
fooIri.set(metadata.ontologyIri.toString)
113113
fooLastModDate = metadata.lastModificationDate.getOrElse(throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
114114
}
115115

116116
"change the metadata of 'foo'" in {
117117
val newLabel = "The modified foo ontology"
118118

119119
responderManager ! ChangeOntologyMetadataRequestV2(
120-
ontologyIri = fooIri.get.toSmartIri,
120+
ontologyIri = fooIri.get.toSmartIri.toOntologySchema(ApiV2Complex),
121121
label = newLabel,
122122
lastModificationDate = fooLastModDate,
123123
apiRequestID = UUID.randomUUID,
@@ -127,7 +127,7 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
127127
val response = expectMsgType[ReadOntologyMetadataV2](timeout)
128128
assert(response.ontologies.size == 1)
129129
val metadata = response.ontologies.head
130-
assert(metadata.ontologyIri.toString == "http://www.knora.org/ontology/00FF/foo")
130+
assert(metadata.ontologyIri == fooIri.get.toSmartIri)
131131
assert(metadata.label.contains(newLabel))
132132
val newFooLastModDate = metadata.lastModificationDate.getOrElse(throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
133133
assert(newFooLastModDate.isAfter(fooLastModDate))
@@ -167,7 +167,7 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
167167

168168
"not allow a user to delete an ontology if they are not a sysadmin or an admin in the ontology's project" in {
169169
responderManager ! DeleteOntologyRequestV2(
170-
ontologyIri = fooIri.get.toSmartIri,
170+
ontologyIri = fooIri.get.toSmartIri.toOntologySchema(ApiV2Complex),
171171
lastModificationDate = fooLastModDate,
172172
apiRequestID = UUID.randomUUID,
173173
requestingUser = SharedTestDataADM.imagesUser02
@@ -182,7 +182,7 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
182182

183183
"delete the 'foo' ontology" in {
184184
responderManager ! DeleteOntologyRequestV2(
185-
ontologyIri = fooIri.get.toSmartIri,
185+
ontologyIri = fooIri.get.toSmartIri.toOntologySchema(ApiV2Complex),
186186
lastModificationDate = fooLastModDate,
187187
apiRequestID = UUID.randomUUID,
188188
requestingUser = imagesUser

0 commit comments

Comments
 (0)