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 2012/08/31 14:03:58 UTC

svn commit: r1379425 - in /jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki: server/SPARQLServer.java servlets/SPARQL_REST.java servlets/SPARQL_ServletBase.java servlets/SPARQL_UberServlet.java servlets/ServletBase.java

Author: andy
Date: Fri Aug 31 12:03:57 2012
New Revision: 1379425

URL: http://svn.apache.org/viewvc?rev=1379425&view=rev
Log:
Make the general dispatch server sensitive to the dataset configuration.

Modified:
    jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java
    jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_REST.java
    jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java
    jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
    jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java

Modified: jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java?rev=1379425&r1=1379424&r2=1379425&view=diff
==============================================================================
--- jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java (original)
+++ jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/server/SPARQLServer.java Fri Aug 31 12:03:57 2012
@@ -229,11 +229,10 @@ public class SPARQLServer
         HttpServlet sparqlUpload    = new SPARQL_Upload(verboseLogging) ;
         HttpServlet sparqlHttpR     = new SPARQL_REST_R(verboseLogging) ;  
         HttpServlet sparqlHttpRW    = new SPARQL_REST_RW(verboseLogging) ;
-        HttpServlet sparqlDataset   = new SPARQL_UberServlet(verboseLogging) ;
+        HttpServlet sparqlDataset   = new SPARQL_UberServlet.AccessByConfig(verboseLogging) ;
 
-        // The überservlet sits on the daatset name and handles all requests.
-        // Includes direct naming.
-        // Need to control as it allows PUT/POST to the dataset as quads.
+        // The überservlet sits on the dataset name and handles all requests.
+        // Includes direct naming and quad access to the dataset.
         final boolean überServlet = false ;
         
         if ( ! überServlet )

Modified: jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_REST.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_REST.java?rev=1379425&r1=1379424&r2=1379425&view=diff
==============================================================================
--- jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_REST.java (original)
+++ jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_REST.java Fri Aug 31 12:03:57 2012
@@ -64,9 +64,8 @@ public abstract class SPARQL_REST extend
     
     protected static ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(log) ;
 
-    public static class HttpActionREST extends HttpAction {
-        
-        // Special ; direct.
+    public static class HttpActionREST extends HttpAction
+    {
         HttpActionREST(long id, DatasetRef desc, String absUri, HttpServletRequest request, HttpServletResponse response, boolean verbose)
         {
             super(id, desc, request, response, verbose) ;
@@ -82,9 +81,9 @@ public abstract class SPARQL_REST extend
 
         protected final boolean hasTarget()
         {
-            return 
-                request.getParameter(HttpNames.paramGraphDefault) == null &&
-                request.getParameter(HttpNames.paramGraph) == null ;
+            return true ;
+//                request.getParameter(HttpNames.paramGraphDefault) == null &&
+//                request.getParameter(HttpNames.paramGraph) == null ;
         }
         
         protected final Target getTarget() 
@@ -198,11 +197,17 @@ public abstract class SPARQL_REST extend
     protected void perform(long id, DatasetRef desc, HttpServletRequest request, HttpServletResponse response)
     {
         validate(request) ;
+        
+//        // Decide on t 
+//        String uri = request.getRequestURI() ;
+//        String method = request.getMethod() ;
+//        String dsname = findDataset(uri) ;
+//        String trailing = uri.substring(dsname.length()+1) ;    // Skip the "/"
+//        String qs = request.getQueryString() ;
+
         //Indirect
         HttpActionREST action = new HttpActionREST(id, desc, request, response, verbose_debug) ;
-        
         // Direct 
-        
         dispatch(action) ;
     }
 
@@ -272,7 +277,7 @@ public abstract class SPARQL_REST extend
                 errorOccurred("Dataset does not have a default graph") ;
             log.info(format("[%d] Creating in-memory graph for <%s>", action.id, dest.graphName)) ;
             // Not default graph.
-            // Not an autocreate dataset - create something.
+            // Not an autocreate dataset -               create something.
             g = GraphFactory.createDefaultGraph() ;
             dest.dsg.addGraph(dest.graphName, g) ;
         }
@@ -327,7 +332,7 @@ public abstract class SPARQL_REST extend
                     // Without content length, reading to send of file is occassionaly fraught.
                     // Reason unknown - maybe some client mishandling of the stream. 
                     String x = FileUtils.readWholeFileAsUTF8(input) ;
-                    System.out.println(x) ;
+                    //System.out.println(x) ;
                     input = new ByteArrayInputStream(x.getBytes("UTF-8")) ; 
                 }
             }
@@ -355,8 +360,10 @@ public abstract class SPARQL_REST extend
     @Override
     protected void validate(HttpServletRequest request)
     {
+        // Direct naming.
         if ( request.getQueryString() == null )
-            errorBadRequest("No query string") ;
+            //errorBadRequest("No query string") ;
+            return ;
         
         String g = request.getParameter(HttpNames.paramGraph) ;
         String d = request.getParameter(HttpNames.paramGraphDefault) ;

Modified: jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java?rev=1379425&r1=1379424&r2=1379425&view=diff
==============================================================================
--- jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java (original)
+++ jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_ServletBase.java Fri Aug 31 12:03:57 2012
@@ -188,7 +188,8 @@ public abstract class SPARQL_ServletBase
     /** A possible implementation for mapRequestToDataset(String)
      *  that assums the form /dataset/service 
      */
-    protected String mapRequestToDataset$(String uri)
+    
+    protected static String mapRequestToDataset$(String uri)
     {
         // Chop off trailing part - the service selector
         // e.f. /dataset/sparql => /dataset 
@@ -201,6 +202,6 @@ public abstract class SPARQL_ServletBase
         
         return uri.substring(0, i) ;
     }
-
+    
     protected abstract void perform(long id, DatasetRef desc, HttpServletRequest request, HttpServletResponse response) ;
 }

Modified: jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java?rev=1379425&r1=1379424&r2=1379425&view=diff
==============================================================================
--- jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java (original)
+++ jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_UberServlet.java Fri Aug 31 12:03:57 2012
@@ -38,11 +38,55 @@ import org.openjena.atlas.web.MediaType 
 import org.openjena.riot.WebContent ;
 
 /** This servlet can be attached to a dataset location
- *  and acts as a router for all SPARQL operations
+ *  and acts as a falserouter for all SPARQL operations
  *  (query, update, graph store, both direct and indirect naming). 
  */
-public class SPARQL_UberServlet extends SPARQL_ServletBase
+public abstract class SPARQL_UberServlet extends SPARQL_ServletBase
 {
+    protected abstract boolean allowQuery(HttpAction action) ;
+    protected abstract boolean allowUpdate(HttpAction action) ;
+    protected abstract boolean allowREST_R(HttpAction action) ;
+    protected abstract boolean allowREST_W(HttpAction action) ;
+    protected abstract boolean allowQuadsR(HttpAction action) ;
+    protected abstract boolean allowQuadsW(HttpAction action) ;
+    
+    public static class ReadOnly extends SPARQL_UberServlet
+    {
+        public ReadOnly(boolean verbose_debug) { super(verbose_debug) ; }
+        @Override protected boolean allowQuery(HttpAction action)    { return true ; }
+        @Override protected boolean allowUpdate(HttpAction action)   { return false ; }
+        @Override protected boolean allowREST_R(HttpAction action)   { return true ; }
+        @Override protected boolean allowREST_W(HttpAction action)   { return false ; }
+        @Override protected boolean allowQuadsR(HttpAction action)   { return true ; }
+        @Override protected boolean allowQuadsW(HttpAction action)   { return false ; }
+    }
+    
+    public static class ReadWrite extends SPARQL_UberServlet
+    {
+        public ReadWrite(boolean verbose_debug) { super(verbose_debug) ; }
+        @Override protected boolean allowQuery(HttpAction action)    { return true ; }
+        @Override protected boolean allowUpdate(HttpAction action)   { return true ; }
+        @Override protected boolean allowREST_R(HttpAction action)   { return true ; }
+        @Override protected boolean allowREST_W(HttpAction action)   { return true ; }
+        @Override protected boolean allowQuadsR(HttpAction action)   { return true ; }
+        @Override protected boolean allowQuadsW(HttpAction action)   { return true ; }
+    }
+    
+    public static class AccessByConfig extends SPARQL_UberServlet
+    {
+        public AccessByConfig(boolean verbose_debug) { super(verbose_debug) ; }
+        @Override protected boolean allowQuery(HttpAction action)    { return isEnabled(action.getDatasetRef().queryEP) ; }
+        @Override protected boolean allowUpdate(HttpAction action)   { return isEnabled(action.getDatasetRef().updateEP) ; }
+        @Override protected boolean allowREST_R(HttpAction action)   { return isEnabled(action.getDatasetRef().readGraphStoreEP) ; }
+        @Override protected boolean allowREST_W(HttpAction action)   { return isEnabled(action.getDatasetRef().readWriteGraphStoreEP) ; }
+        // Quad operations tied to presence/absence of GSP.
+        @Override protected boolean allowQuadsR(HttpAction action)   { return isEnabled(action.getDatasetRef().readGraphStoreEP) ; }
+        @Override protected boolean allowQuadsW(HttpAction action)   { return isEnabled(action.getDatasetRef().readWriteGraphStoreEP) ; }
+        
+        private boolean isEnabled(List<String> ep) { return ep.size() > 0 ; } 
+    }
+        
+    
     /*  This can be used for a single servlet for everything (über-servlet)
      *  
      *  It can check for a request that looks like a service request and passes it on.
@@ -64,22 +108,6 @@ public class SPARQL_UberServlet extends 
         super(verbose_debug) ;
     }
 
-    protected String findDataset(final String uri) 
-    {
-        // Find the dataset.
-        Iterator<String> datasets = DatasetRegistry.get().keys() ;
-        Filter<String> matchDS = new Filter<String>()
-            {
-                @Override
-                public boolean accept(String datasetname)
-                {
-                    return uri.startsWith(datasetname) ;
-                }
-            } ;
-        String ds = Iter.first(datasets, matchDS) ;
-        return ds ;
-    }
-
     private String getEPName(String dsname, List<String> endpoints)
     {
         if (endpoints == null || endpoints.size() == 0) return null ;
@@ -103,10 +131,11 @@ public class SPARQL_UberServlet extends 
         String uri = request.getRequestURI() ;
         String method = request.getMethod() ;
         String dsname = findDataset(uri) ;
-        String trailing = uri.substring(dsname.length()+1) ;    // Skip the "/"
+        String trailing = findTrailing(uri, dsname) ;
         String qs = request.getQueryString() ;
+
+        boolean hasParams = request.getParameterMap().size() > 0 ;
         
-        boolean hasParams               = request.getParameterMap().size() != 0 ;
         // Test for parameters - includes HTML forms.
         boolean hasParamQuery           = request.getParameter(HttpNames.paramQuery) != null ;
         // Include old name "request="
@@ -123,6 +152,9 @@ public class SPARQL_UberServlet extends 
             mt = MediaType.create(ct, charset) ;
         
         DatasetRef desc = DatasetRegistry.get().get(dsname) ;
+        // The servlets create their own, subclass, action, but it's 
+        // convenient to collect everything together. 
+        HttpAction action = new HttpAction(id, desc, request, response, verbose_debug) ;
         
         log.info(format("[%d] All: %S %s :: %s :: %s ? %s", id, method, dsname, trailing, (mt==null?"<none>":mt), (qs==null?"":qs))) ;
                        
@@ -141,25 +173,25 @@ public class SPARQL_UberServlet extends 
             // Has params of some kind.
             if ( hasParamQuery || WebContent.contentTypeSPARQLQuery.equalsIgnoreCase(ct) )
             {
-                // query
+                // SPARQL Query
+                if ( ! allowQuery(action))
+                    errorForbidden("Forbidden: SPARQL query") ; 
                 executeRequest(desc, queryServlet, desc.queryEP, id, request, response) ;
                 return ;
             }
                  
             if ( hasParamUpdate || WebContent.contentTypeSPARQLUpdate.equalsIgnoreCase(ct) )
             {
-                // update
+                // SPARQL Update
+                if ( ! allowQuery(action))
+                    errorForbidden("Forbidden: SPARQL query") ; 
                 executeRequest(desc, updateServlet, desc.updateEP, id, request, response) ;
                 return ;
             }
             
             if ( hasParamGraph || hasParamGraphDefault )
             {
-                // Indirct naming. Prefer the RW service if available.
-                if ( desc.readWriteGraphStoreEP.size() > 0 )
-                    executeRequest(desc, restServlet_RW, desc.readWriteGraphStoreEP, id, request, response) ;
-                else
-                    executeRequest(desc, restServlet_R, desc.readGraphStoreEP, id, request, response) ;
+                doGraphStoreProtocol(action) ;
                 return ;
             }
             
@@ -178,41 +210,41 @@ public class SPARQL_UberServlet extends 
             if ( checkDispatch(desc.readGraphStoreEP, trailing, restServlet_R, desc, id, request, response) ) return ; 
             if ( checkDispatch(desc.readWriteGraphStoreEP, trailing, restServlet_RW, desc, id, request, response) ) return ; 
         }       
-        // There is a trailing paSPARQL_RESTrt - params are illegal by this point.
+        // There is a trailing part - params are illegal by this point.
         if ( hasParams )
             // Revisit to include query-on-one-graph 
             errorBadRequest("Can't invoke a query-string service on a direct named graph") ; 
 
-        // There is a trailing part - not a service, no params ==> direct naming.
-        // Direct naming to indirect naming.
-        doDirectNaming(desc, id, request, response) ;
+        // There is a trailing part - not a service, no params ==> GSP direct naming.
+        doGraphStoreProtocol(action) ;
     }
     
-    private void doDirectNaming(DatasetRef desc , long id, HttpServletRequest request, HttpServletResponse response)
+    private void doGraphStoreProtocol(HttpAction action)
     {
-        if ( desc.readWriteGraphStoreEP.size() > 0 )
-            executeRequest(desc, restServlet_RW, desc.readWriteGraphStoreEP, id, request, response) ;
-        else if ( desc.readGraphStoreEP.size() > 0 )
-            executeRequest(desc, restServlet_R, desc.readGraphStoreEP, id, request, response) ;
-        else
-            errorMethodNotAllowed(request.getMethod()) ;
-
-        // If direct naming not supported by SPARQL_REST_*
-//        String uri = request.getRequestURI() ;
-//        String dsname = findDataset(uri) ;
-//        DatasetRef desc = DatasetRegistry.get().get(dsname) ;
-//        
-//        String absURI = request.getRequestURL().toString() ;
-//        HttpActionREST a = new HttpActionREST(id, desc, absURI, request, response, verbose_debug) ;
-//
-//        if ( desc.readWriteGraphStoreEP.size() > 0 )
-//            // ****
-//            restServlet_RW.dispatch(a) ;
-//        else if ( desc.readGraphStoreEP.size() > 0 )
-//            // ****
-//            restServlet_R.dispatch(a) ;
-//        else
-//            errorMethodNotAllowed(request.getMethod()) ;
+        // The GSP servlets handle direct and indirect naming. 
+        DatasetRef desc = action.getDatasetRef();
+        String method = action.request.getMethod() ;
+        
+        if ( HttpNames.METHOD_GET.equalsIgnoreCase(method) ||
+            HttpNames.METHOD_HEAD.equalsIgnoreCase(method) ) 
+       {
+           if ( ! allowREST_R(action))
+               errorForbidden("Forbidden: SPARQL Graph Store Protocol : Read operation : "+method) ;
+           // Graphs Store Protocol, indirect naming, read
+           // Indirect naming. Prefer the R service if available.
+           if ( desc.readGraphStoreEP.size() > 0 )
+               executeRequest(desc, restServlet_R, desc.readGraphStoreEP, action.id, action.request, action.response) ;
+           else if ( desc.readWriteGraphStoreEP.size() > 0 )
+               executeRequest(desc, restServlet_RW, desc.readWriteGraphStoreEP, action.id, action.request, action.response) ;
+           else
+               errorMethodNotAllowed(method) ;
+       }
+       
+       // Graphs Store Protocol, indirect naming, write
+       if ( ! allowREST_W(action))
+           errorForbidden("Forbidden: SPARQL Graph Store Protocol : Write operation : "+method) ;
+       executeRequest(desc, restServlet_RW, desc.readWriteGraphStoreEP, action.id, action.request, action.response) ;
+       return ;
     }
 
     private void executeRequest(DatasetRef desc, SPARQL_ServletBase servlet, List<String> endpointList, long id,
@@ -269,6 +301,31 @@ public class SPARQL_UberServlet extends 
         // Dummy - restructure SPARQL_ServletBase?
         error(HttpSC.INTERNAL_SERVER_ERROR_500, "Operation directed to general indirection servlet") ;
     }
+    
+    /** Find the dataset name even if direct naming */ 
+    protected static String findDataset(final String uri) 
+    {
+        // Find the dataset.
+        Iterator<String> datasets = DatasetRegistry.get().keys() ;
+        Filter<String> matchDS = new Filter<String>()
+            {
+                @Override
+                public boolean accept(String datasetname)
+                {
+                    return uri.startsWith(datasetname) ;
+                }
+            } ;
+        String ds = Iter.first(datasets, matchDS) ;
+        return ds ;
+    }
+
+    /** Find the dataset name even if direct naming */ 
+    protected static String findTrailing(String uri, String dsname) 
+    {
+        if ( dsname.length() >= uri.length() )
+            return "" ;
+        return uri.substring(dsname.length()+1) ;   // Skip the separating "/"
+    }
 
     @Override
     protected void doHead(HttpServletRequest request, HttpServletResponse response)

Modified: jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java?rev=1379425&r1=1379424&r2=1379425&view=diff
==============================================================================
--- jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java (original)
+++ jena/trunk/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java Fri Aug 31 12:03:57 2012
@@ -147,6 +147,14 @@ public abstract class ServletBase extend
         error(HttpSC.METHOD_NOT_ALLOWED_405, "HTTP method not allowed: "+method) ;
     }
 
+    protected static void errorForbidden(String msg)
+    {
+        if ( msg != null )
+            error(HttpSC.FORBIDDEN_403, msg) ;
+        else
+            error(HttpSC.FORBIDDEN_403, "Forbidden") ;
+    }
+    
     protected static void error(int statusCode)
     {
         throw new ActionErrorException(null, null, statusCode) ;