2

My situation is simple: I have an RDF (N3) file that I want to upload into sparql-auth-endpoint. I use Jena ARQ, but unfortunately it doesn't work; I get no errors, but the graph doesn't change. Where could be the problem? My code:

HttpContext httpContext = new BasicHttpContext();
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(new AuthScope(AuthScope.ANY_HOST,
    AuthScope.ANY_PORT), new UsernamePasswordCredentials("user", "pass"));
httpContext.setAttribute(ClientContext.CREDS_PROVIDER, provider);

GraphStore graphStore = GraphStoreFactory.create() ;

UpdateRequest request = UpdateFactory.read("turtle.ttl");

/*another possible query, same result - no errors but the graph doesn't change
request.add(new UpdateCreate("graph")) ;
request.add(new UpdateLoad("file:turtle_2.ttl", "graph")) ;
request.add("prefix dcterms: <http://purl.org/dc/terms/>"
    + "INSERT DATA { GRAPH <graph> {<http://example/book3> dcterms:title    \"A new book\" }}");
UpdateAction.execute(request, graphStore) ;
*/

UpdateProcessor processor = UpdateExecutionFactory
    .createRemote(request, "http://sparql-endpoint/sparql-auth");
((UpdateProcessRemote)processor).setHttpContext(httpContext);
processor.execute();

How can I modify the code to upload that data to the sparql-endpoint?

Edit 1

Here is a smaller example, also not working. I can create a new graph via sparql-endpoint in a browser, but in Jena I can't; no errors, no new graph.

UpdateRequest request = UpdateFactory.create();
request.add(new UpdateCreate("http://linkeddata.com/graph"));
UpdateProcessor processor = UpdateExecutionFactory
    .createRemote(request, "http://sparql-endpoint/sparql-auth");
((UpdateProcessRemote)processor).setHttpContext(httpContext);
processor.execute();

Edit 2

Using a Virtuoso server with sparql-auth-endpoint, I've changed these lines and it works much better.

UpdateProcessor processor = UpdateExecutionFactory
    .createRemoteForm(request, "http://sparql-endpoint/sparql-auth");
((UpdateProcessRemoteForm)processor).setHttpContext(httpContext);
processor.execute();

Well, it works on localhost:8890, but doesn't work in another virtuoso server

Exception in thread "main" org.apache.jena.atlas.web.HttpException: 400 Bad Request
at org.apache.jena.riot.web.HttpOp.httpResponse(HttpOp.java:425)
at org.apache.jena.riot.web.HttpOp.execHttpPostForm(HttpOp.java:316)
at com.hp.hpl.jena.sparql.modify.UpdateProcessRemoteForm.execute(UpdateProcessRemoteForm.java:75)
at bakalarska_prace.UpVirtuoso.main(UpVirtuoso.java:108) -> processor.execute()
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
159753
  • 53
  • 1
  • 11

4 Answers4

2

What is the actual SPARQL Update you are reading in with this line:

UpdateRequest request = UpdateFactory.read("turtle.ttl");

Without knowing what the actual SPARQL Update is it is hard to say what is going wrong.

Guesswork...

Based on your commented out example are you trying to do something like the following:

LOAD <file:local.ttl> INTO GRAPH <http://graph>

If this is the case then this will not work, the remote server does not have access to your local file system so this command is not going to work.

Also file:local.ttl is actually an invalid URI anyway, a file URI should look like file:///local.ttl.

Edit

Per the comment I think your problem may be down to the Graph URIs being used, in all your examples you are using relative URIs so your data may not be going in the graph you expect. It's likely your data is being inserted but not into the graph you expect, if you don't have too much data you could try the following query to dump all data in named graphs to see if the data has gone somewhere:

SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }

Or if you are expecting to have a small number of named graphs in the store the following will list out named graphs so you can see if you have any unexpected graphs:

SELECT DISTINCT ?g WHERE { GRAPH ?g { } }

Generally speaking it is always a good idea to use absolute URIs to ensure you are creating the data you expect in the graph you expect, relative URIs are error prone because they can resolve to different absolute URIs depending on the context in which they are resolved.

RobV
  • 28,022
  • 11
  • 77
  • 119
  • turtle.ttl is basic sparql insert query - prefix a: INSERT DATA {graph { a:adddda "paráda!!!"}} - it's the same like the current example. So is there any possibility how to do that? Google haven't helped me... Thx a lot – 159753 May 10 '13 at 18:45
  • @159753 I have updated my answer with more suggestions based on your additional information – RobV May 10 '13 at 18:54
  • 1
    There's no problem with URIs, I use absolute everywhere. Anyway, I edited the main text - just to create a new graph via UpdateRequest - still cannot reach the goal :( – 159753 May 10 '13 at 19:25
  • 2
    Hmm, try enabling `DEBUG` level logging for your code. ARQ uses Apache HttpClient under the hood to submit updates so with `DEBUG` level logging on you should be able to see exactly what is being sent to and from the server. One possibility is that your server doesn't support `POST` requests with `Content-Type: application/sparql-update` which is what your code does, you could try using `UpdateExecutionFactory.createRemoteForm()` instead which sends a more traditional Form URL encoded `POST` request – RobV May 10 '13 at 23:00
  • Also note that a bare `CREATE` update may have no effect anyway, if the underlying store has no notion of empty graphs it is not required to do anything and a `CREATE` is essentially a no-op - http://www.w3.org/TR/sparql11-update/#create - "Stores that do not record empty named graphs will always return success on creation of a non-existing graph." – RobV May 10 '13 at 23:02
  • I use typical Virtuoso server and I had this problem on localhost as well. So createRemoteForm works fine now on localhost, the problem is on another server but I think this is the question for the admin of that server, right? Or do you have another good tip? :-) Anyway, thanks a lot :) – 159753 May 11 '13 at 07:21
0

Virtuoso does not support INSERT DATA {graph <graph> {}} going by the online documentation.

400 Bad Request means syntax error from the server.

You'll need to send the request string straight to the server - because it's not SPARQL 1.1 synatx, Jena wil not parse it.

AndyS
  • 16,345
  • 17
  • 21
  • So why does it work in localhost:8890 (Also Virtuoso server)? Any ideas how to send it straight? If I try this - the post might cause the problem - no errors, no changes in the graph ... `HttpOp.execHttpPost("http://endpoint:8890/sparql-auth", WebContent.contentTypeSPARQLUpdate, request.toString(), null, null, httpContext);` – 159753 May 11 '13 at 11:12
0

If it works in Virtuoso conductor interface (http://localhost:8890), so you could use Virtuoso Jena provider and the next code:

  String queryString = "INSERT DATA {graph <graph> ...."; // your query
  Model m = VirtModel.openDatabaseModel(file, connectionURL, username, password); 
  VirtuosoUpdateRequest vur = VirtuosoUpdateFactory.create(queryString, m);
  vur.exec();  

It will sent query directly to Virtuoso server.

0

I had the same problem and it started to work when I added "/update" in the end of the endpoint uri.

Hannu
  • 11
  • 3