JENA-1435: Documentation. Example using Content-Type. Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/4a0c2ab5 Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/4a0c2ab5 Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/4a0c2ab5
Branch: refs/heads/master Commit: 4a0c2ab5480e84283a5c7a44a52ec6bb289c2dad Parents: 12a3f1f Author: Andy Seaborne <[email protected]> Authored: Mon Nov 27 09:40:36 2017 +0000 Committer: Andy Seaborne <[email protected]> Committed: Mon Dec 11 14:56:08 2017 +0000 ---------------------------------------------------------------------- .../examples/ExtendFuseki_AddService_1.java | 39 ++++++- .../examples/ExtendFuseki_AddService_2.java | 2 +- .../examples/ExtendFuseki_AddService_3.java | 107 +++++++++++++++++++ 3 files changed, 142 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/4a0c2ab5/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 index e925386..cdeb7c4 100644 --- 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 @@ -34,11 +34,40 @@ 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. - * - * + * This example show adding a custom operation to Fuseki. + * <p> + * There are two ways operations are routed: for a datset {@code /dataset}: + * <ol> + * <li>By endpoint name: {@code /dataset/endpoint}</li> + * <li>By content type, when a POST is made on the {@code /dataset}.</li> + * </ol> + * The first is the usual way; the second is not a common pattern. + * <p> + * The second way is in addition to the endpoint; an endpoint is always required to + * enabled routing by {@code Content-Type}. + * <p> + * The process for adding an operation is: + * <ul> + * <li>Register the operation with the server, with its implmementation.</li> + * <li>Add the operation to a datasets.</li> + * </ul> + * <pre> + * // Register operation. + * Operation myOperation = Operation.register("Special", "Custom operation"); + * // An implementation to call + * ActionService customHandler = new SpecialService(); + * // Builder pattern ... + * FusekiServer server = + * FusekiServer.create().port (1122) + * // Register the operation with the server, together with implementation. + * .registerOperation(myOperation, customHandler) + * // Add a dataset + * .add("/dataset", DatasetGraphFactory.createTxnMem(), true) + * // Add operation by endpoint + * .addOperation("/dataset", "endpoint", myOperation) + * .build(); + * </pre> + * @see SpecialService */ public class ExtendFuseki_AddService_1 { http://git-wip-us.apache.org/repos/asf/jena/blob/4a0c2ab5/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 index 4711c90..a05026a 100644 --- 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 @@ -36,7 +36,7 @@ import org.apache.jena.sparql.engine.http.QueryExceptionHTTP; import org.apache.jena.web.HttpSC; /** - * Create custom endpoint names. + * Create custom endpoint names, dispatch by {@code Content-Type}. * See also {@link ExtendFuseki_AddService_1} for more details. */ http://git-wip-us.apache.org/repos/asf/jena/blob/4a0c2ab5/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_3.java ---------------------------------------------------------------------- diff --git a/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_3.java b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_3.java new file mode 100644 index 0000000..eb23df3 --- /dev/null +++ b/jena-fuseki2/jena-fuseki-embedded/src/test/java/org/apache/jena/fuseki/embedded/examples/ExtendFuseki_AddService_3.java @@ -0,0 +1,107 @@ +/* + * 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.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; + +/** + * 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 + */ + +public class ExtendFuseki_AddService_3 { + static { LogCtl.setLog4j(); } + + 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"; + String contentType = "application/special"; + + // The handled for the new operation. + + ActionService customHandler = new SpecialService(); + + FusekiServer server = + FusekiServer.create().setPort(PORT) + .setVerbose(true) + + // Register the new operation, with content type and handler + .registerOperation(myOperation, contentType, 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. + // Required when when routing via Content-Type. + .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 datasetURL = SERVER_URL + DATASET; + //String customOperationURL = SERVER_URL + DATASET + "/" + endpointName; + + try { + + // Dataset endpoint name : POST, with Content-type. + try ( TypedInputStream stream = HttpOp.execHttpPostStream(datasetURL, contentType, "", "text/plain") ) { + String s2 = FileUtils.readWholeFileAsUTF8(stream); + System.out.print(s2); + if ( s2 == null ) + System.out.println(); + } catch (IOException ex) { IO.exception(ex); } + } finally { + server.stop(); + } + } +}
