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 2017/12/17 19:33:44 UTC
[12/28] jena git commit: JENA-1435: Examples
JENA-1435: Examples
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/9338a1fc
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/9338a1fc
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/9338a1fc
Branch: refs/heads/master
Commit: 9338a1fc091b59f073694e752a5837cb62f3f519
Parents: 07409cd
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Nov 26 17:06:24 2017 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Dec 11 14:56:08 2017 +0000
----------------------------------------------------------------------
.../servlets/ServiceDispatchRegistry.java | 4 +-
.../jena/fuseki/servlets/ServiceRouter.java | 40 +++---
.../jena/fuseki/embedded/FusekiServer.java | 22 +++-
.../embedded/TestFusekiCustomOperation.java | 8 +-
.../examples/ExtendFuseki_AddService_1.java | 129 +++++++++++++++++++
.../examples/ExtendFuseki_AddService_2.java | 123 ++++++++++++++++++
.../embedded/examples/SpecialService.java | 81 ++++++++++++
.../src/test/resources/log4j.properties | 40 ++++++
8 files changed, 417 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
index bf52647..e714ee1 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceDispatchRegistry.java
@@ -45,6 +45,7 @@ public class ServiceDispatchRegistry {
/** Map ContentType (lowercase, no charset) to the {@code Operation} for handling it. */
private final Map<String, Operation> contentTypeToOperation = new ConcurrentHashMap<>();
+ public Map<String, Operation> contentTypeToOperation() { return contentTypeToOperation; }
/** Map {@link Operation} to servlet handler.
* {@code Operation}s are the internal symbol identifying an operation,
@@ -52,6 +53,7 @@ public class ServiceDispatchRegistry {
* which is mapped by {@link DataService#getEndpoint(String)}.
*/
private final Map<Operation, ActionService> operationToHandler = new ConcurrentHashMap<>();
+ public Map<Operation, ActionService> operationToHandler() { return operationToHandler; }
public ServiceDispatchRegistry(ServiceDispatchRegistry other) {
contentTypeToOperation.putAll(other.contentTypeToOperation);
@@ -99,7 +101,7 @@ public class ServiceDispatchRegistry {
contentTypeToOperation.put(contentType, operation);
operationToHandler.put(operation, action);
}
-
+
// The server DataAccessPointRegistry is held in the ServletContext for the server.
private static final String attrServiceRegistry = "jena-fuseki:ServiceDispatchRegistry" ;
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/servlets/ServiceRouter.java
----------------------------------------------------------------------
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 cb3cf1b..a88d211 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
@@ -40,7 +40,7 @@ import org.apache.jena.riot.web.HttpNames;
* for operations by service endpoint.
* <p>
* Normal use is to route all service operations to this servlet via {@link ActionService}.
- * It wil route for operations on teh dataset and the
+ * It will route for operations on the dataset and the
* <p>
* It be attached to a dataset location and acts as a router for all SPARQL operations
* (query, update, graph store, both direct and indirect naming, quads operations on a
@@ -63,27 +63,25 @@ public abstract class ServiceRouter extends ActionService {
protected abstract boolean allowQuads_RW(HttpAction action);
-// public static class ReadOnly extends ServiceRouterServlet
-// {
-// public ReadOnly() { super() ; }
-// @Override protected boolean allowQuery(HttpAction action) { return true ; }
-// @Override protected boolean allowUpdate(HttpAction action) { return false ; }
-// @Override protected boolean allowGSP_R(HttpAction action) { return true ; }
-// @Override protected boolean allowGSP_RW(HttpAction action) { return false ; }
-// @Override protected boolean allowQuads_R(HttpAction action) { return true ; }
-// @Override protected boolean allowQuads_RW(HttpAction action) { return false ; }
-// }
+// public static class ReadOnly extends ServiceRouterServlet {
+// public ReadOnly() { super() ; }
+// @Override protected boolean allowQuery(HttpAction action) { return true ; }
+// @Override protected boolean allowUpdate(HttpAction action) { return false ; }
+// @Override protected boolean allowGSP_R(HttpAction action) { return true ; }
+// @Override protected boolean allowGSP_RW(HttpAction action) { return false ; }
+// @Override protected boolean allowQuads_R(HttpAction action) { return true ; }
+// @Override protected boolean allowQuads_RW(HttpAction action) { return false ; }
+// }
//
-// public static class ReadWrite extends ServiceRouterServlet
-// {
-// public ReadWrite() { super() ; }
-// @Override protected boolean allowQuery(HttpAction action) { return true ; }
-// @Override protected boolean allowUpdate(HttpAction action) { return true ; }
-// @Override protected boolean allowGSP_R(HttpAction action) { return true ; }
-// @Override protected boolean allowGSP_RW(HttpAction action) { return true ; }
-// @Override protected boolean allowQuads_R(HttpAction action) { return true ; }
-// @Override protected boolean allowQuads_RW(HttpAction action) { return true ; }
-// }
+// public static class ReadWrite extends ServiceRouterServlet {
+// public ReadWrite() { super() ; }
+// @Override protected boolean allowQuery(HttpAction action) { return true ; }
+// @Override protected boolean allowUpdate(HttpAction action) { return true ; }
+// @Override protected boolean allowGSP_R(HttpAction action) { return true ; }
+// @Override protected boolean allowGSP_RW(HttpAction action) { return true ; }
+// @Override protected boolean allowQuads_R(HttpAction action) { return true ; }
+// @Override protected boolean allowQuads_RW(HttpAction action) { return true ; }
+// }
public static class AccessByConfig extends ServiceRouter {
public AccessByConfig() {
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
index 40d6cff..67702d3 100644
--- a/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
+++ b/jena-fuseki2/jena-fuseki-embedded/src/main/java/org/apache/jena/fuseki/embedded/FusekiServer.java
@@ -316,6 +316,20 @@ public class FusekiServer {
}
/**
+ * Add an operation and handler to the server. This does not enable it for any dataset.
+ * <p>
+ * To associate an operation with a dataset, call {@link #addOperation} after adding the dataset.
+ * <p>
+ * (Advanced and experimental option: see
+ * <a href="http://jena.apache.org/documentation/fuseki2/extend.html>Extending Fuseki</a>)
+ * @see #addOperation
+ */
+ public Builder registerOperation(Operation operation, ActionService handler) {
+ registerOperation(operation, null, handler);
+ return this;
+ }
+
+ /**
* Add an operation to the server, together with its triggering Content-Type (may be null) and servlet handler.
* <p>
* To associate an operation with a daatsets, call {@link #addOperation} after adding the dataset.
@@ -334,12 +348,12 @@ public class FusekiServer {
}
/**
- * Create an endpoint on the dataset. The operation must already be registered with the builder.
- * @see #registerOperation
+ * Create an endpoint on the dataset.
+ * The operation must already be registered with the builder.
+ * @see #registerOperation(Operation, ActionService)
*/
- public Builder addOperation(String datasetName, Operation operation, String endpointName) {
+ public Builder addOperation(String datasetName, String endpointName, Operation operation) {
Objects.requireNonNull(datasetName, "datasetName");
- Objects.requireNonNull(operation, "operation");
Objects.requireNonNull(endpointName, "endpointName");
String name = DataAccessPoint.canonical(datasetName);
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/TestFusekiCustomOperation.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/TestFusekiCustomOperation.java b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/TestFusekiCustomOperation.java
index 8b037b6..dcecb26 100644
--- a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/TestFusekiCustomOperation.java
+++ b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/TestFusekiCustomOperation.java
@@ -78,7 +78,7 @@ public class TestFusekiCustomOperation {
.setPort(port)
.registerOperation(newOp, contentType, customHandler)
.add("/ds", DatasetGraphFactory.createTxnMem(), true)
- .addOperation("/ds", newOp, endpointName)
+ .addOperation("/ds", endpointName, newOp)
.build();
testServer(server, true);
}
@@ -90,7 +90,7 @@ public class TestFusekiCustomOperation {
.setPort(port)
.registerOperation(newOp, null, customHandler)
.add("/ds", DatasetGraphFactory.createTxnMem(), true)
- .addOperation("/ds", newOp, endpointName)
+ .addOperation("/ds", endpointName, newOp)
.build();
testServer(server, false);
}
@@ -100,7 +100,7 @@ public class TestFusekiCustomOperation {
FusekiServer.create()
.setPort(port)
.registerOperation(newOp, null, customHandler)
- .addOperation("/UNKNOWN", newOp, endpointName);
+ .addOperation("/UNKNOWN", endpointName, newOp);
//.build();
}
@@ -111,7 +111,7 @@ public class TestFusekiCustomOperation {
//.registerOperation(newOp, null, customHandler)
.add("/ds", DatasetGraphFactory.createTxnMem(), true)
// Unregistered.
- .addOperation("/ds", newOp, endpointName);
+ .addOperation("/ds", endpointName, newOp);
//.build();
}
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_1.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_1.java b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_1.java
new file mode 100644
index 0000000..e925386
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_1.java
@@ -0,0 +1,129 @@
+/*
+ * 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.embedded.examples;
+
+import java.io.IOException;
+
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.atlas.logging.LogCtl;
+import org.apache.jena.atlas.web.HttpException;
+import org.apache.jena.atlas.web.TypedInputStream;
+import org.apache.jena.fuseki.FusekiLib;
+import org.apache.jena.fuseki.embedded.FusekiServer;
+import org.apache.jena.fuseki.server.Operation;
+import org.apache.jena.fuseki.servlets.ActionService;
+import org.apache.jena.riot.web.HttpOp;
+import org.apache.jena.sparql.core.DatasetGraphFactory;
+import org.apache.jena.util.FileUtils;
+import org.apache.jena.web.HttpSC;
+
+/**
+ * Dispatch:
+ * By endpoint name. {@code /dataset/special} - normal way to do it.
+ * By {@code Content-Type} {@code /dataset/} -- optional, uncommon.
+ *
+ *
+ */
+
+public class ExtendFuseki_AddService_1 {
+ static { LogCtl.setLog4j(); }
+
+ // Endpoint dispatch only.
+
+ // Choose free port for the example
+ // Normally, this is fixed and published, and fixed in URLs.
+ // To make the example portable, we ask the OS for a free port.
+ static int PORT = FusekiLib.choosePort();
+
+ // The server
+ static String SERVER_URL = "http://localhost:"+PORT+"/";
+
+ static String DATASET = "dataset";
+
+ public static void main(String ...args) {
+ // Create a new operation: operations are really just names (symbols). The code to
+ // run is found by looking up the operation in a per-server table that gives the server-specific
+ // implementation as an ActionService.
+
+ Operation myOperation = Operation.register("Special", "Custom operation");
+
+ // Service endpoint name.
+ // This can be different for different datasets even in the same server.
+ // c.f. {@code fuseki:serviceQuery}
+
+ String endpointName = "special";
+
+ // The handled for the new operation.
+
+ ActionService customHandler = new SpecialService();
+
+ FusekiServer server =
+ FusekiServer.create().setPort(PORT)
+ .setVerbose(true)
+
+ // Register the new operation, and it's handler, but no Content-Type
+ .registerOperation(myOperation, customHandler)
+
+ // Add a dataset with the normal, default naming services
+ // (/sparql, /query, /update, /upload, /data, /get)
+ .add(DATASET, DatasetGraphFactory.createTxnMem(), true)
+
+ // Add the custom service, mapping from endpoint to operation for a specific dataset.
+ .addOperation(DATASET, endpointName, myOperation)
+
+ // And build the server.
+ .build();
+
+ // Start the server. This does not block this thread.
+ server.start();
+
+ // Try some operations on the server using the service URL.
+ String customOperationURL = SERVER_URL + DATASET + "/" + endpointName;
+
+ try {
+
+ // Service endpoint name : GET
+ String s1 = HttpOp.execHttpGetString(customOperationURL);
+ System.out.print(s1);
+ if ( s1 == null )
+ System.out.println();
+
+ // Service endpoint name : POST
+ try ( TypedInputStream stream = HttpOp.execHttpPostStream(customOperationURL, null, "text/plain") ) {
+ String s2 = FileUtils.readWholeFileAsUTF8(stream);
+ System.out.print(s2);
+ if ( s2 == null )
+ System.out.println();
+ } catch (IOException ex) { IO.exception(ex); }
+
+ // Service endpoint name. DELETE -> fails 405
+ try {
+ HttpOp.execHttpDelete(customOperationURL);
+ throw new IllegalStateException("DELETE succeeded");
+ } catch (HttpException ex) {
+ if ( ex.getResponseCode() != HttpSC.METHOD_NOT_ALLOWED_405 )
+ System.err.println("Unexpected HTTP Response Code: "+ex.getMessage());
+ else
+ System.out.println("DELETE rejected correctly: "+ex.getMessage());
+ }
+ } finally {
+ server.stop();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_2.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_2.java b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_2.java
new file mode 100644
index 0000000..4711c90
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_2.java
@@ -0,0 +1,123 @@
+/*
+ * 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.embedded.examples;
+
+import org.apache.jena.atlas.logging.LogCtl;
+import org.apache.jena.fuseki.FusekiLib;
+import org.apache.jena.fuseki.build.FusekiBuilder;
+import org.apache.jena.fuseki.embedded.FusekiServer;
+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.query.Query;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+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.sparql.engine.http.QueryExceptionHTTP;
+import org.apache.jena.web.HttpSC;
+
+/**
+ * Create custom endpoint names.
+ * See also {@link ExtendFuseki_AddService_1} for more details.
+ */
+
+public class ExtendFuseki_AddService_2 {
+ static { LogCtl.setLog4j(); }
+
+ // Endpoint dispatch only.
+ static int PORT = FusekiLib.choosePort();
+
+ // The server
+ static String SERVER_URL = "http://localhost:"+PORT+"/";
+
+ static String DATASET = "dataset";
+
+ public static void main(String ...args) {
+ // Register a new operation
+
+ Operation myOperation = Operation.register("Special", "Custom operation");
+
+ // Service endpoint names.
+
+ String queryEndpoint = "q";
+ String customEndpoint = "x";
+
+ // Make a DataService with custom named for endpoints.
+ // In this example, "q" for SPARQL query and "x" for our custom extension and no others.
+ DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+ DataService dataService = new DataService(dsg);
+ // This would add the usual defaults.
+ //FusekiBuilder.populateStdServices(dataService, true);
+ FusekiBuilder.addServiceEP(dataService, myOperation, customEndpoint);
+ FusekiBuilder.addServiceEP(dataService, Operation.Query, queryEndpoint);
+
+ // The handled for the new operation.
+ ActionService customHandler = new SpecialService();
+
+ FusekiServer server =
+ FusekiServer.create().setPort(PORT)
+ .setVerbose(true)
+ // Register the new operation, and it's handler
+ .registerOperation(myOperation, customHandler)
+
+ // The DataService.
+ .add(DATASET, dataService)
+
+ // And build the server.
+ .build();
+
+ server.start();
+
+ // Try some operations on the server using the service URL.
+ String customOperationURL = SERVER_URL + DATASET + "/" + customEndpoint;
+ String queryOperationURL = SERVER_URL + DATASET + "/" + queryEndpoint;
+
+ Query query = QueryFactory.create("ASK{}");
+
+
+ try {
+
+ // Try custom name - OK
+ try ( QueryExecution qExec = QueryExecutionFactory.sparqlService(queryOperationURL, query) ) {
+ qExec.execAsk();
+ }
+
+ // Try default name - 404
+ try ( QueryExecution qExec = QueryExecutionFactory.sparqlService(SERVER_URL + DATASET + "/sparql", query) ) {
+ qExec.execAsk();
+ throw new RuntimeException("Didn't fail");
+ } catch (QueryExceptionHTTP ex) {
+ if ( ex.getResponseCode() != HttpSC.NOT_FOUND_404 ) {
+ throw new RuntimeException("Not a 404", ex);
+ }
+ }
+
+ // Service endpoint name : GET
+ String s1 = HttpOp.execHttpGetString(customOperationURL);
+ if ( s1 == null )
+ throw new RuntimeException("Failed: "+customOperationURL);
+
+ } finally {
+ server.stop();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/SpecialService.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/SpecialService.java b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/SpecialService.java
new file mode 100644
index 0000000..239e6d7
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/SpecialService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.embedded.examples;
+
+import java.io.IOException;
+
+import org.apache.jena.atlas.logging.LogCtl;
+import org.apache.jena.fuseki.servlets.ActionREST;
+import org.apache.jena.fuseki.servlets.HttpAction;
+import org.apache.jena.fuseki.servlets.ServletOps;
+import org.apache.jena.riot.WebContent;
+import org.apache.jena.web.HttpSC;
+
+public class SpecialService extends ActionREST {
+ static { LogCtl.setLog4j(); }
+
+ @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();
+ }
+ }
+
+ @Override
+ protected void doPatch(HttpAction action) { notSupported(action); }
+
+ @Override
+ protected void doDelete(HttpAction action) { notSupported(action); }
+
+ @Override
+ protected void doPut(HttpAction action) { notSupported(action); }
+
+ @Override
+ protected void doOptions(HttpAction action) { notSupported(action); }
+
+ @Override
+ protected void validate(HttpAction action) { }
+
+ private void notSupported(HttpAction action) {
+ ServletOps.errorMethodNotAllowed(action.getMethod()+" "+action.getActionURI());
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/9338a1fc/jena-fuseki2/jena-fuseki-embedded/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/resources/log4j.properties b/jena-fuseki2/jena-fuseki-embedded/src/test/resources/log4j.properties
new file mode 100644
index 0000000..e84e60e
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-embedded/src/test/resources/log4j.properties
@@ -0,0 +1,40 @@
+# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+# Plain output to stdout
+log4j.appender.jena.plainstdout=org.apache.log4j.ConsoleAppender
+log4j.appender.jena.plainstdout.target=System.out
+log4j.appender.jena.plainstdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.jena.plainstdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %-10c{1} %-5p %m%n
+## %d{ISO8601} -- includes "ss,sss"
+## log4j.appender.jena.plainstdout.layout.ConversionPattern=[%d{ISO8601}] %-10c{1} %-5p %m%n
+
+# Unadorned, for the NCSA requests log.
+log4j.appender.fuseki.plain=org.apache.log4j.ConsoleAppender
+log4j.appender.fuseki.plain.target=System.out
+log4j.appender.fuseki.plain.layout=org.apache.log4j.PatternLayout
+log4j.appender.fuseki.plain.layout.ConversionPattern=%m%n
+
+log4j.rootLogger=INFO, jena.plainstdout
+log4j.logger.org.apache.jena=WARN
+log4j.logger.org.apache.jena.fuseki=INFO
+
+# Others
+log4j.logger.org.eclipse.jetty=WARN
+log4j.logger.org.apache.shiro=WARN
+
+# Fuseki System logs.
+log4j.logger.org.apache.jena.fuseki.Server=INFO
+log4j.logger.org.apache.jena.fuseki.Fuseki=INFO
+log4j.logger.org.apache.jena.fuseki.Admin=INFO
+log4j.logger.org.apache.jena.fuseki.Validate=INFO
+log4j.logger.org.apache.jena.fuseki.Config=INFO
+
+# NCSA Request log.
+log4j.additivity.org.apache.jena.fuseki.Request=false
+log4j.logger.org.apache.jena.fuseki.Request=OFF, fuseki.plain
+
+# TDB
+log4j.logger.org.apache.jena.tdb.loader=INFO
+## Parser output
+log4j.additivity.org.apache.jena.riot=false
+log4j.logger.org.apache.jena.riot=INFO, jena.plainstdout