Uploaded image for project: 'Blazegraph (by SYSTAP)'
  1. Blazegraph (by SYSTAP)
  2. BLZG-1616

Handling of blank node with Nanosparql Server

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed - Won't Fix
    • Priority: High
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • 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())

      { System.out.println(rr.next()); }

      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)

      { e.printStackTrace(); }

      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).

        Attachments

          Activity

            People

            Assignee:
            beebs Brad Bebee
            Reporter:
            stephanef@imagemattersllc.com Stephane Fellah
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: