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 2018/09/21 10:16:06 UTC
[55/70] [abbrv] jena git commit: JENA-1597: Modules jena-fuseki-main
and jena-fuseki-server
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..6003320
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiCustomOperation.java
@@ -0,0 +1,188 @@
+/*
+ * 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.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.atlas.web.HttpException;
+import org.apache.jena.atlas.web.TypedInputStream;
+import org.apache.jena.fuseki.FusekiConfigException;
+import org.apache.jena.fuseki.FusekiLib;
+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.query.QueryExecution;
+import org.apache.jena.rdfconnection.RDFConnection;
+import org.apache.jena.rdfconnection.RDFConnectionFactory;
+import org.apache.jena.riot.web.HttpOp;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.sparql.core.DatasetGraphFactory;
+import org.junit.Test;
+
+/** Test for adding a new operation */
+public class TestFusekiCustomOperation {
+ private static final Operation newOp = Operation.register("Special", "Custom operation");
+ private static final String contentType = "application/special";
+ private static final String endpointName = "special";
+
+ private final ActionService customHandler = new CustomService();
+ private final int port = FusekiLib.choosePort();
+ private final String url = "http://localhost:"+port;
+
+ @Test
+ public void cfg_dataservice() {
+ // Create a DataService and add the endpoint -> operation association.
+ // This still needs the server to have the operation registered.
+ DatasetGraph dsg = DatasetGraphFactory.createTxnMem();
+ DataService dataService = new DataService(dsg);
+ FusekiBuilder.populateStdServices(dataService, true);
+ FusekiBuilder.addServiceEP(dataService, newOp, endpointName);
+
+ FusekiServer server =
+ FusekiServer.create()
+ .port(port)
+ .registerOperation(newOp, contentType, customHandler)
+ .add("/ds", dataService)
+ .build();
+ testServer(server, true, true);
+ }
+
+ @Test
+ public void cfg_builder_CT() {
+ FusekiServer server =
+ FusekiServer.create()
+ .port(port)
+ .registerOperation(newOp, contentType, customHandler)
+ .add("/ds", DatasetGraphFactory.createTxnMem(), true)
+ .addOperation("/ds", endpointName, newOp)
+ .build();
+ testServer(server, true, true);
+ }
+
+ @Test
+ public void cfg_builder_noCT() {
+ FusekiServer server =
+ FusekiServer.create()
+ .port(port)
+ .registerOperation(newOp, null, customHandler)
+ .add("/ds", DatasetGraphFactory.createTxnMem(), true)
+ .addOperation("/ds", endpointName, newOp)
+ .build();
+ testServer(server, true, false);
+ }
+
+ @Test(expected=FusekiConfigException.class)
+ public void cfg_bad_01() {
+ FusekiServer.create()
+ .port(port)
+ .registerOperation(newOp, null, customHandler)
+ .addOperation("/UNKNOWN", endpointName, newOp);
+ //.build();
+ }
+
+ @Test(expected=FusekiConfigException.class)
+ public void cfg_bad_02() {
+ FusekiServer.create()
+ .port(port)
+ //.registerOperation(newOp, null, customHandler)
+ .add("/ds", DatasetGraphFactory.createTxnMem(), true)
+ // Unregistered.
+ .addOperation("/ds", endpointName, newOp);
+ //.build();
+ }
+
+ public void cfg_bad_ct_not_enabkled_here() {
+ FusekiServer server = FusekiServer.create()
+ .port(port)
+ .registerOperation(newOp, "app/special", customHandler)
+ .add("/ds", DatasetGraphFactory.createTxnMem(), true)
+ // Unregistered.
+ .addOperation("/ds", endpointName, newOp)
+ .build();
+ testServer(server, false, false);
+ }
+
+
+ private void testServer(FusekiServer server, boolean withEndpoint, boolean withContentType) {
+ try {
+ server.start();
+ // Try query (no extension required)
+ try(RDFConnection rconn = RDFConnectionFactory.connect(url+"/ds")) {
+ try(QueryExecution qExec = rconn.query("ASK {}")) {
+ qExec.execAsk();
+ }
+ }
+
+ if ( withEndpoint ) {
+ // Service endpoint name : GET
+ String s1 = HttpOp.execHttpGetString(url+"/ds/"+endpointName);
+
+ // Service endpoint name : POST
+ try ( TypedInputStream stream = HttpOp.execHttpPostStream(url+"/ds/"+endpointName, "ignored", "", "text/plain") ) {
+ String x = IOUtils.toString(stream, StandardCharsets.UTF_8);
+ assertNotNull(x);
+ } catch (IOException ex) {
+ IO.exception(ex);
+ }
+ } else {
+ // No endpoint so we expect a 404.
+ try {
+ // Service endpoint name : GET
+ HttpOp.execHttpGet(url+"/ds/"+endpointName);
+ fail("Expected to fail HTTP GET");
+ } catch (HttpException ex) {
+ assertEquals(404, ex.getResponseCode());
+ }
+ }
+
+ if ( withContentType ) {
+ // Content-type
+ try ( TypedInputStream stream = HttpOp.execHttpPostStream(url+"/ds", contentType, "", "text/plain") ) {
+ String x = IOUtils.toString(stream, StandardCharsets.UTF_8);
+ assertNotNull(x);
+ } catch (IOException ex) {
+ IO.exception(ex);
+ }
+ } else {
+ // No Content-Type
+ try ( TypedInputStream stream = HttpOp.execHttpPostStream(url+"/ds", contentType, "", "text/plain") ) {
+ fail("Expected to fail HTTP POST using Content-Type");
+ } catch (HttpException ex) {}
+
+ // Service endpoint name. DELETE -> fails 405
+ try {
+ HttpOp.execHttpDelete(url+"/ds/"+endpointName);
+ throw new IllegalStateException("DELETE succeeded");
+ } catch (HttpException ex) {
+ assertEquals(405, ex.getResponseCode());
+ }
+ }
+ } finally {
+ server.stop();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestAuth.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestAuth.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestAuth.java
new file mode 100644
index 0000000..939725f
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestAuth.java
@@ -0,0 +1,98 @@
+/*
+ * 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.apache.jena.fuseki.main.FusekiTestAuth.assertAuthHttpException;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClients;
+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.Fuseki;
+import org.apache.jena.riot.web.HttpOp;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestFusekiTestAuth {
+
+ static {
+ 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");
+ }
+
+ private static String USER = "user1234";
+ private static String PASSWORD = "password1234";
+
+ @BeforeClass
+ public static void ctlBeforeClass() {
+ SecurityHandler sh = FusekiTestAuth.makeSimpleSecurityHandler("/*", USER, PASSWORD);
+ FusekiTestAuth.setupServer(false, sh);
+ }
+
+ @AfterClass
+ public static void ctlAfterClass() {
+ FusekiTestAuth.teardownServer();
+ HttpOp.setDefaultHttpClient(HttpOp.createPoolingHttpClient());
+ }
+
+ @Test(expected=HttpException.class)
+ public void testServer_auth_no_auth() {
+ // No Auth
+ try ( TypedInputStream in = HttpOp.execHttpGet(FusekiTestAuth.urlDataset(), "*/*") ) {}
+ catch (HttpException ex) { throw assertAuthHttpException(ex); }
+ }
+
+ @Test public void testServer_auth() {
+ BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
+ Credentials credentials = new UsernamePasswordCredentials(USER, PASSWORD);
+ credsProvider.setCredentials(AuthScope.ANY, credentials);
+ HttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
+ try ( TypedInputStream in = HttpOp.execHttpGet(FusekiTestAuth.urlDataset(), "*/*", client, null) ) {}
+ }
+
+ @Test(expected=HttpException.class)
+ public void testServer_auth_bad_user() {
+ BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
+ Credentials credentials = new UsernamePasswordCredentials("USERUSER", PASSWORD);
+ credsProvider.setCredentials(AuthScope.ANY, credentials);
+ HttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
+ try ( TypedInputStream in = HttpOp.execHttpGet(FusekiTestAuth.urlDataset(), "*/*", client, null) ) {}
+ catch (HttpException ex) { throw assertAuthHttpException(ex); }
+ }
+
+ @Test(expected=HttpException.class)
+ public void testServer_auth_bad_password() {
+ BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
+ credsProv.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(USER, "WRONG"));
+ HttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProv).build();
+
+ try ( TypedInputStream in = HttpOp.execHttpGet(FusekiTestAuth.urlDataset(), "*/*", client, null) ) {}
+ catch (HttpException ex) { throw assertAuthHttpException(ex); }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestServer.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestServer.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestServer.java
new file mode 100644
index 0000000..8637d36
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestFusekiTestServer.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.jena.atlas.web.HttpException;
+import org.apache.jena.atlas.web.TypedInputStream;
+import org.apache.jena.riot.web.HttpOp;
+import org.apache.jena.web.HttpSC;
+import org.junit.*;
+
+public class TestFusekiTestServer {
+
+// @BeforeClass static public void beforeSuiteClass() { ServerCtl.ctlBeforeTestSuite(); }
+// @AfterClass static public void afterSuiteClass() { ServerCtl.ctlAfterTestSuite(); }
+
+ // This is file is the "suite".
+
+ @BeforeClass public static void ctlBeforeClass() { FusekiTestServer.ctlBeforeTestSuite(); FusekiTestServer.ctlBeforeClass(); }
+ @AfterClass public static void ctlAfterClass() { FusekiTestServer.ctlAfterClass(); FusekiTestServer.ctlAfterTestSuite(); }
+ @Before public void ctlBeforeTest() { FusekiTestServer.ctlBeforeTest(); }
+ @After public void ctlAfterTest() { FusekiTestServer.ctlAfterTest(); }
+
+ @Test public void testServer_1() {
+ HttpOp.execHttpGetString(FusekiTestServer.urlDataset());
+ }
+
+ @Test public void testServer_2() {
+ BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
+ credsProv.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("USER", "PASSWORD"));
+ HttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProv).build();
+
+ // No auth set - should work.
+ try ( TypedInputStream in = HttpOp.execHttpGet(FusekiTestServer.urlDataset(), "*/*") ) {}
+ catch (HttpException ex) {
+ Assert.assertTrue(ex.getResponseCode() == HttpSC.FORBIDDEN_403 || ex.getResponseCode() == HttpSC.UNAUTHORIZED_401 );
+ throw ex;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestMultipleEmbedded.java
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestMultipleEmbedded.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestMultipleEmbedded.java
new file mode 100644
index 0000000..ecb4e21
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/TestMultipleEmbedded.java
@@ -0,0 +1,170 @@
+/*
+ * 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.apache.jena.fuseki.main.TestEmbeddedFuseki.dataset;
+import static org.apache.jena.fuseki.main.TestEmbeddedFuseki.query;
+import static org.junit.Assert.assertEquals ;
+import static org.junit.Assert.assertTrue ;
+
+import java.io.OutputStream ;
+
+import org.apache.http.HttpEntity ;
+import org.apache.http.entity.ContentProducer ;
+import org.apache.http.entity.EntityTemplate ;
+import org.apache.jena.atlas.web.ContentType ;
+import org.apache.jena.fuseki.FusekiException ;
+import org.apache.jena.fuseki.FusekiLib;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.query.ResultSet ;
+import org.apache.jena.query.ResultSetFormatter ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.RDFFormat ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.Txn ;
+import org.junit.Test ;
+
+public class TestMultipleEmbedded {
+
+ static Quad q1 = SSE.parseQuad("(_ :s :p 1)") ;
+ static Quad q2 = SSE.parseQuad("(_ :s :p 2)") ;
+
+ // Two servers, same port -> bad.
+ @Test(expected=FusekiException.class)
+ public void multiple_01() {
+ DatasetGraph dsg = dataset() ;
+
+ int port = FusekiLib.choosePort() ;
+ FusekiServer server1 = FusekiServer.create().port(port).add("/ds1", dsg).build() ;
+ // Same port - Bad.
+ FusekiServer server2 = FusekiServer.create().port(port).add("/ds2", dsg).build() ;
+
+ server1.start();
+
+ try {
+ server2.start();
+ } catch (FusekiException ex) {
+ assertTrue(ex.getCause() instanceof java.net.BindException ) ;
+ throw ex ;
+ } finally {
+ try { server1.stop() ; } catch (Exception ex) {}
+ try { server2.stop() ; } catch (Exception ex) {}
+ }
+ }
+
+ // Two servers, different ports -> good.
+ @Test
+ public void multiple_02() {
+ DatasetGraph dsg = dataset() ;
+ int port1 = FusekiLib.choosePort() ;
+ FusekiServer server1 = FusekiServer.create().port(port1).add("/ds1", dsg).build() ;
+
+ // Different port - good
+ int port2 = FusekiLib.choosePort() ;
+ FusekiServer server2 = FusekiServer.create().port(port2).add("/ds2", dsg).build() ;
+
+ try {
+ server1.start();
+ server2.start();
+ } finally {
+ try { server1.stop() ; } catch (Exception ex) {}
+ try { server2.stop() ; } catch (Exception ex) {}
+ }
+ }
+
+ // Two servers, two datasets.
+ @Test
+ public void multiple_03() {
+ DatasetGraph dsg1 = dataset() ;
+ DatasetGraph dsg2 = dataset() ;
+ // Same name.
+ int port1 = FusekiLib.choosePort() ;
+ FusekiServer server1 = FusekiServer.create().port(port1).add("/ds", dsg1).build().start() ;
+ Txn.executeWrite(dsg1, ()->dsg1.add(q1));
+
+ int port2 = FusekiLib.choosePort() ;
+ FusekiServer server2 = FusekiServer.create().port(port2).add("/ds", dsg2).build().start() ;
+ Txn.executeWrite(dsg2, ()->dsg2.add(q2));
+
+ query("http://localhost:"+port1+"/ds/", "SELECT * {?s ?p 1}", qExec->{
+ ResultSet rs = qExec.execSelect() ;
+ int x = ResultSetFormatter.consume(rs) ;
+ assertEquals(1, x) ;
+ }) ;
+ query("http://localhost:"+port2+"/ds/", "SELECT * {?s ?p 1}", qExec->{
+ ResultSet rs = qExec.execSelect() ;
+ int x = ResultSetFormatter.consume(rs) ;
+ assertEquals(0, x) ;
+ }) ;
+ server1.stop();
+ // server2 still running
+ query("http://localhost:"+port2+"/ds/", "SELECT * {?s ?p 2}", qExec->{
+ ResultSet rs = qExec.execSelect() ;
+ int x = ResultSetFormatter.consume(rs) ;
+ assertEquals(1, x) ;
+ }) ;
+ server2.stop();
+ }
+
+ // Two servers, one dataset under two names.
+ @Test
+ public void multiple_04() {
+ DatasetGraph dsg = dataset() ;
+
+ int port1 = FusekiLib.choosePort() ;
+ FusekiServer server1 = FusekiServer.create().port(port1).add("/ds1", dsg).build().start() ;
+ Txn.executeWrite(dsg, ()->dsg.add(q1));
+
+ int port2 = FusekiLib.choosePort() ;
+ FusekiServer server2 = FusekiServer.create().port(port2).add("/ds2", dsg).build().start() ;
+ Txn.executeWrite(dsg, ()->dsg.add(q2));
+
+ query("http://localhost:"+port1+"/ds1", "SELECT * {?s ?p ?o}", qExec->{
+ ResultSet rs = qExec.execSelect() ;
+ int x = ResultSetFormatter.consume(rs) ;
+ assertEquals(2, x) ;
+ }) ;
+ query("http://localhost:"+port2+"/ds2", "SELECT * {?s ?p ?o}", qExec->{
+ ResultSet rs = qExec.execSelect() ;
+ int x = ResultSetFormatter.consume(rs) ;
+ assertEquals(2, x) ;
+ }) ;
+
+ server1.stop();
+ server2.stop();
+ }
+
+ /** Create an HttpEntity for the graph */
+ protected static HttpEntity graphToHttpEntity(final Graph graph) {
+ final RDFFormat syntax = RDFFormat.TURTLE_BLOCKS ;
+ ContentProducer producer = new ContentProducer() {
+ @Override
+ public void writeTo(OutputStream out) {
+ RDFDataMgr.write(out, graph, syntax) ;
+ }
+ } ;
+ EntityTemplate entity = new EntityTemplate(producer) ;
+ ContentType ct = syntax.getLang().getContentType() ;
+ entity.setContentType(ct.getContentType()) ;
+ return entity ;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..bfdcb42
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_1.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.main.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.main.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;
+
+/**
+ * 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 {
+ 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().port(PORT)
+ .verbose(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/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_2.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..295eebc
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/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.main.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.main.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, dispatch by {@code Content-Type}.
+ * 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().port(PORT)
+ .verbose(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/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/ExtendFuseki_AddService_3.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..f0dc08f
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/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.main.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.main.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().port(PORT)
+ .verbose(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();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/examples/SpecialService.java
----------------------------------------------------------------------
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/SpecialService.java
new file mode 100644
index 0000000..d7a00cc
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/main/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.main.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/7e6d03af/jena-fuseki2/jena-fuseki-main/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/src/test/resources/log4j.properties b/jena-fuseki2/jena-fuseki-main/src/test/resources/log4j.properties
new file mode 100644
index 0000000..e84e60e
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/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
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/config.ttl
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/config.ttl b/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/config.ttl
new file mode 100644
index 0000000..5a7f84a
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/config.ttl
@@ -0,0 +1,18 @@
+@prefix : <#> .
+@prefix fuseki: <http://jena.apache.org/fuseki#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .
+@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
+
+<#serviceInMemory> rdf:type fuseki:Service;
+ rdfs:label "test";
+ fuseki:name "FuTest";
+ fuseki:serviceQuery "query";
+ fuseki:serviceUpdate "update";
+ fuseki:serviceUpload "upload" ;
+ fuseki:dataset <#dataset> ;
+.
+
+<#dataset> rdf:type ja:RDFDataset;
+.
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/test.txt
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/test.txt b/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/test.txt
new file mode 100644
index 0000000..1a98ff9
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-main/testing/FusekiEmbedded/test.txt
@@ -0,0 +1 @@
+Test data.
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/jena-fuseki-server/pom.xml
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-server/pom.xml b/jena-fuseki2/jena-fuseki-server/pom.xml
new file mode 100644
index 0000000..d91bac1
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-server/pom.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>Apache Jena - Fuseki Server Jar</name>
+ <artifactId>jena-fuseki-server</artifactId>
+
+ <parent>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-fuseki</artifactId>
+ <version>3.9.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+
+ <packaging>jar</packaging>
+ <description>Fuseki server - combined jar with built-in webserver.</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-fuseki-main</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-fuseki-access</artifactId>
+ <version>3.9.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-cmds</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <configuration>
+ <shadedArtifactAttached>false</shadedArtifactAttached>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.jena.fuseki.main.cmds.FusekiMainCmd</mainClass>
+ </transformer>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer" />
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
+ <addHeader>false</addHeader>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <!-- Some jars are signed but shading breaks that.
+ Don't include signing files.
+ -->
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <!--<phase /><!- - Switch off -->
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-fuseki2/pom.xml
----------------------------------------------------------------------
diff --git a/jena-fuseki2/pom.xml b/jena-fuseki2/pom.xml
index 5607c06..1f73ecc 100644
--- a/jena-fuseki2/pom.xml
+++ b/jena-fuseki2/pom.xml
@@ -59,14 +59,15 @@
<modules>
<module>jena-fuseki-core</module>
- <module>jena-fuseki-embedded</module>
<module>jena-fuseki-access</module>
+ <module>jena-fuseki-main</module>
+ <module>jena-fuseki-server</module>
+
<module>jena-fuseki-webapp</module>
<module>jena-fuseki-war</module>
<module>jena-fuseki-fulljar</module>
- <module>jena-fuseki-basic</module>
<module>apache-jena-fuseki</module>
</modules>
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-integration-tests/pom.xml
----------------------------------------------------------------------
diff --git a/jena-integration-tests/pom.xml b/jena-integration-tests/pom.xml
index 14289d7..d70ef7d 100644
--- a/jena-integration-tests/pom.xml
+++ b/jena-integration-tests/pom.xml
@@ -115,7 +115,7 @@
<dependency>
<groupId>org.apache.jena</groupId>
- <artifactId>jena-fuseki-embedded</artifactId>
+ <artifactId>jena-fuseki-main</artifactId>
<version>3.9.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionFusekiBinary.java
----------------------------------------------------------------------
diff --git a/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionFusekiBinary.java b/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionFusekiBinary.java
index 881b87e..8b7f4dc 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionFusekiBinary.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionFusekiBinary.java
@@ -22,7 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.jena.fuseki.FusekiLib;
-import org.apache.jena.fuseki.embedded.FusekiServer;
+import org.apache.jena.fuseki.main.FusekiServer;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.QueryExecution;
http://git-wip-us.apache.org/repos/asf/jena/blob/7e6d03af/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionRemote.java
----------------------------------------------------------------------
diff --git a/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionRemote.java b/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionRemote.java
index 5dc87f1..00eb5a0 100644
--- a/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionRemote.java
+++ b/jena-integration-tests/src/test/java/org/apache/jena/test/rdfconnection/TestRDFConnectionRemote.java
@@ -21,7 +21,7 @@ package org.apache.jena.test.rdfconnection;
import org.apache.jena.atlas.logging.LogCtl ;
import org.apache.jena.fuseki.Fuseki ;
import org.apache.jena.fuseki.FusekiLib;
-import org.apache.jena.fuseki.embedded.FusekiServer ;
+import org.apache.jena.fuseki.main.FusekiServer ;
import org.apache.jena.rdfconnection.AbstractTestRDFConnection;
import org.apache.jena.rdfconnection.RDFConnection;
import org.apache.jena.rdfconnection.RDFConnectionFactory;