jena-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject [3/5] jena git commit: JENA-1150: Better dispatch for actions directed on the dataset URL.
Date Sat, 27 Feb 2016 17:55:19 GMT
JENA-1150: Better dispatch for actions directed on the dataset URL.

To include SPARQL Update.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/8e7f737f
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/8e7f737f
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/8e7f737f

Branch: refs/heads/master
Commit: 8e7f737fa0d71ceed002282c4eca7fc3a5d843ea
Parents: 0f48af3
Author: Andy Seaborne <andy@apache.org>
Authored: Sat Feb 27 17:37:11 2016 +0000
Committer: Andy Seaborne <andy@apache.org>
Committed: Sat Feb 27 17:40:32 2016 +0000

----------------------------------------------------------------------
 .../java/org/apache/jena/riot/web/HttpOp.java   | 109 +++++++++++--
 .../fuseki/servlets/SPARQL_UberServlet.java     |  98 +++++++-----
 .../java/org/apache/jena/fuseki/TS_Fuseki.java  |   1 +
 .../apache/jena/fuseki/TestHttpOperations.java  | 158 +++++++++++++++++++
 4 files changed, 314 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/8e7f737f/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
index 67bcf87..32a9224 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/web/HttpOp.java
@@ -497,6 +497,22 @@ public class HttpOp {
     }
 
     /**
+     * Execute a HTTP POST and return the typed return stream.
+     * 
+     * @param url
+     *            URL
+     * @param contentType
+     *            Content Type to POST
+     * @param content
+     *            Content to POST
+     * @param acceptType
+     *            Accept Type
+     */
+    public static TypedInputStream execHttpPostStream(String url, String contentType, String
content, String acceptType) {
+        return execHttpPostStream(url, contentType, content, acceptType, null, null, null)
;
+    }
+
+    /**
      * Executes a HTTP POST with a string as the request body and response
      * handling
      * 
@@ -514,10 +530,24 @@ public class HttpOp {
      *            HTTP Authenticator
      */
     public static void execHttpPost(String url, String contentType, String content, HttpClient
httpClient,
-            HttpContext httpContext, HttpAuthenticator authenticator) {
+                                    HttpContext httpContext, HttpAuthenticator authenticator)
{
         execHttpPost(url, contentType, content, null, nullHandler, httpClient, httpContext,
authenticator);
     }
 
+    public static TypedInputStream execHttpPostStream(String url, String contentType, String
content, String acceptType,
+                                                      HttpClient httpClient, HttpContext
httpContext, HttpAuthenticator authenticator) {
+        CaptureInput handler = new CaptureInput();
+        try {
+            execHttpPost(url, contentType, content, acceptType, handler, httpClient, httpContext,
authenticator);
+        } catch (HttpException ex) {
+            if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
+                return null;
+            throw ex;
+        }
+        return handler.get();
+    }
+
+    
     /**
      * Executes a HTTP POST with a string as the request body and response
      * handling
@@ -552,6 +582,19 @@ public class HttpOp {
         }
     }
 
+    //    
+//        
+//        StringEntity e = null;
+//        try {
+//            e = new StringEntity(content, StandardCharsets.UTF_8);
+//            e.setContentType(contentType);
+//            return execHttpPostStream(url, e, acceptType, null, null, null) ;
+//        }
+//        finally {
+//            closeEntity(e);
+//        }
+//    }
+
     /**
      * Executes a HTTP POST with a request body from an input stream without
      * response body with no response handling
@@ -646,6 +689,20 @@ public class HttpOp {
     }
 
     /**
+     * Execute a HTTP POST and return the typed return stream.
+     * 
+     * @param url
+     *            URL
+     * @param entity
+     *            Entity to POST
+     */
+    public static TypedInputStream execHttpPostStream(String url, HttpEntity entity, String
acceptHeader) {
+        CaptureInput handler = new CaptureInput();
+        execHttpPost(url, entity, acceptHeader, handler);
+        return handler.get() ;
+    }
+
+    /**
      * Executes a HTTP Post
      * 
      * @param url
@@ -700,6 +757,34 @@ public class HttpOp {
      *            Entity to POST
      * @param acceptHeader
      *            Accept Header
+     * @param httpClient
+     *            HTTP Client
+     * @param httpContext
+     *            HTTP Context
+     * @param authenticator
+     *            HTTP Authenticator
+     */
+    public static TypedInputStream execHttpPostStream(String url, HttpEntity entity, String
acceptHeader,
+                                    HttpClient httpClient, HttpContext httpContext, HttpAuthenticator
authenticator) {
+        CaptureInput handler = new CaptureInput();
+        execHttpPost(url, entity, acceptHeader, handler, httpClient, httpContext, authenticator)
;
+        return handler.get() ;
+    }
+
+    /**
+     * POST with response body.
+     * <p>
+     * The content for the POST body comes from the HttpEntity.
+     * <p>
+     * Additional headers e.g. for authentication can be injected through an
+     * {@link HttpContext}
+     * 
+     * @param url
+     *            URL
+     * @param entity
+     *            Entity to POST
+     * @param acceptHeader
+     *            Accept Header
      * @param handler
      *            Response handler called to process the response
      * @param httpClient
@@ -717,35 +802,39 @@ public class HttpOp {
             httppost.setEntity(entity);
         exec(url, httppost, acceptHeader, handler, httpClient, httpContext, authenticator);
     }
-
+    
+    
+    
     // ---- HTTP POST as a form.
 
     /**
-     * Executes a HTTP POST and returns a TypedInputStream, The TypedInputStream
-     * must be closed.
+     * Executes a HTTP POST.
      * 
      * @param url
      *            URL
      * @param params
      *            Parameters to POST
-     * @param acceptHeader
      */
-    public static TypedInputStream execHttpPostFormStream(String url, Params params, String
acceptHeader) {
-        return execHttpPostFormStream(url, params, acceptHeader, null, null, null);
+    public static void execHttpPostForm(String url, Params params) {
+        execHttpPostForm(url, params, null, nullHandler);
     }
 
     /**
-     * Executes a HTTP POST.
+     * Executes a HTTP POST and returns a TypedInputStream, The TypedInputStream
+     * must be closed.
      * 
      * @param url
      *            URL
      * @param params
      *            Parameters to POST
+     * @param acceptHeader
      */
-    public static void execHttpPostForm(String url, Params params) {
-        execHttpPostForm(url, params, null, nullHandler);
+    public static TypedInputStream execHttpPostFormStream(String url, Params params, String
acceptHeader) {
+        return execHttpPostFormStream(url, params, acceptHeader, null, null, null);
     }
 
+    
+
     // @formatter:off
 //    /**
 //     * Executes a HTTP POST Form.

http://git-wip-us.apache.org/repos/asf/jena/blob/8e7f737f/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
index 7b116c3..2b41487 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
@@ -118,7 +118,7 @@ public abstract class SPARQL_UberServlet extends ActionSPARQL
     private final ActionSPARQL uploadServlet   = new SPARQL_Upload() ;
     private final ActionSPARQL gspServlet_R    = new SPARQL_GSP_R() ;
     private final ActionSPARQL gspServlet_RW   = new SPARQL_GSP_RW() ;
-    private final ActionSPARQL restQuads_R     = new REST_Quads_R() ; // XXX
+    private final ActionSPARQL restQuads_R     = new REST_Quads_R() ;
     private final ActionSPARQL restQuads_RW    = new REST_Quads_RW() ;
 
     public SPARQL_UberServlet() { super(); }
@@ -153,6 +153,10 @@ public abstract class SPARQL_UberServlet extends ActionSPARQL
      */
     @Override
     protected void executeAction(HttpAction action) {
+        
+        //SPARQL Update direct
+        //SPARQL Query POST
+        
         long id = action.id ;
         HttpServletRequest request = action.request ;
         HttpServletResponse response = action.response ;
@@ -171,28 +175,70 @@ public abstract class SPARQL_UberServlet extends ActionSPARQL
 
         boolean hasParams = request.getParameterMap().size() > 0 ;
 
+        // Is it a query or update because of a ?query= , ?request= parameter? 
         // Test for parameters - includes HTML forms.
-        boolean hasParamQuery           = request.getParameter(HttpNames.paramQuery) != null
;
+        boolean isQuery           = request.getParameter(HttpNames.paramQuery) != null ;
         // Include old name "request="
-        boolean hasParamUpdate          = request.getParameter(HttpNames.paramUpdate) !=
null || request.getParameter(HttpNames.paramRequest) != null ;
+        boolean isUpdate          = request.getParameter(HttpNames.paramUpdate) != null ||
request.getParameter(HttpNames.paramRequest) != null ;
+
         boolean hasParamGraph           = request.getParameter(HttpNames.paramGraph) != null
;
         boolean hasParamGraphDefault    = request.getParameter(HttpNames.paramGraphDefault)
!= null ;
 
+        boolean hasTrailing = ( trailing.length() != 0 ) ;
+        
         String ct = request.getContentType() ;
         String charset = request.getCharacterEncoding() ;
 
         MediaType mt = null ;
-        if ( ct != null )
+        if ( ct != null ) {
+            // Parse it.
             mt = MediaType.create(ct, charset) ;
-
+            // Another way to send queries and updates is with the content-type. 
+            if ( contentTypeSPARQLQuery.equalsIgnoreCase(ct) )
+                isQuery = true ;
+            else if ( contentTypeSPARQLUpdate.equalsIgnoreCase(ct) )
+                isUpdate = true ;
+        }
+            
         if (action.log.isInfoEnabled() ) {
             //String cxt = action.getContextPath() ;
             action.log.info(format("[%d] %s %s :: '%s' :: %s ? %s", id, method, desc.getName(),
trailing, (mt==null?"<none>":mt), (qs==null?"":qs))) ;
         }
+        
+        if ( !hasTrailing ) {
+            // Nothing after the DataAccessPoint i.e. Dataset by name.
+            // Action on the dataset itself. This can be:
+            //   http://localhost:3030/ds?query=
+            //   http://localhost:3030/ds and a content type.
+            //   http://localhost:3030/ds?default ?graph=  GSP  
+            //   http://localhost:3030/ds , REST quads action on the dataset itself.
+            if ( isQuery ) {
+                if ( !allowQuery(action) )
+                    ServletOps.errorMethodNotAllowed("SPARQL query : "+method) ;
+                executeRequest(action, queryServlet) ;
+                return ;
+            }
 
-        boolean hasTrailing = ( trailing.length() != 0 ) ;
+            if ( isUpdate ) {
+                // SPARQL Update
+                if ( !allowUpdate(action) )
+                    ServletOps.errorMethodNotAllowed("SPARQL update : "+method) ;
+                // This wil dela with using GET.
+                executeRequest(action, updateServlet) ;
+                return ;
+            }
+
+            // ?graph=, ?default
+            if ( hasParamGraph || hasParamGraphDefault ) {
+                doGraphStoreProtocol(action) ;
+                return ;
+            }
 
-        if ( !hasTrailing && !hasParams ) {
+            if ( hasParams ) {
+                // Unrecognized ?key=value
+                ServletOps.errorBadRequest("Malformed request") ;
+            }
+            
             // REST dataset.
             boolean isGET = method.equals(HttpNames.METHOD_GET) ;
             boolean isHEAD = method.equals(HttpNames.METHOD_HEAD) ;
@@ -206,7 +252,7 @@ public abstract class SPARQL_UberServlet extends ActionSPARQL
                 return ;
             }
             // If the read-only server has the same name as the writable server,
-            // and the default fro a read-only server is "/data", like a writable dataset,
+            // and the default for a read-only server is "/data", like a writable dataset,
             // this test is insufficient.
             if ( allowREST_W(action) )
                 restQuads_RW.executeLifecycle(action) ;
@@ -215,40 +261,8 @@ public abstract class SPARQL_UberServlet extends ActionSPARQL
             return ;
         }
 
-        if ( !hasTrailing ) {
-            boolean isPOST = action.getRequest().getMethod().equals(HttpNames.METHOD_POST)
;
-            // Nothing after the DataAccessPoint i.e Dataset by name.
-            // e.g.  http://localhost:3030/ds?query=
-            // Query - GET or POST.
-            // Query - ?query= or body of application/sparql-query
-            if ( hasParamQuery || ( isPOST && contentTypeSPARQLQuery.equalsIgnoreCase(ct)
) ) {
-                // SPARQL Query
-                if ( !allowQuery(action) )
-                    ServletOps.errorMethodNotAllowed("SPARQL query : "+method) ;
-                executeRequest(action, queryServlet) ;
-                return ;
-            }
-
-            // Insist on POST for update.
-            // Update - ?update= or body of application/sparql-update
-            if ( isPOST && ( hasParamUpdate || contentTypeSPARQLUpdate.equalsIgnoreCase(ct)
) ) {
-                // SPARQL Update
-                if ( !allowUpdate(action) )
-                    ServletOps.errorMethodNotAllowed("SPARQL update : "+method) ;
-                executeRequest(action, updateServlet) ;
-                return ;
-            }
-
-            // ?graph=, ?default
-            if ( hasParamGraph || hasParamGraphDefault ) {
-                doGraphStoreProtocol(action) ;
-                return ;
-            }
-
-            ServletOps.errorBadRequest("Malformed request") ;
-            ServletOps.errorMethodNotAllowed("SPARQL Graph Store Protocol : "+method) ;
-        }
-
+        // Has trailing path name => service or direct naming GSP.
+        
         final boolean checkForPossibleService = true ;
         if ( checkForPossibleService && action.getEndpoint() != null ) {
             // There is a trailing part.

http://git-wip-us.apache.org/repos/asf/jena/blob/8e7f737f/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java
b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java
index 2094755..cdbb629 100644
--- a/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java
+++ b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java
@@ -34,6 +34,7 @@ import org.junit.runners.Suite ;
 @Suite.SuiteClasses( {
     TestHttpOp.class
     , TestSPARQLProtocol.class
+    , TestHttpOperations.class
     , TestHttpOptions.class
     , TestDatasetGraphAccessorHTTP.class
     , TestDatasetAccessorHTTP.class

http://git-wip-us.apache.org/repos/asf/jena/blob/8e7f737f/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestHttpOperations.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestHttpOperations.java
b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestHttpOperations.java
new file mode 100644
index 0000000..5042576
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/test/java/org/apache/jena/fuseki/TestHttpOperations.java
@@ -0,0 +1,158 @@
+/*
+ * 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 ;
+
+import static org.apache.jena.fuseki.ServerTest.* ;
+import static org.apache.jena.fuseki.ServerTest.serviceUpdate ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.atlas.web.HttpException ;
+import org.apache.jena.atlas.web.TypedInputStream ;
+import org.apache.jena.riot.WebContent ;
+import org.apache.jena.riot.web.HttpOp ;
+import org.apache.jena.sparql.engine.http.Params ;
+import org.apache.jena.sparql.util.Convert ;
+import org.junit.AfterClass ;
+import org.junit.Assert ;
+import org.junit.BeforeClass ;
+import org.junit.Test ;
+
+/** Operation by HTTP - test dispatch - lower level than TestSPARQLProtocol */
+public class TestHttpOperations extends BaseTest {
+    @BeforeClass
+    public static void beforeClass() {
+        ServerTest.allocServer() ;
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        ServerTest.freeServer() ;
+    }
+    
+    // XXX and directly on dataset
+    
+    @Test 
+    public void query_by_get_1() {
+        String qs = Convert.encWWWForm("ASK{}") ;
+        String u = serviceQuery+"?query=" + qs ;
+        try (TypedInputStream in = HttpOp.execHttpGet(u)) {
+            Assert.assertNotNull(in);
+        }
+    }
+    
+    @Test 
+    public void query_by_post_1() {
+        String u = serviceQuery ;
+        try (TypedInputStream in = HttpOp.execHttpPostStream(u, WebContent.contentTypeSPARQLQuery,
"ASK{}", "*")) {
+            Assert.assertNotNull(in);
+        }
+    }
+
+    @Test 
+    public void query_by_post_2() {
+        String qs = Convert.encWWWForm("ASK{}") ;
+        String u = serviceQuery+"?query=" + qs ;
+        try (TypedInputStream in = HttpOp.execHttpPostStream(u, null, null)) {
+            Assert.assertNotNull(in);
+        }
+    }
+
+    @Test 
+    public void query_by_form_1() {
+        String qs = Convert.encWWWForm("ASK{}") ;
+        String u = serviceQuery ;
+        Params params = new Params();
+        params.addParam("query", "ASK{}") ;
+        try (TypedInputStream in = HttpOp.execHttpPostFormStream(u, params, "*") ) { 
+            Assert.assertNotNull(in);
+        }
+    }
+
+    @Test(expected=HttpException.class) 
+    public void query_by_form_2() {
+        String u = serviceQuery ;
+        Params params = new Params();
+        params.addParam("foobar", "ASK{}") ;    // Wrong.
+        try (TypedInputStream in = HttpOp.execHttpPostFormStream(u, params, "*") ) { 
+            Assert.assertNotNull(in);
+        }
+    }
+
+    @Test 
+    public void update_by_post_1() {
+        String u = serviceUpdate ;
+        HttpOp.execHttpPost(u, WebContent.contentTypeSPARQLUpdate, "INSERT DATA{}") ;
+    }
+
+    // POST ?request= :: Not supported.
+//    @Test 
+//    public void update_by_post_2() {
+//        String us = Convert.encWWWForm("INSERT DATA {}") ;
+//        String u = serviceUpdate+"?update=" + us ;
+//        try (TypedInputStream in = HttpOp.execHttpPostStream(u, null, null)) {
+//            Assert.assertNotNull(in);
+//        }
+//    }
+
+    @Test
+    public void update_by_form_1() {
+        String u = serviceUpdate ;
+        Params params = new Params();
+        params.addParam("update", "INSERT DATA{}") ;
+        try (TypedInputStream in = HttpOp.execHttpPostFormStream(u, params, "*") ) { 
+            Assert.assertNotNull(in);
+        }
+    }
+    
+    @Test(expected=HttpException.class)
+    public void update_by_form_2() {
+        String u = serviceUpdate ;
+        Params params = new Params();
+        params.addParam("query", "INSERT DATA{}") ;  // Wrong paramater
+        try (TypedInputStream in = HttpOp.execHttpPostFormStream(u, params, "*") ) { 
+            Assert.assertNotNull(in);
+        }
+    }
+
+    // ---- Dataset direct
+    
+    @Test 
+    public void ds_query_by_get_1() {
+        String qs = Convert.encWWWForm("ASK{}") ;
+        String u = urlDataset ;
+        try (TypedInputStream in = HttpOp.execHttpGet(u)) {
+            Assert.assertNotNull(in);
+        }
+    }
+
+    @Test 
+    public void ds_query_by_post_1() {
+        String u = urlDataset ;
+        try (TypedInputStream in = HttpOp.execHttpPostStream(u, WebContent.contentTypeSPARQLQuery,
"ASK{}", "*")) {
+            Assert.assertNotNull(in);
+        }
+    }
+    
+    @Test 
+    public void ds_update_by_post_1() {
+        String u = urlDataset ;
+        HttpOp.execHttpPost(u, WebContent.contentTypeSPARQLUpdate, "INSERT DATA{}") ;
+    }
+
+}


Mime
View raw message