This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jena.git


The following commit(s) were added to refs/heads/master by this push:
     new 33bfa90  JENA-1671: Fix general query servlet.
     new 4e1e517  Merge pull request #531 from afs/fuseki-web-query
33bfa90 is described below

commit 33bfa90de9758d22ec49620f4c9db590ac7d0d45
Author: Andy Seaborne <[email protected]>
AuthorDate: Thu Feb 14 16:21:00 2019 +0000

    JENA-1671: Fix general query servlet.
    
    * direct servlet as ActionService
    * remove dataset description from query if processed
---
 .../access/AccessCtl_SPARQL_QueryDataset.java      | 14 ++--
 .../org/apache/jena/fuseki/server/Operation.java   |  9 ++-
 .../apache/jena/fuseki/servlets/ActionService.java | 35 +++++++--
 .../apache/jena/fuseki/servlets/SPARQL_Query.java  | 14 +++-
 .../jena/fuseki/servlets/SPARQL_QueryDataset.java  |  5 +-
 .../jena/fuseki/servlets/SPARQL_QueryGeneral.java  | 34 ++++++---
 .../apache/jena/fuseki/servlets/ServiceRouter.java |  2 +-
 .../apache/jena/fuseki/main/cmds/FusekiMain.java   |  5 +-
 .../{CustomService.java => CustomTestService.java} |  2 +-
 .../org/apache/jena/fuseki/main/TC_Fuseki.java     |  2 +-
 .../{TS_EmbeddedFuseki.java => TS_FusekiMain.java} | 10 +--
 .../fuseki/main/TestFusekiCustomOperation.java     | 36 ++++++++-
 .../apache/jena/fuseki/main/TestFusekiMainCmd.java | 85 ++++++++++++++++++++++
 .../{SpecialService.java => ExampleService.java}   |  2 +-
 .../main/examples/ExtendFuseki_AddService_1.java   |  4 +-
 .../main/examples/ExtendFuseki_AddService_2.java   |  2 +-
 .../main/examples/ExtendFuseki_AddService_3.java   |  4 +-
 17 files changed, 212 insertions(+), 53 deletions(-)

diff --git 
a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
 
b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
index 3788355..54948a9 100644
--- 
a/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
+++ 
b/jena-fuseki2/jena-fuseki-access/src/main/java/org/apache/jena/fuseki/access/AccessCtl_SPARQL_QueryDataset.java
@@ -25,6 +25,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
 
+import org.apache.jena.atlas.lib.Pair;
 import org.apache.jena.fuseki.servlets.ActionService;
 import org.apache.jena.fuseki.servlets.HttpAction;
 import org.apache.jena.fuseki.servlets.SPARQL_QueryDataset;
@@ -44,27 +45,28 @@ public class AccessCtl_SPARQL_QueryDataset extends 
SPARQL_QueryDataset {
     }
 
     private static boolean ALLOW_FROM = true; 
-    
+
     @Override
     protected Collection<String> customParams() {
         // The additional ?user.
         return Collections.singletonList("user");
     }
-    
+
     /** Decide the dataset - this modifies the query
      *  If the query has a dataset description.
      */
     @Override
-    protected DatasetGraph decideDataset(HttpAction action, Query query, 
String queryStringLog) {
+    protected Pair<DatasetGraph, Query> decideDataset(HttpAction action, Query 
query, String queryStringLog) {
         DatasetGraph dsg = action.getActiveDSG();
         if ( ! DataAccessCtl.isAccessControlled(dsg) )
             return super.decideDataset(action, query, queryStringLog);
-        
+
         DatasetDescription dsDesc0 = getDatasetDescription(action, query);
         SecurityContext sCxt = DataAccessLib.getSecurityContext(action, dsg, 
requestUser);
-        return dynamicDataset(action, query, dsg, dsDesc0, sCxt);
+        DatasetGraph dsg2 = dynamicDataset(action, query, dsg, dsDesc0, sCxt);
+        return Pair.create(dsg2,  query);
     }
-        
+
     private DatasetGraph dynamicDataset(HttpAction action, Query query, 
DatasetGraph dsg0, DatasetDescription dsDesc0, SecurityContext sCxt) {
         if ( dsDesc0 == null )
             return dsg0;
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
index 7037f0d..f9afc8a 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Operation.java
@@ -27,10 +27,15 @@ import 
org.apache.jena.fuseki.servlets.ServiceDispatchRegistry;
  */
 public class Operation {
     
-    // Create intern'ed symbols. 
+    /** Create/intern. */ 
     static private NameMgr<Operation> mgr = new NameMgr<>(); 
     static public Operation register(String name, String description) {
-        return mgr.register(name, (x)->new Operation(x, description));
+        return mgr.register(name, (x)->create(x, description));
+    }
+    
+    /** Create; not registered */
+    static private Operation create(String name, String description) {
+        return new Operation(name, description);
     }
     
     public static final Operation Query          = register("Query", "SPARQL 
Query");
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
index fe87407..c329cda 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ActionService.java
@@ -25,6 +25,8 @@ import static 
org.apache.jena.fuseki.server.CounterName.RequestsGood;
 
 import java.io.IOException;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.function.BiFunction;
 
 import javax.servlet.ServletException;
 
@@ -38,8 +40,26 @@ import org.apache.jena.web.HttpSC;
 
 /** Service request lifecycle */
 public abstract class ActionService extends ActionBase {
+    
+    private final BiFunction<HttpAction, Operation, ActionService> 
selectProcessor;
+
+    /**
+     * ActionService for a directly called serlvet. The request handler will be
+     * {@code this.executeLifecycle}.
+     */
     protected ActionService() {
         super(Fuseki.actionLog);
+        selectProcessor = (action, operation)->this;
+    }
+
+    /**
+     * ActionService to redirect to another ActionService to be request 
handler will be
+     * {@code selectProcessor.executeLifecycle}.
+     * @see ServiceRouter
+     */
+    protected ActionService(BiFunction<HttpAction, Operation, ActionService> 
selectProcessor) {
+        super(Fuseki.actionLog);
+        this.selectProcessor = selectProcessor;
     }
 
     protected abstract void validate(HttpAction action);
@@ -85,7 +105,7 @@ public abstract class ActionService extends ActionBase {
         String endpointName = mapRequestToOperation(action, dataAccessPoint);
         
         // ServiceRouter dispatch
-        Operation operation = null;
+        Operation operation;
         if ( !endpointName.isEmpty() ) {
             operation = chooseOperation(action, dSrv, endpointName);
             if ( operation == null )
@@ -96,8 +116,6 @@ public abstract class ActionService extends ActionBase {
         } else {
             // Endpoint ""
             operation = chooseOperation(action, dSrv);
-            if ( operation == null )
-                ServletOps.errorBadRequest(format("dataset=%s", 
dataAccessPoint.getName()));
         }
 
         // ---- Auth checking.
@@ -120,15 +138,18 @@ public abstract class ActionService extends ActionBase {
             // No Endpoint name given; there may be several endpoints for the 
operation.
             // authorization is the AND of all endpoints.
             Collection<Endpoint> x = getEndpoints(dSrv, operation);
-            if ( x.isEmpty() )
+            if ( operation != null && x.isEmpty() )
                 throw new InternalErrorException("Inconsistent: no endpoints 
for "+operation);
             x.forEach(ep->{
                 Auth.allow(user, ep.getAuthPolicy(), 
ServletOps::errorForbidden);
             });
         }
         // ---- End auth checking.
-
-        ActionService handler = 
action.getServiceDispatchRegistry().findHandler(operation);
+        
+        // Decide the code to execute the request.
+        // For ServiceRouter, this involves a lookup in the service dispatch 
registry.
+        // For directly called services, they override the operations called 
by this.executeLifecycle. 
+        ActionService handler = selectProcessor.apply(action, operation);
         if ( handler == null )
             ServletOps.errorBadRequest(format("dataset=%s: op=%s", 
dataAccessPoint.getName(), operation.getName()));
         handler.executeLifecycle(action);
@@ -140,6 +161,8 @@ public abstract class ActionService extends ActionBase {
     // If asked for GSP_R and there are no endpoints for GSP_R, try GSP_RW.
     // Ditto Quads_R -> Quads_RW.
     private Collection<Endpoint> getEndpoints(DataService dSrv, Operation 
operation) {
+        if ( operation == null )
+            return Collections.emptySet();
         Collection<Endpoint> x = dSrv.getEndpoints(operation);
         if ( x == null || x.isEmpty() ) {
             if ( operation == Operation.GSP_R )
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
index b69a336..3dc66a1 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java
@@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse ;
 import org.apache.jena.atlas.io.IO ;
 import org.apache.jena.atlas.io.IndentedLineBuffer ;
 import org.apache.jena.atlas.json.JsonObject;
+import org.apache.jena.atlas.lib.Pair;
 import org.apache.jena.atlas.web.ContentType ;
 import org.apache.jena.fuseki.Fuseki ;
 import org.apache.jena.fuseki.system.FusekiNetLib;
@@ -279,8 +280,13 @@ public abstract class SPARQL_Query extends SPARQL_Protocol
         // Assumes finished whole thing by end of sendResult.
         try {
             action.beginRead() ;
-            DatasetGraph dataset = decideDataset(action, query, 
queryStringLog) ;
-            try ( QueryExecution qExec = createQueryExecution(action, query, 
dataset) ; ) {
+            Pair<DatasetGraph, Query> p = decideDataset(action, query, 
queryStringLog) ;
+            DatasetGraph dataset = p.getLeft();
+            Query q = p.getRight();
+            if ( q == null )
+                q = query;
+            
+            try ( QueryExecution qExec = createQueryExecution(action, q, 
dataset) ; ) {
                 SPARQLResult result = executeQuery(action, qExec, query, 
queryStringLog) ;
                 // Deals with exceptions itself.
                 sendResults(action, result, query.getPrologue()) ;
@@ -390,9 +396,9 @@ public abstract class SPARQL_Query extends SPARQL_Protocol
      * @param action
      * @param query  Query - this may be modified to remove a 
DatasetDescription.
      * @param queryStringLog
-     * @return {@link Dataset}
+     * @return Pair of {@link Dataset} and {@link Query}. 
      */
-    protected abstract DatasetGraph decideDataset(HttpAction action, Query 
query, String queryStringLog) ;
+    protected abstract Pair<DatasetGraph, Query> decideDataset(HttpAction 
action, Query query, String queryStringLog) ;
 
     /** Ship the results to the remote caller.
      * @param action
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java
index 668e563..8dd0ce7 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java
@@ -18,6 +18,7 @@
 
 package org.apache.jena.fuseki.servlets;
 
+import org.apache.jena.atlas.lib.Pair;
 import org.apache.jena.query.Query ;
 import org.apache.jena.sparql.core.DatasetDescription ;
 import org.apache.jena.sparql.core.DatasetGraph ;
@@ -42,7 +43,7 @@ public class SPARQL_QueryDataset extends SPARQL_Query
      *  If the query has a dataset description.
      */
     @Override
-    protected DatasetGraph decideDataset(HttpAction action, Query query, 
String queryStringLog) {
+    protected Pair<DatasetGraph, Query> decideDataset(HttpAction action, Query 
query, String queryStringLog) {
         DatasetGraph dsg = action.getActiveDSG() ;
         DatasetDescription dsDesc = getDatasetDescription(action, query) ;
         if ( dsDesc != null ) {
@@ -52,6 +53,6 @@ public class SPARQL_QueryDataset extends SPARQL_Query
                 query.getNamedGraphURIs().clear() ;
             }
         }
-        return dsg ;
+        return Pair.create(dsg, query);
     }
 }
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
index c31174e..677b619 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java
@@ -23,6 +23,7 @@ import static java.lang.String.format ;
 import java.util.List ;
 
 import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.atlas.lib.Pair;
 import org.apache.jena.fuseki.server.DataService;
 import org.apache.jena.fuseki.server.Operation;
 import org.apache.jena.fuseki.system.GraphLoadUtils;
@@ -37,6 +38,11 @@ import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphZero;
 
 public class SPARQL_QueryGeneral extends SPARQL_Query {
+    // In order to use as much of the main SPARQL code as possible, 
+    // this freestanding servlet mimics being a dataset service, 
+    // and inserts the loaded dataset at decideDataset.
+    // ActionService understands this - the operation is null. 
+    
     final static int MaxTriples = 100 * 1000 ;
 
     public SPARQL_QueryGeneral() {
@@ -54,24 +60,28 @@ public class SPARQL_QueryGeneral extends SPARQL_Query {
         return null ;
     }
     
-    /** SPARQL_QueryGeneral is a servlet to be called directly.
-     * It declares it is own {@code Operation} to fit into {@link 
ActionService#execCommonWorker}.
-     * The Fuseki service handling continues; 
-     * {@link SPARQL_Query} will ask for a dataset which will return the 
fixed, empty dataset.
-     * 
-     */
+    /** SPARQL_QueryGeneral is a servlet to be called directly. */
     @Override
     protected Operation chooseOperation(HttpAction action, DataService 
dataService) {
-        return Operation.Query;
+        return null;
     }
 
     @Override
-    protected DatasetGraph decideDataset(HttpAction action, Query query, 
String queryStringLog) {
-        DatasetDescription datasetDesc = getDatasetDescription(action, query) ;
-        if ( datasetDesc == null )
+    protected Pair<DatasetGraph, Query> decideDataset(HttpAction action, Query 
query, String queryStringLog) {
+        DatasetDescription datasetDesc = getDatasetDescription(action, query);
+        if ( datasetDesc == null ) {
             //ServletOps.errorBadRequest("No dataset description in protocol 
request or in the query string") ;
-            return new DatasetGraphZero();
-        return datasetFromDescriptionWeb(action, datasetDesc) ;
+            return Pair.create(new DatasetGraphZero(), query);
+        }
+        
+        // These will have been taken care of by the "getDatasetDescription"
+        if ( query.hasDatasetDescription() ) {
+            // Don't modify input.
+            query = query.cloneQuery();
+            query.getNamedGraphURIs().clear();
+            query.getGraphURIs().clear();
+        }
+        return Pair.create(datasetFromDescriptionWeb(action, datasetDesc), 
query) ;
     }
 
     /**
diff --git 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
index 6b8c279..671efe9 100644
--- 
a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
+++ 
b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
@@ -55,7 +55,7 @@ import org.apache.jena.riot.web.HttpNames;
 public class ServiceRouter extends ActionService {
     
     public ServiceRouter() {
-        super();
+        super((action, 
operation)->action.getServiceDispatchRegistry().findHandler(operation));
     }
 
     // These calls should not happen because ActionService calls 
chooseOperation(),
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
 
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
index 5d07b43..9ee5048 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java
@@ -169,9 +169,8 @@ public class FusekiMain extends CmdARQ {
             add(argPasswdFile, "--passwd=FILE", "Password file");
             // put in the configuration file
 //            add(argRealm, "--realm=REALM", "Realm name");
-            
-//            add(argWithPing,    "--ping",   "Enable /$/ping");
-//            add(argWithStats,   "--stats",  "Enable /$/stats");
+           add(argWithPing,    "--ping",   "Enable /$/ping");
+           add(argWithStats,   "--stats",  "Enable /$/stats");
 
             super.modVersion.addClass(Fuseki.class);
         }
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomService.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomTestService.java
similarity index 98%
rename from 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomService.java
rename to 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomTestService.java
index 94eec39..6af6c25 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomService.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/CustomTestService.java
@@ -26,7 +26,7 @@ import org.apache.jena.fuseki.servlets.ServletOps;
 import org.apache.jena.riot.WebContent;
 import org.apache.jena.web.HttpSC;
 
-public class CustomService extends ActionREST {
+public class CustomTestService extends ActionREST {
 
     // do* -- the operations to accept
     
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TC_Fuseki.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TC_Fuseki.java
index e0e2ba9..f3ad133 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TC_Fuseki.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TC_Fuseki.java
@@ -24,7 +24,7 @@ import org.junit.runners.Suite;
 
 @RunWith(Suite.class)
 @Suite.SuiteClasses( {
-  TS_EmbeddedFuseki.class,
+  TS_FusekiMain.class,
   TS_SecurityFuseki.class
 })
 public class TC_Fuseki {
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_EmbeddedFuseki.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_FusekiMain.java
similarity index 82%
rename from 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_EmbeddedFuseki.java
rename to 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_FusekiMain.java
index c10c8d5..f49c9fd 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_EmbeddedFuseki.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TS_FusekiMain.java
@@ -32,20 +32,14 @@ import org.junit.runners.Suite.SuiteClasses ;
   , TestFusekiTestServer.class
   , TestFusekiTestAuth.class
   , TestFusekiCustomOperation.class
+  , TestFusekiMainCmd.class
 })
-public class TS_EmbeddedFuseki {
+public class TS_FusekiMain {
     @BeforeClass public static void setupForFusekiServer() {
         LogCtl.setLevel(Fuseki.serverLogName,        "WARN");
         LogCtl.setLevel(Fuseki.actionLogName,        "WARN");
         LogCtl.setLevel(Fuseki.requestLogName,       "WARN");
         LogCtl.setLevel(Fuseki.adminLogName,         "WARN");
         LogCtl.setLevel("org.eclipse.jetty",         "WARN");
-        
-        // Shouldn't see these in the embedded server.
-//        LogCtl.setLevel("org.apache.shiro",          "WARN") ;
-//        LogCtl.setLevel(Fuseki.configLogName,        "WARN");
-
-//        LogCtl.setLevel(Fuseki.builderLogName,       "WARN");
-//        LogCtl.setLevel(Fuseki.servletRequestLogName,"WARN");
     }
 }
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
index 2431d82..0696140 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
@@ -35,12 +35,15 @@ import org.apache.jena.fuseki.build.FusekiBuilder;
 import org.apache.jena.fuseki.server.DataService;
 import org.apache.jena.fuseki.server.Operation;
 import org.apache.jena.fuseki.servlets.ActionService;
+import org.apache.jena.fuseki.servlets.HttpAction;
 import org.apache.jena.query.QueryExecution;
 import org.apache.jena.rdfconnection.RDFConnection;
 import org.apache.jena.rdfconnection.RDFConnectionFactory;
+import org.apache.jena.riot.WebContent;
 import org.apache.jena.riot.web.HttpOp;
 import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFactory;
+import org.apache.jena.web.HttpSC;
 import org.junit.Test;
 
 /** Test for adding a new operation */
@@ -49,7 +52,38 @@ public class TestFusekiCustomOperation {
     private static final String contentType = "application/special";
     private static final String endpointName = "special";
 
-    private final ActionService customHandler = new CustomService();
+    private final ActionService customHandler = new CustomTestService() {
+        @Override
+        protected void doGet(HttpAction action) {
+            action.response.setStatus(HttpSC.OK_200);
+            try {
+                
action.response.setContentType(WebContent.contentTypeTextPlain);
+                action.response.getOutputStream().println("    ** Hello world 
(GET) **");
+            }
+            catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        @Override
+        protected void doHead(HttpAction action) {
+            action.response.setStatus(HttpSC.OK_200);
+            action.response.setContentType(WebContent.contentTypeTextPlain);
+        }
+
+        @Override
+        protected void doPost(HttpAction action) {
+            action.response.setStatus(HttpSC.OK_200);
+            try {
+                
action.response.setContentType(WebContent.contentTypeTextPlain);
+                action.response.getOutputStream().println("    ** Hello world 
(POST) **");
+            }
+            catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    };
+    
     private final int port = WebLib.choosePort();
     private final String url = "http://localhost:"+port;
 
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiMainCmd.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiMainCmd.java
new file mode 100644
index 0000000..3eeef96
--- /dev/null
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiMainCmd.java
@@ -0,0 +1,85 @@
+/*
+ * 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.main;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import org.apache.jena.atlas.json.JSON;
+import org.apache.jena.atlas.web.WebLib;
+import org.apache.jena.fuseki.main.cmds.FusekiMain;
+import org.apache.jena.query.ResultSetFormatter;
+import org.apache.jena.rdfconnection.RDFConnection;
+import org.apache.jena.rdfconnection.RDFConnectionFactory;
+import org.apache.jena.riot.web.HttpOp;
+import org.junit.After;
+import org.junit.Test;
+
+/** Test features */
+public class TestFusekiMainCmd {
+
+    // Fuseki Main server
+    private FusekiServer server = null;
+    private String serverURL = null;
+    
+    private void server(String... cmdline) {
+        int port = WebLib.choosePort();
+        
+        String[] a = Stream.concat(
+            Stream.of("--port="+port), 
+            Arrays.stream(cmdline))
+            .toArray(String[]::new); 
+        
+        FusekiServer server = FusekiMain.build(a);
+        server.start();
+        serverURL = "http://localhost:"+port;
+    }
+    
+    @After public void after() {
+        if ( server != null )
+            server.stop();
+    }
+    
+    @Test public void general_01() {
+        server("--general=/q", "--empty");
+        String string = "SELECT * { VALUES ?x {1 2 3} }";
+        try ( RDFConnection conn = 
RDFConnectionFactory.connect(serverURL+"/q", null, null) ) {
+            conn.queryResultSet(string, rs-> {
+                long count = ResultSetFormatter.consume(rs);
+                assertEquals(3,count);
+            });
+        }
+    }
+    
+    @Test public void ping_01() {
+        server("--mem", "--ping", "/ds");
+        String x = HttpOp.execHttpGetString(serverURL+"/$/ping");
+        assertNotNull(x);
+    }
+    
+    @Test public void stats_01() {
+        server("--mem", "--stats", "/ds");
+        String x = HttpOp.execHttpGetString(serverURL+"/$/stats");
+        assertNotNull(x);
+        JSON.parse(x);
+    }
+}
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/SpecialService.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExampleService.java
similarity index 98%
rename from 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/SpecialService.java
rename to 
jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExampleService.java
index d7a00cc..990d2fc 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/SpecialService.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExampleService.java
@@ -27,7 +27,7 @@ import org.apache.jena.fuseki.servlets.ServletOps;
 import org.apache.jena.riot.WebContent;
 import org.apache.jena.web.HttpSC;
 
-public class SpecialService extends ActionREST {
+public class ExampleService extends ActionREST {
     static { LogCtl.setLog4j(); }
     
     @Override
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.java
index 95dcbe9..7059e60 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.java
@@ -67,7 +67,7 @@ import org.apache.jena.web.HttpSC;
  *          .addOperation("/dataset", "endpoint", myOperation)
  *          .build();
  * </pre>
- * @see SpecialService
+ * @see ExampleService
  */
 
 public class ExtendFuseki_AddService_1 {
@@ -100,7 +100,7 @@ public class ExtendFuseki_AddService_1 {
 
         // The handled for the new operation.
         
-        ActionService customHandler = new SpecialService();
+        ActionService customHandler = new ExampleService();
         
         FusekiServer server = 
             FusekiServer.create().port(PORT)
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_2.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_2.java
index cbe868a..b6936fd 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_2.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_2.java
@@ -71,7 +71,7 @@ public class ExtendFuseki_AddService_2 {
         FusekiBuilder.addServiceEP(dataService, Operation.Query, 
queryEndpoint);
 
         // The handled for the new operation.
-        ActionService customHandler = new SpecialService();
+        ActionService customHandler = new ExampleService();
         
         FusekiServer server = 
             FusekiServer.create().port(PORT)
diff --git 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_3.java
 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_3.java
index cc1f7df..477d9c6 100644
--- 
a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_3.java
+++ 
b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_3.java
@@ -35,7 +35,7 @@ import org.apache.jena.util.FileUtils;
  * This example show adding a custom operation to Fuseki, with dispatch by 
{@code Content-Type}.
  * <p>
  * See {@link ExtendFuseki_AddService_1} fior a geenral description of the 
routing process.
- * @see SpecialService
+ * @see ExampleService
  */
 
 public class ExtendFuseki_AddService_3 {
@@ -64,7 +64,7 @@ public class ExtendFuseki_AddService_3 {
 
         // The handled for the new operation.
         
-        ActionService customHandler = new SpecialService();
+        ActionService customHandler = new ExampleService();
         
         FusekiServer server = 
             FusekiServer.create().port(PORT)

Reply via email to