ChangeRequest to add blank nodes fails
It seems that the handling/preprocessing of blank nodes in ChangeRequests does not work correctly. Perhaps empty nodes in the Change object should be replaced by internal neone ids?
This could affect compatibility with other ONE-Record client/server implementations as ne-one require specific bNode IDs.
Tested with commit 0db3006bd7f3b6bc80a2f5c5cf144f87b7e08ba6 and commit 1898d22eb63b2e260807a6721e411f3d63b133f0
Steps to reproduce:
1. Create LogisticsObject
{
"@type": "https://onerecord.iata.org/ns/cargo#Piece",
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a56",
"https://onerecord.iata.org/ns/cargo#goodsDescription": "something"
}
2a. Add Embedded Object to LogisticsObject with _:b0 (fails)
{
"@context": {
"cargo": "https://onerecord.iata.org/ns/cargo#",
"api": "https://onerecord.iata.org/ns/api#"
},
"@type": "api:Change",
"api:hasLogisticsObject": {
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a56"
},
"api:hasDescription": "Add grossWeight",
"api:hasOperation": [
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a56",
"api:p": "https://onerecord.iata.org/ns/cargo#grossWeight",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "https://onerecord.iata.org/ns/cargo#Value",
"api:hasValue": "_:b0"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "_:b0",
"api:p": "https://onerecord.iata.org/ns/cargo#unit",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#string",
"api:hasValue": "KGM"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "_:b0",
"api:p": "https://onerecord.iata.org/ns/cargo#value",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#double",
"api:hasValue": "20.0"
}
]
}
],
"api:hasRevision": {
"@type": "http://www.w3.org/2001/XMLSchema#positiveInteger",
"@value": "1"
}
}
Result:
After accepting the ChangeRequest (e.g. by scheduled trigger):
```bash
2023-12-01 09:38:52,100 WARN [org.ope.neo.rep.RepositoryTransaction] (vert.x-worker-thread-2) Exception during transaction, rolling back transaction: java.lang.IllegalArgumentException: IRI must be absolute
at org.eclipse.rdf4j.model.impl.ValidatingValueFactory.createIRI(ValidatingValueFactory.java:72)
at org.eclipse.rdf4j.model.util.Values.iri(Values.java:94)
at org.eclipse.rdf4j.model.util.Values.iri(Values.java:80)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService.lambda$applyOperations$20(LogisticsObjectService.java:407)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService.applyOperations(LogisticsObjectService.java:395)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService.acceptChangeRequest(LogisticsObjectService.java:317)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService.lambda$onChangeRequestUpdated$8(LogisticsObjectService.java:292)
at org.openlogisticsfoundation.neone.repository.RepositoryTransaction.lambda$transactionallyDo$1(RepositoryTransaction.java:47)
at org.openlogisticsfoundation.neone.repository.RepositoryTransaction.transactionallyGet(RepositoryTransaction.java:64)
at org.openlogisticsfoundation.neone.repository.RepositoryTransaction.transactionallyDo(RepositoryTransaction.java:46)
at org.openlogisticsfoundation.neone.repository.RepositoryTransaction_ClientProxy.transactionallyDo(Unknown Source)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService.onChangeRequestUpdated(LogisticsObjectService.java:286)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService_ClientProxy.onChangeRequestUpdated(Unknown Source)
at org.openlogisticsfoundation.neone.service.LogisticsObjectService_VertxInvoker_onChangeRequestUpdated_4625f873faa7a096e68a815ba4134b092ba1a294.invokeBean(Unknown Source)
at io.quarkus.vertx.runtime.EventConsumerInvoker.invoke(EventConsumerInvoker.java:45)
at io.quarkus.vertx.runtime.VertxEventBusConsumerRecorder$3$1$2.call(VertxEventBusConsumerRecorder.java:142)
at io.quarkus.vertx.runtime.VertxEventBusConsumerRecorder$3$1$2.call(VertxEventBusConsumerRecorder.java:138)
at io.vertx.core.impl.ContextBase.lambda$executeBlocking$0(ContextBase.java:167)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:277)
at io.vertx.core.impl.ContextBase.lambda$internalExecuteBlocking$2(ContextBase.java:199)
at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:76)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
2b. Add Embedded Object to LogisticsObject with internal:b0 (works partly)
{
"@context": {
"cargo": "https://onerecord.iata.org/ns/cargo#",
"api": "https://onerecord.iata.org/ns/api#"
},
"@type": "api:Change",
"api:hasLogisticsObject": {
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a57"
},
"api:hasDescription": "Add grossWeight",
"api:hasOperation": [
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a57",
"api:p": "https://onerecord.iata.org/ns/cargo#grossWeight",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "https://onerecord.iata.org/ns/cargo#Value",
"api:hasValue": "internal:b0"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "internal:b0",
"api:p": "https://onerecord.iata.org/ns/cargo#unit",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#string",
"api:hasValue": "KGM"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "internal:b0",
"api:p": "https://onerecord.iata.org/ns/cargo#value",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#double",
"api:hasValue": "20.0"
}
]
}
],
"api:hasRevision": {
"@type": "http://www.w3.org/2001/XMLSchema#positiveInteger",
"@value": "1"
}
}
Result:
{
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a57",
"@type": "Piece",
"goodsDescription": "something",
"grossWeight": {
"@id": "internal:b0"
},
"@context": {
"@vocab": "https://onerecord.iata.org/ns/cargo#"
}
}
2c. Add Embedded Object to LogisticsObject with neone:12345 (works)
{
"@context": {
"cargo": "https://onerecord.iata.org/ns/cargo#",
"api": "https://onerecord.iata.org/ns/api#"
},
"@type": "api:Change",
"api:hasLogisticsObject": {
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a58"
},
"api:hasDescription": "Add grossWeight",
"api:hasOperation": [
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a58",
"api:p": "https://onerecord.iata.org/ns/cargo#grossWeight",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "https://onerecord.iata.org/ns/cargo#Value",
"api:hasValue": "neone:12345"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "neone:12345",
"api:p": "https://onerecord.iata.org/ns/cargo#unit",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#string",
"api:hasValue": "KGM"
}
]
},
{
"@type": "api:Operation",
"api:op": {
"@id": "api:ADD"
},
"api:s": "neone:12345",
"api:p": "https://onerecord.iata.org/ns/cargo#value",
"api:o": [
{
"@type": "api:OperationObject",
"api:hasDatatype": "http://www.w3.org/2001/XMLSchema#double",
"api:hasValue": "20.0"
}
]
}
],
"api:hasRevision": {
"@type": "http://www.w3.org/2001/XMLSchema#positiveInteger",
"@value": "1"
}
}
Result:
{
"@graph": [
{
"@id": "http://localhost:8080/logistics-objects/8d4cbec9-817a-4ab8-b07f-8802e4463a58",
"@type": "Piece",
"goodsDescription": "something",
"grossWeight": {
"@id": "neone:12345"
}
},
{
"@id": "neone:12345",
"@type": "Value",
"unit": "KGM",
"value": {
"@type": "http://www.w3.org/2001/XMLSchema#double",
"@value": "20.0"
}
}
],
"@context": {
"@vocab": "https://onerecord.iata.org/ns/cargo#"
}
}
Edited by Daniel A. Doeppner