Details
-
Type:
Bug
-
Status: Closed - Won't Fix
-
Priority:
High
-
Resolution: Won't Fix
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: Bigdata SAIL, RemoteRepository
-
Labels:None
Description
Hi,
I am integrating the NSS with my code based to manipulate RDF graph remotely. To be able to provide a seamless integration, I define a repository with the option STORE_BLANK_NODES to true. Unfortunately the behavior over wire does not behave like the embedded version due to the fact the the RDFWriter and RDF Reader used for the serialization/deserialization does not preserve the blank node. This results to the inability to refer to blank node from the client side.
To demonstrate the behavior here an example of code
{{import java.util.Properties;
import org.openrdf.model.BNode;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.repository.RepositoryResult;
import com.bigdata.rdf.sail.remote.BigdataSailRemoteRepository;
import com.bigdata.rdf.sail.remote.BigdataSailRemoteRepositoryConnection;
import com.bigdata.rdf.sail.webapp.client.RemoteRepository;
import com.bigdata.rdf.sail.webapp.client.RemoteRepositoryManager;
import com.bigdata.rdf.store.AbstractTripleStore;
public class TestRemoteBlankNode {
public static void main(String[] args) throws Exception {
RemoteRepositoryManager mgr = new RemoteRepositoryManager(
"http://localhost:8080/bigdata");
Properties props = new Properties();
props.put(AbstractTripleStore.Options.AXIOMS_CLASS,
"com.bigdata.rdf.axioms.NoAxioms");
props.put(AbstractTripleStore.Options.STORE_BLANK_NODES, "true");
props.put(AbstractTripleStore.Options.QUADS, "false");
BigdataSailRemoteRepository sailRepo = null;
BigdataSailRemoteRepositoryConnection con = null;
try {
mgr.createRepository("repotest", props);
RemoteRepository repo = mgr.getRepositoryForNamespace("repotest");
sailRepo = repo.getBigdataSailRemoteRepository();
sailRepo.initialize();
ValueFactory vf = sailRepo.getValueFactory();
URI s = vf.createURI("http://example.org/s");
URI p = vf.createURI("http://example.org/p");
BNode o = vf.createBNode("b1");
// create a statement with a blank node object
Statement stmt = vf.createStatement(s, p, o);
System.out.println("Statement send to storage");
System.out.println(stmt);
con = sailRepo.getConnection();
con.add(stmt);
System.out.println("Retrieve statement from remote repo");
RepositoryResult<Statement> rr = con.getStatements(null, null,
null, false);
while (rr.hasNext())
rr.close();
// the following call will throw an exception because the statement
// contains a blanknode
System.out.print(con.hasStatement(stmt, false));
} catch (Exception e)
finally
{ con.close(); sailRepo.shutDown(); mgr.close(); } }
}
}}
The output is the following:
{{Statement send to storage
(http://example.org/s, http://example.org/p, _:b1)
Retrieve statement from remote repo
(http://example.org/s, http://example.org/p, _:genid-c4a43091ddaa4911b1f8b79f37d13e49-genid-8497473e12b544ab9a1f1eb6e33b39e2-b1)
org.openrdf.repository.RepositoryException: java.lang.IllegalArgumentException
at com.bigdata.rdf.sail.remote.BigdataSailRemoteRepositoryConnection.hasStatement(BigdataSailRemoteRepositoryConnection.java:258)
at com.bigdata.rdf.sail.remote.BigdataSailRemoteRepositoryConnection.hasStatement(BigdataSailRemoteRepositoryConnection.java:383)
at com.knowledgesmarts.repository.plugins.bigdata.remote.TestRemoteBlankNode.main(TestRemoteBlankNode.java:59)
Caused by: java.lang.IllegalArgumentException
at com.bigdata.rdf.sail.webapp.client.EncodeDecodeValue.encodeValue(EncodeDecodeValue.java:413)
at com.bigdata.rdf.sail.webapp.client.RemoteRepository.hasStatement(RemoteRepository.java:471)
at com.bigdata.rdf.sail.remote.BigdataSailRemoteRepositoryConnection.hasStatement(BigdataSailRemoteRepositoryConnection.java:254)
... 2 more
}}
If you use the NSS client provided by Blazegraph, the blank node has the following id:
genid-8497473e12b544ab9a1f1eb6e33b39e2-b1
To summarize have:
_:b1 on client side
_:genid-8497473e12b544ab9a1f1eb6e33b39e2-b1 (on server side)
_:genid-c4a43091ddaa4911b1f8b79f37d13e49-genid-8497473e12b544ab9a1f1eb6e33b39e2-b1 after round trip to client
This is making very difficult to traverse graph using blank node on the client side
Also the method hasStatement does not allow any blank node in the query, which in my opinion should be allowed.
One possible work around is to set config to the RDF writer and reader to preserve the blank nodes (in AddOp, RemoveOp and UpdateOp) operations.
This issue is considered as a blocker for anyone trying to manipulate or navigate graph. For example how can you delete a triple with a blank node if you cannot control its matching, or how can you traverse a triple having a blank node object and access its properties (bnode closure is not always desirable due to overhead of traversal).