You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2014/06/12 17:30:34 UTC
svn commit: r1602204 - in /jena/Experimental/jena-fuseki2: ./
src/main/java/org/apache/jena/fuseki/mgt/
src/main/java/org/apache/jena/fuseki/servlets/
Author: andy
Date: Thu Jun 12 15:30:34 2014
New Revision: 1602204
URL: http://svn.apache.org/r1602204
Log:
Calculate upload statistics. Return in JSON
Added:
jena/Experimental/jena-fuseki2/D.ttl (with props)
jena/Experimental/jena-fuseki2/dwim-upload (with props)
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java (with props)
Modified:
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/Upload.java
Added: jena/Experimental/jena-fuseki2/D.ttl
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/D.ttl?rev=1602204&view=auto
==============================================================================
Binary file - no diff available.
Propchange: jena/Experimental/jena-fuseki2/D.ttl
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: jena/Experimental/jena-fuseki2/dwim-upload
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/dwim-upload?rev=1602204&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/dwim-upload (added)
+++ jena/Experimental/jena-fuseki2/dwim-upload Thu Jun 12 15:30:34 2014
@@ -0,0 +1,31 @@
+#!/bin/bash
+# How to do a file upload in curl
+
+# GSP strict
+U='http://localhost:3030/ds/data?graph=http://example/G'
+# PUT
+## curl --upload-file D.ttl --header 'Content-Type: text/turtle' "$U"
+
+# POST
+curl -XPOST --upload-file D.ttl --header 'Content-Type: text/turtle' "$U"
+
+
+
+# Quads to GSP
+
+## curl -F 'file=@D.ttl' http://localhost:3030/ds/data
+## curl -F 'file=@D.trig' http://localhost:3030/ds/data
+
+# Quads to graph : NGs in data ignored
+# curl -F 'file=@D.trig' 'http://localhost:3030/ds/data?default'
+#curl -F 'file=@D.trig' 'http://localhost:3030/ds/data?graph=http://example/G'
+
+# Dataset
+## curl -F 'file=@D.trig' http://localhost:3030/ds
+
+# Upload service
+## curl -F 'file=@D.trig' -F 'name=http://graph/' 'http://localhost:3030/ds/upload'
+
+
+echo "==== Dataset"
+curl http://localhost:3030/ds
Propchange: jena/Experimental/jena-fuseki2/dwim-upload
------------------------------------------------------------------------------
svn:executable = *
Modified: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java?rev=1602204&r1=1602203&r2=1602204&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java (original)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java Thu Jun 12 15:30:34 2014
@@ -313,7 +313,7 @@ public class ActionDatasets extends Acti
}
private void assemblerFromUpload(HttpAction action, StreamRDF dest) {
- Upload.fileUploadWorker(action, dest, true);
+ Upload.fileUploadWorker(action, dest);
}
// ---- DELETE
Modified: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java?rev=1602204&r1=1602203&r2=1602204&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java (original)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads_RW.java Thu Jun 12 15:30:34 2014
@@ -80,7 +80,7 @@ public class REST_Quads_RW extends REST_
try {
DatasetGraph dsg = action.getActiveDSG() ;
StreamRDF dest = StreamRDFLib.dataset(dsg) ;
- Upload.incomingData(action, dest, false) ;
+ UploadDetails details = Upload.incomingData(action, dest) ;
action.commit() ;
ServletOps.success(action) ;
} catch (RiotException ex) {
@@ -100,10 +100,12 @@ public class REST_Quads_RW extends REST_
DatasetGraph dsgTmp = DatasetGraphFactory.createMem() ;
StreamRDF dest = StreamRDFLib.dataset(dsgTmp) ;
+ UploadDetails details ;
try {
- Upload.incomingData(action, dest, false) ;
+ details = Upload.incomingData(action, dest) ;
} catch (RiotException ex) {
ServletOps.errorBadRequest(ex.getMessage()) ;
+ return ;
}
// Now insert into dataset
action.beginWrite() ;
Modified: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java?rev=1602204&r1=1602203&r2=1602204&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java (original)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_GSP_RW.java Thu Jun 12 15:30:34 2014
@@ -18,13 +18,16 @@
package org.apache.jena.fuseki.servlets;
+import static org.apache.jena.riot.WebContent.ctMultipartMixed ;
+import static org.apache.jena.riot.WebContent.matchContentType ;
+import org.apache.jena.atlas.json.JsonValue ;
import org.apache.jena.atlas.web.ContentType ;
import org.apache.jena.fuseki.FusekiLib ;
-import org.apache.jena.riot.web.HttpNames ;
+import org.apache.jena.fuseki.servlets.UploadDetails.PreState ;
import org.apache.jena.riot.RiotException ;
-import static org.apache.jena.riot.WebContent.* ;
import org.apache.jena.riot.system.StreamRDF ;
import org.apache.jena.riot.system.StreamRDFLib ;
+import org.apache.jena.riot.web.HttpNames ;
import org.apache.jena.web.HttpSC ;
import com.hp.hpl.jena.graph.Graph ;
@@ -81,16 +84,20 @@ public class SPARQL_GSP_RW extends SPARQ
ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "multipart/mixed not supported") ;
}
- boolean existedBefore = false ;
+ UploadDetails details ;
if ( action.isTransactional() )
- existedBefore = addDataIntoTxn(action, overwrite) ;
+ details = addDataIntoTxn(action, overwrite) ;
else
- existedBefore = addDataIntoNonTxn(action, overwrite) ;
-
- if ( existedBefore )
- ServletOps.successNoContent(action) ;
+ details = addDataIntoNonTxn(action, overwrite) ;
+
+ // WRONG
+ if ( details.getExistedBefore().equals(PreState.ABSENT) )
+ ServletOps.successCreated(action) ; // Gets lost by
else
- ServletOps.successCreated(action) ;
+ ServletOps.success(action) ; // successNoContent if empty body.
+
+ JsonValue v = details.detailsJson() ;
+ ServletOps.sendJson(action, v) ;
}
/** Directly add data in a transaction.
@@ -100,7 +107,7 @@ public class SPARQL_GSP_RW extends SPARQ
* @param cleanDest Whether to remove data first (true = PUT, false = POST)
* @return whether the target existed beforehand
*/
- protected static boolean addDataIntoTxn(HttpAction action, boolean overwrite) {
+ protected static UploadDetails addDataIntoTxn(HttpAction action, boolean overwrite) {
action.beginWrite();
Target target = determineTarget(action) ;
boolean existedBefore = false ;
@@ -112,19 +119,20 @@ public class SPARQL_GSP_RW extends SPARQ
if ( overwrite && existedBefore )
clearGraph(target) ;
StreamRDF sink = StreamRDFLib.graph(g) ;
- Upload.incomingData(action, sink, true);
+ UploadDetails upload = Upload.incomingData(action, sink);
+ upload.setExistedBefore(existedBefore) ;
action.commit() ;
- return existedBefore ;
+ return upload ;
} catch (RiotException ex) {
// Parse error
action.abort() ;
ServletOps.errorBadRequest(ex.getMessage()) ;
- return existedBefore ;
+ return null ;
} catch (Exception ex) {
// Something else went wrong. Backout.
action.abort() ;
ServletOps.errorOccurred(ex.getMessage()) ;
- return existedBefore ;
+ return null ;
} finally {
action.endWrite() ;
}
@@ -139,14 +147,15 @@ public class SPARQL_GSP_RW extends SPARQ
* @return whether the target existed beforehand.
*/
- protected static boolean addDataIntoNonTxn(HttpAction action, boolean overwrite) {
+ protected static UploadDetails addDataIntoNonTxn(HttpAction action, boolean overwrite) {
Graph graphTmp = GraphFactory.createGraphMem() ;
StreamRDF dest = StreamRDFLib.graph(graphTmp) ;
- try { Upload.incomingData(action, dest, true); }
+ UploadDetails details ;
+ try { details = Upload.incomingData(action, dest); }
catch (RiotException ex) {
ServletOps.errorBadRequest(ex.getMessage()) ;
- return false ;
+ return null ;
}
// Now insert into dataset
action.beginWrite() ;
@@ -159,8 +168,9 @@ public class SPARQL_GSP_RW extends SPARQ
if ( overwrite && existedBefore )
clearGraph(target) ;
FusekiLib.addDataInto(graphTmp, target.dsg, target.graphName) ;
+ details.setExistedBefore(existedBefore) ;
action.commit() ;
- return existedBefore ;
+ return details ;
} catch (Exception ex) {
// We parsed into a temporary graph so an exception at this point
// is not because of a parse error.
@@ -168,7 +178,7 @@ public class SPARQL_GSP_RW extends SPARQ
// but it might and there is no harm safely trying.
try { action.abort() ; } catch (Exception ex2) {}
ServletOps.errorOccurred(ex.getMessage()) ;
- return existedBefore ;
+ return null ;
} finally { action.endWrite() ; }
}
Modified: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java?rev=1602204&r1=1602203&r2=1602204&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java (original)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/ServletOps.java Thu Jun 12 15:30:34 2014
@@ -159,13 +159,23 @@ public class ServletOps {
response.setHeader(HttpNames.hPragma, "no-cache");
}
- /** Send a JSON value as a 200 response. Null objetc means no response body and no content-type headers. */
+ /** Send a JSON value as a 200 response. Null object means no response body and no content-type headers. */
public static void sendJsonReponse(HttpAction action, JsonValue v) {
if ( v == null ) {
ServletOps.success(action);
+ //ServletOps.successNoContent(action);
return ;
}
+ ServletOps.success(action);
+ sendJson(action, v) ;
+ }
+
+ /** Send a JSON value as a 200 response. Null object means no response body and no content-type headers. */
+ public static void sendJson(HttpAction action, JsonValue v) {
+ if ( v == null )
+ return ;
+
try {
HttpServletResponse response = action.response ;
ServletOutputStream out = response.getOutputStream() ;
@@ -174,10 +184,9 @@ public class ServletOps {
JSON.write(out, v) ;
out.println() ;
out.flush() ;
- ServletOps.success(action);
} catch (IOException ex) { ServletOps.errorOccurred(ex) ; }
}
-
+
}
Modified: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/Upload.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/Upload.java?rev=1602204&r1=1602203&r2=1602204&view=diff
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/Upload.java (original)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/Upload.java Thu Jun 12 15:30:34 2014
@@ -20,6 +20,7 @@ package org.apache.jena.fuseki.servlets;
import static java.lang.String.format ;
import static org.apache.jena.riot.WebContent.ctMultipartFormData ;
+import static org.apache.jena.riot.WebContent.ctTextPlain ;
import static org.apache.jena.riot.WebContent.matchContentType ;
import java.io.IOException ;
@@ -35,42 +36,45 @@ import org.apache.jena.fuseki.FusekiLib
import org.apache.jena.riot.Lang ;
import org.apache.jena.riot.RDFLanguages ;
import org.apache.jena.riot.RiotParseException ;
-import static org.apache.jena.riot.WebContent.* ;
import org.apache.jena.riot.lang.StreamRDFCounting ;
import org.apache.jena.riot.system.StreamRDF ;
import org.apache.jena.riot.system.StreamRDFLib ;
public class Upload {
- public static void incomingData(HttpAction action, StreamRDF dest, boolean isGraph) {
+ public static UploadDetails incomingData(HttpAction action, StreamRDF dest) {
ContentType ct = FusekiLib.getContentType(action) ;
if ( matchContentType(ctMultipartFormData, ct) ) {
- fileUploadWorker(action, dest, isGraph) ;
- return ;
+ return fileUploadWorker(action, dest) ;
}
// Single graph (or quads) in body.
- String base = ActionLib.wholeRequestURL(action.request) ; // XXX Actually wrong?!
+ String base = ActionLib.wholeRequestURL(action.request) ;
Lang lang = RDFLanguages.contentTypeToLang(ct.getContentType()) ;
if ( lang == null ) {
ServletOps.errorBadRequest("Unknown content type for triples: " + ct) ;
- return ;
+ return null ;
}
InputStream input = null ;
try { input = action.request.getInputStream() ; }
catch (IOException ex) { IO.exception(ex) ; }
int len = action.request.getContentLength() ;
- if ( action.verbose ) {
- if ( len >= 0 )
- action.log.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s", action.id, len,
- ct.getContentType(), ct.getCharset(), lang.getName())) ;
- else
- action.log.info(format("[%d] Body: Content-Type=%s, Charset=%s => %s", action.id, ct.getContentType(),
- ct.getCharset(), lang.getName())) ;
+
+ StreamRDFCounting countingDest = StreamRDFLib.count(dest) ;
+ try {
+ ActionSPARQL.parse(action, countingDest, input, lang, base) ;
+ UploadDetails details = new UploadDetails(countingDest.count(), countingDest.countTriples(),countingDest.countQuads()) ;
+ action.log.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s : %s",
+ action.id, len, ct.getContentType(), ct.getCharset(), lang.getName(),
+ details.detailsStr())) ;
+ return details ;
+ } catch (RiotParseException ex) {
+ action.log.info(format("[%d] Body: Content-Length=%d, Content-Type=%s, Charset=%s => %s : %s",
+ action.id, len, ct.getContentType(), ct.getCharset(), lang.getName(),
+ ex.getMessage())) ;
+ throw ex ;
}
-
- ActionSPARQL.parse(action, dest, input, lang, base) ;
}
/** Process an HTTP upload of RDF files (triples or quads)
@@ -78,9 +82,8 @@ public class Upload {
* is known at the start of the multipart file body
*/
- public static void fileUploadWorker(HttpAction action, StreamRDF dest, boolean isGraph) {
+ public static UploadDetails fileUploadWorker(HttpAction action, StreamRDF dest) {
String base = ActionLib.wholeRequestURL(action.request) ;
- String item = (isGraph)?"triple":"quad" ;
ServletFileUpload upload = new ServletFileUpload();
long count = -1 ;
@@ -126,11 +129,11 @@ public class Upload {
StreamRDFCounting countingDest = StreamRDFLib.count(dest) ;
try {
ActionSPARQL.parse(action, countingDest, stream, lang, base);
- long c = countingDest.count() ;
-
- action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s : %d %s%s",
+ UploadDetails details = new UploadDetails(countingDest.count(), countingDest.countTriples(),countingDest.countQuads()) ;
+ action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s : %s",
action.id, printfilename, ct.getContentType(), ct.getCharset(), lang.getName(),
- c, item, (c==1)?"":"s")) ;
+ details.detailsStr())) ;
+ return details ;
} catch (RiotParseException ex) {
action.log.info(format("[%d] Filename: %s, Content-Type=%s, Charset=%s => %s : %s",
action.id, printfilename, ct.getContentType(), ct.getCharset(), lang.getName(),
@@ -141,6 +144,7 @@ public class Upload {
}
catch (ActionErrorException ex) { throw ex ; }
catch (Exception ex) { ServletOps.errorOccurred(ex.getMessage()) ; }
+ return null ;
}
}
Added: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java?rev=1602204&view=auto
==============================================================================
--- jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java (added)
+++ jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java Thu Jun 12 15:30:34 2014
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.fuseki.servlets;
+
+import org.apache.jena.atlas.json.JsonBuilder ;
+import org.apache.jena.atlas.json.JsonValue ;
+
+/** Record of an upload */
+public class UploadDetails {
+ public enum PreState { EXISTED, ABSENT, UNKNOWN }
+
+ private final long count ;
+ private final long tripleCount ;
+ private final long quadCount ;
+ private PreState state = PreState.UNKNOWN ;
+
+ /*package*/ UploadDetails(long parserCount, long parserTripleCount, long parserQuadCount) {
+ this.count = parserCount ;
+ this.tripleCount = parserTripleCount ;
+ this.quadCount = parserQuadCount ;
+ }
+
+ public String detailsStr() {
+ return String.format("Count=%d Triples=%d Quads=%d", count, tripleCount, quadCount) ;
+ }
+
+ public static String jCount = "count" ;
+ public static String jTriplesCount = "tripleCount" ;
+ public static String jQuadsCount = "quadCount" ;
+
+ public JsonValue detailsJson() {
+ JsonBuilder b = new JsonBuilder() ;
+ b.startObject("details") ;
+ b.key(jCount).value(count) ;
+ b.key(jTriplesCount).value(tripleCount) ;
+ b.key(jQuadsCount).value(quadCount) ;
+ b.finishObject("details") ;
+ return b.build() ;
+ }
+
+ public long getCount() {
+ return count ;
+ }
+
+ public long getTripleCount() {
+ return tripleCount ;
+ }
+
+ public long getQuadCount() {
+ return quadCount ;
+ }
+
+ public void setExistedBefore(boolean existedBefore) {
+ if ( existedBefore )
+ setExistedBefore(PreState.EXISTED) ;
+ else
+ setExistedBefore(PreState.ABSENT) ;
+ }
+ public void setExistedBefore(PreState state) { this.state = state ; }
+
+ public PreState getExistedBefore() { return state ; }
+}
Propchange: jena/Experimental/jena-fuseki2/src/main/java/org/apache/jena/fuseki/servlets/UploadDetails.java
------------------------------------------------------------------------------
svn:mime-type = text/plain