Repository: jena Updated Branches: refs/heads/master 368d051f3 -> 4692c7397
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/main/resources/META-INF/LICENSE b/jena-fuseki1/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/jena-fuseki1/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/resources/META-INF/NOTICE ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/main/resources/META-INF/NOTICE b/jena-fuseki1/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000..1bf7fa8 --- /dev/null +++ b/jena-fuseki1/src/main/resources/META-INF/NOTICE @@ -0,0 +1,16 @@ +Apache Jena - module Fuseki +Copyright 2011, 2012, 2013, 2014, 2015 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Portions of this software were originally based on the following: + - Copyright 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP + - Copyright 2010, 2011 Epimorphics Ltd. + - Copyright 2010, 2011 Talis Systems Ltd. +These have been licensed to the Apache Software Foundation under a software grant. + +- - - - - - - - - - - - - - - - - - - - - - - + +Portions of this software include software from Mort Bay Consulting Pty. Ltd. + - Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml b/jena-fuseki1/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml new file mode 100644 index 0000000..34082eb --- /dev/null +++ b/jena-fuseki1/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> +<!-- Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0" --> +<properties version="1.0"> + <comment>Fuseki System Properties</comment> + <entry key="org.apache.jena.fuseki.version">${project.version}</entry> + <entry key="org.apache.jena.fuseki.build.datetime">${build.time.xsd}</entry> +</properties> http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/ServerTest.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/ServerTest.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/ServerTest.java new file mode 100644 index 0000000..18150b1 --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/ServerTest.java @@ -0,0 +1,111 @@ +/* + * 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; + +import com.hp.hpl.jena.graph.Graph ; +import com.hp.hpl.jena.graph.Node ; +import com.hp.hpl.jena.graph.NodeFactory ; +import com.hp.hpl.jena.rdf.model.Model ; +import com.hp.hpl.jena.rdf.model.ModelFactory ; +import com.hp.hpl.jena.sparql.core.DatasetGraph ; +import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ; +import com.hp.hpl.jena.sparql.modify.request.Target ; +import com.hp.hpl.jena.sparql.modify.request.UpdateDrop ; +import com.hp.hpl.jena.sparql.sse.SSE ; +import com.hp.hpl.jena.update.Update ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateProcessor ; + +/** Manage a server for testing. + * Example for one server per test suite: + * <pre> + \@BeforeClass public static void beforeClass() { ServerTest.allocServer() ; } + \@AfterClass public static void afterClass() { ServerTest.freeServer() ; } + \@Before public void beforeTest() { ServerTest.resetServer() ; } + </pre> + */ +public class ServerTest +{ + // Abstraction that runs a SPARQL server for tests. + + public static final int port = 3635 ; // Different to the Fuseki2 test port. + public static final String urlRoot = "http://localhost:"+port+"/" ; + public static final String datasetPath = "/dataset" ; + public static final String serviceUpdate = "http://localhost:"+port+datasetPath+"/update" ; + public static final String serviceQuery = "http://localhost:"+port+datasetPath+"/query" ; + public static final String serviceREST = "http://localhost:"+port+datasetPath+"/data" ; // ?????? + + public static final String gn1 = "http://graph/1" ; + public static final String gn2 = "http://graph/2" ; + public static final String gn99 = "http://graph/99" ; + + public static final Node n1 = NodeFactory.createURI("http://graph/1") ; + public static final Node n2 = NodeFactory.createURI("http://graph/2") ; + public static final Node n99 = NodeFactory.createURI("http://graph/99") ; + + public static final Graph graph1 = SSE.parseGraph("(base <http://example/> (graph (<x> <p> 1)))") ; + public static final Graph graph2 = SSE.parseGraph("(base <http://example/> (graph (<x> <p> 2)))") ; + + public static final Model model1 = ModelFactory.createModelForGraph(graph1) ; + public static final Model model2 = ModelFactory.createModelForGraph(graph2) ; + + private static EmbeddedFusekiServer server = null ; + + // reference count of start/stop server + private static int countServer = 0 ; + + // This will cause there to be one server over all tests. + // Must be after initialization of counters + //static { allocServer() ; } + + static public void allocServer() + { + if ( countServer == 0 ) + setupServer() ; + countServer++ ; + } + + static public void freeServer() + { + if ( countServer >= 0 ) { + countServer -- ; + if ( countServer == 0 ) + teardownServer() ; + } + } + + protected static void setupServer() + { + DatasetGraph dsg = DatasetGraphFactory.createMem() ; + server = EmbeddedFusekiServer.create(port, dsg, datasetPath) ; + server.start() ; + } + + protected static void teardownServer() { + if ( server != null ) + server.stop() ; + server = null ; + } + public static void resetServer() + { + Update clearRequest = new UpdateDrop(Target.ALL) ; + UpdateProcessor proc = UpdateExecutionFactory.createRemote(clearRequest, ServerTest.serviceUpdate) ; + proc.execute() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java new file mode 100644 index 0000000..693217f --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java @@ -0,0 +1,61 @@ +/* + * 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; + +import org.apache.http.client.HttpClient ; +import org.apache.jena.atlas.logging.LogCtl ; +import org.apache.jena.fuseki.http.TestDatasetAccessorHTTP ; +import org.apache.jena.fuseki.http.TestDatasetGraphAccessorHTTP ; +import org.apache.jena.fuseki.http.TestHttpOp ; +import org.apache.jena.riot.web.HttpOp ; +import org.junit.AfterClass ; +import org.junit.BeforeClass ; +import org.junit.runner.RunWith ; +import org.junit.runners.Suite ; + +@RunWith(Suite.class) [email protected]( { + TestHttpOp.class + , TestSPARQLProtocol.class + , TestDatasetGraphAccessorHTTP.class + , TestDatasetAccessorHTTP.class + , TestQuery.class + , TestAuth.class +}) +public class TS_Fuseki extends ServerTest +{ + // Use HttpOp caching of connections during testing to stop + // swamping kernel socket management (seems to be most + // acute on Java 1.6) + + static HttpClient defaultHttpClient = HttpOp.getDefaultHttpClient() ; + // Used for all tests except auth tests. + static HttpClient globalCachingClient = HttpOp.createCachingHttpClient() ; + + @BeforeClass public static void beforeClassAbstract1() { + HttpOp.setDefaultHttpClient(globalCachingClient) ; + } + + @AfterClass public static void afterClassAbstract1() { + HttpOp.setDefaultHttpClient(defaultHttpClient) ; + } + + @BeforeClass static public void beforeClass() { LogCtl.disable(Fuseki.requestLogName) ; } + @AfterClass static public void afterClass() { LogCtl.setInfo(Fuseki.requestLogName) ;} +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestAuth.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestAuth.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestAuth.java new file mode 100644 index 0000000..4cff28d --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestAuth.java @@ -0,0 +1,429 @@ +/* + * 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; + +import java.io.File ; +import java.io.FileWriter ; +import java.io.IOException ; +import java.net.URI ; +import java.net.URISyntaxException ; +import java.util.HashMap ; +import java.util.Map ; + +import org.apache.jena.atlas.logging.LogCtl ; +import org.apache.jena.atlas.web.HttpException ; +import org.apache.jena.atlas.web.auth.PreemptiveBasicAuthenticator ; +import org.apache.jena.atlas.web.auth.ScopedAuthenticator ; +import org.apache.jena.atlas.web.auth.ServiceAuthenticator ; +import org.apache.jena.atlas.web.auth.SimpleAuthenticator ; +import org.apache.jena.fuseki.server.FusekiConfig ; +import org.apache.jena.fuseki.server.SPARQLServer ; +import org.apache.jena.fuseki.server.ServerConfig ; +import org.junit.AfterClass ; +import org.junit.Assert ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.query.ARQ ; +import com.hp.hpl.jena.query.DatasetAccessor ; +import com.hp.hpl.jena.query.DatasetAccessorFactory ; +import com.hp.hpl.jena.query.QueryExecutionFactory ; +import com.hp.hpl.jena.rdf.model.Model ; +import com.hp.hpl.jena.sparql.core.DatasetGraph ; +import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ; +import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP ; +import com.hp.hpl.jena.sparql.engine.http.QueryExceptionHTTP ; +import com.hp.hpl.jena.sparql.engine.http.Service ; +import com.hp.hpl.jena.sparql.modify.UpdateProcessRemoteBase ; +import com.hp.hpl.jena.sparql.util.Context ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateFactory ; +import com.hp.hpl.jena.update.UpdateRequest ; + +/** + * Tests Fuseki operation with authentication enabled + */ +public class TestAuth { + // Use different port etc because sometimes the previous testing servers + // don't release ports fast enough (OS issue / Linux) + public static final int authPort = ServerTest.port+10 ; + public static final String authUrlRoot = "http://localhost:"+authPort+"/" ; + public static final String authDatasetPath = "/dataset" ; + public static final String authServiceUpdate = "http://localhost:"+authPort+authDatasetPath+"/update" ; + public static final String authServiceQuery = "http://localhost:"+authPort+authDatasetPath+"/query" ; + public static final String authServiceREST = "http://localhost:"+authPort+authDatasetPath+"/data" ; + + + private static File realmFile; + private static SPARQLServer server; + + /** + * Sets up the authentication for tests + * @throws IOException + */ + @BeforeClass + public static void setup() throws IOException { + realmFile = File.createTempFile("realm", ".properties"); + + try(FileWriter writer = new FileWriter(realmFile)) { + writer.write("allowed: password, fuseki\n"); + writer.write("forbidden: password, other"); + } + + LogCtl.logLevel(Fuseki.serverLog.getName(), org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + LogCtl.logLevel(Fuseki.requestLog.getName(), org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + LogCtl.logLevel("org.eclipse.jetty", org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + + DatasetGraph dsg = DatasetGraphFactory.createMem(); + // This must agree with ServerTest + ServerConfig conf = FusekiConfig.defaultConfiguration(authDatasetPath, dsg, true, true); + conf.port = authPort ; + conf.pagesPort = authPort ; + conf.authConfigFile = realmFile.getAbsolutePath(); + + server = new SPARQLServer(conf); + server.start(); + } + + /** + * Tears down authentication test setup + */ + @AfterClass + public static void teardown() { + server.stop(); + + realmFile.delete(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_01() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + // No auth credentials should result in an error + qe.execAsk(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_02() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + // Auth credentials for valid user with bad password + qe.setBasicAuthentication("allowed", "incorrect".toCharArray()); + qe.execAsk(); + } + + @Test + public void query_with_auth_03() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + // Auth credentials for valid user with correct password + qe.setBasicAuthentication("allowed", "password".toCharArray()); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_04() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + // Auth credentials for valid user with correct password BUT not in + // correct role + qe.setBasicAuthentication("forbidden", "password".toCharArray()); + qe.execAsk(); + } + + @Test + public void query_with_auth_05() { + // Uses auth and enables compression + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + qe.setAllowDeflate(true); + qe.setAllowGZip(true); + + // Auth credentials for valid user with correct password + qe.setBasicAuthentication("allowed", "password".toCharArray()); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_06() { + // Uses auth and enables compression + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + qe.setAllowDeflate(true); + qe.setAllowGZip(true); + + // Auth credentials for valid user with bad password + qe.setBasicAuthentication("allowed", "incorrect".toCharArray()); + qe.execAsk(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_07() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password but scoped to + // wrong URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://example"), "allowed", + "password".toCharArray()); + qe.setAuthenticator(authenticator); + qe.execAsk(); + } + + @Test + public void query_with_auth_08() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // correct URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(authServiceQuery), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_09() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password using + // pre-emptive auth + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(authServiceQuery), "allowed", "password".toCharArray()); + qe.setAuthenticator(new PreemptiveBasicAuthenticator(authenticator)); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_10() { + Context ctx = ARQ.getContext(); + try { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped + // to correct URI + // Provided via Service Context and its associated authenticator + Map<String, Context> serviceContext = new HashMap<String, Context>(); + Context authContext = new Context(); + authContext.put(Service.queryAuthUser, "allowed"); + authContext.put(Service.queryAuthPwd, "password"); + serviceContext.put(authServiceQuery, authContext); + ctx.put(Service.serviceContext, serviceContext); + + qe.setAuthenticator(new ServiceAuthenticator()); + Assert.assertTrue(qe.execAsk()); + } finally { + ctx.remove(Service.serviceContext); + } + } + + @Test + public void query_with_auth_11() { + Context ctx = ARQ.getContext(); + try { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped + // to base URI of the actual service URL + // Provided via Service Context and its associated authenticator + Map<String, Context> serviceContext = new HashMap<String, Context>(); + Context authContext = new Context(); + authContext.put(Service.queryAuthUser, "allowed"); + authContext.put(Service.queryAuthPwd, "password"); + serviceContext.put(authUrlRoot, authContext); + ctx.put(Service.serviceContext, serviceContext); + + qe.setAuthenticator(new ServiceAuthenticator()); + Assert.assertTrue(qe.execAsk()); + } finally { + ctx.remove(Service.serviceContext); + } + } + + @Test + public void query_with_auth_12() { + ARQ.getContext().remove(Service.serviceContext); + + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password + // Use service authenticator with fallback credentials. + qe.setAuthenticator(new ServiceAuthenticator("allowed", "password".toCharArray())); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_13() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // base URI of the actual service URL + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(authUrlRoot), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_14() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(authServiceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // base URI of the actual service URL + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://localhost:" + authPort), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = HttpException.class) + public void update_with_auth_01() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + // No auth credentials should result in an error + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_02() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + // Auth credentials for valid user with bad password + ue.setAuthentication("allowed", "incorrect".toCharArray()); + ue.execute(); + } + + @Test + public void update_with_auth_03() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + // Auth credentials for valid user with correct password + ue.setAuthentication("allowed", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_04() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + // Auth credentials for valid user with correct password BUT not in + // correct role + ue.setAuthentication("forbidden", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_05() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, authServiceUpdate); + // No auth credentials should result in an error + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_06() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, authServiceUpdate); + // Auth credentials for valid user with bad password + ue.setAuthentication("allowed", "incorrect".toCharArray()); + ue.execute(); + } + + @Test + public void update_with_auth_07() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, authServiceUpdate); + // Auth credentials for valid user with correct password + ue.setAuthentication("allowed", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_08() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, authServiceUpdate); + // Auth credentials for valid user with correct password BUT not in + // correct role + ue.setAuthentication("forbidden", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_09() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + + // Auth credentials for valid user with correct password but scoped to + // wrong URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://example"), "allowed", + "password".toCharArray()); + ue.setAuthenticator(authenticator); + ue.execute(); + } + + @Test + public void update_with_auth_10() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + + // Auth credentials for valid user with correct password scoped to + // correct URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(authServiceUpdate), "allowed", "password".toCharArray()); + ue.setAuthenticator(authenticator); + ue.execute(); + } + + @Test + public void update_with_auth_11() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, authServiceUpdate); + + // Auth credentials for valid user with correct password scoped to + // correct URI + // Also using pre-emptive auth + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(authServiceUpdate), "allowed", "password".toCharArray()); + ue.setAuthenticator(new PreemptiveBasicAuthenticator(authenticator)); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_01() { + // No auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(authServiceREST); + accessor.getModel(); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_02() { + // Incorrect auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(authServiceREST, new SimpleAuthenticator("allowed", "incorrect".toCharArray())); + accessor.getModel(); + } + + @Test + public void graphstore_with_auth_03() { + // Correct auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(authServiceREST, new SimpleAuthenticator("allowed", "password".toCharArray())); + Model m = accessor.getModel(); + Assert.assertTrue(m.isEmpty()); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_04() throws URISyntaxException { + // Correct auth credentials scoped to wrong URI + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(authServiceREST, new ScopedAuthenticator(new URI("http://example.org/"), "allowed", "password".toCharArray())); + accessor.getModel(); + } + + @Test + public void graphstore_with_auth_05() throws URISyntaxException { + // Correct auth credentials scoped to correct URI + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(authServiceREST, new ScopedAuthenticator(new URI(authServiceREST), "allowed", "password".toCharArray())); + accessor.getModel(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestQuery.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestQuery.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestQuery.java new file mode 100644 index 0000000..5748dc4 --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestQuery.java @@ -0,0 +1,117 @@ +/* + * 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; + +import java.io.IOException ; +import java.net.HttpURLConnection ; +import java.net.URL ; + +import static org.apache.jena.fuseki.ServerTest.* ; + +import org.junit.AfterClass ; +import org.junit.Assert ; +import org.junit.BeforeClass ; +import org.junit.Test ; +import org.apache.jena.atlas.junit.BaseTest ; +import com.hp.hpl.jena.query.* ; +import com.hp.hpl.jena.sparql.core.Var ; +import com.hp.hpl.jena.sparql.engine.binding.Binding ; +import com.hp.hpl.jena.sparql.resultset.ResultSetCompare ; +import com.hp.hpl.jena.sparql.sse.Item ; +import com.hp.hpl.jena.sparql.sse.SSE ; +import com.hp.hpl.jena.sparql.sse.builders.BuilderResultSet ; +import com.hp.hpl.jena.sparql.util.Convert ; + +public class TestQuery extends BaseTest +{ + protected static ResultSet rs1 = null ; + static { + Item item = SSE.parseItem("(resultset (?s ?p ?o) (row (?s <x>)(?p <p>)(?o 1)))") ; + rs1 = BuilderResultSet.build(item) ; + } + + // DRY - test protocol? + @BeforeClass public static void beforeClass() + { + ServerTest.allocServer() ; + ServerTest.resetServer() ; + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.putModel(model1) ; + du.putModel(gn1, model2) ; + } + + @AfterClass public static void afterClass() + { + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.deleteDefault() ; + ServerTest.freeServer() ; + } + + @Test public void query_01() + { + execQuery("SELECT * {?s ?p ?o}", 1) ; + } + + @Test public void query_recursive_01() + { + String query = "SELECT * WHERE { SERVICE <" + serviceQuery + "> { ?s ?p ?o . BIND(?o AS ?x) } }"; + try(QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, query)) { + ResultSet rs = qExec.execSelect(); + + Var x = Var.alloc("x"); + while (rs.hasNext()) { + Binding b = rs.nextBinding(); + Assert.assertNotNull(b.get(x)); + } + } + } + + @Test public void query_with_params_01() + { + String query = "ASK { }"; + try(QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) { + boolean result = qExec.execAsk(); + Assert.assertTrue(result); + } + } + + @Test public void request_id_header_01() throws IOException + { + String qs = Convert.encWWWForm("ASK{}") ; + URL u = new URL(serviceQuery+"?query="+qs); + HttpURLConnection conn = (HttpURLConnection) u.openConnection(); + Assert.assertTrue(conn.getHeaderField("Fuseki-Request-ID") != null); + } + + private void execQuery(String queryString, int exceptedRowCount) + { + QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, queryString) ; + ResultSet rs = qExec.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertEquals(exceptedRowCount, x) ; + } + + private void execQuery(String queryString, ResultSet expectedResultSet) + { + QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, queryString) ; + ResultSet rs = qExec.execSelect() ; + boolean b = ResultSetCompare.equalsByTerm(rs, expectedResultSet) ; + assertTrue("Result sets different", b) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java new file mode 100644 index 0000000..3b86e17 --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java @@ -0,0 +1,95 @@ +/* + * 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; + +import static org.apache.jena.fuseki.ServerTest.* ; +import org.apache.jena.atlas.junit.BaseTest ; +import org.apache.jena.riot.WebContent ; +import org.junit.AfterClass ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.query.* ; +import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP ; +import com.hp.hpl.jena.sparql.util.Convert ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateFactory ; +import com.hp.hpl.jena.update.UpdateProcessor ; +import com.hp.hpl.jena.update.UpdateRequest ; +// Generally poke the server using Jena APIs +// SPARQL Query +// SPARQL Update +// GSP is done in TestDatasetAccessorHTTP + +public class TestSPARQLProtocol extends BaseTest +{ + @BeforeClass public static void beforeClass() + { + ServerTest.allocServer() ; + ServerTest.resetServer() ; + // Load some data. + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.putModel(model1) ; + du.putModel(gn1, model2) ; + } + + @AfterClass public static void afterClass() + { + ServerTest.resetServer() ; + ServerTest.freeServer() ; + } + + static String query(String base, String queryString) + { + return base+"?query="+Convert.encWWWForm(queryString) ; + } + + @Test public void query_01() + { + Query query = QueryFactory.create("SELECT * { ?s ?p ?o }") ; + QueryExecution qexec = QueryExecutionFactory.sparqlService(serviceQuery, query) ; + ResultSet rs = qexec.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertTrue( x != 0 ) ; + } + + @Test public void query_02() + { + Query query = QueryFactory.create("SELECT * { ?s ?p ?o }") ; + QueryEngineHTTP engine = QueryExecutionFactory.createServiceRequest(serviceQuery, query) ; + engine.setSelectContentType(WebContent.contentTypeResultsJSON) ; + ResultSet rs = engine.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertTrue( x != 0 ) ; + } + + @Test public void update_01() + { + UpdateRequest update = UpdateFactory.create("INSERT DATA {}") ; + UpdateProcessor proc = UpdateExecutionFactory.createRemote(update, serviceUpdate) ; + proc.execute() ; + } + + @Test public void update_02() + { + UpdateRequest update = UpdateFactory.create("INSERT DATA {}") ; + UpdateProcessor proc = UpdateExecutionFactory.createRemoteForm(update, serviceUpdate) ; + proc.execute() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetAccessorHTTP.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetAccessorHTTP.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetAccessorHTTP.java new file mode 100644 index 0000000..f8cf8fd --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetAccessorHTTP.java @@ -0,0 +1,261 @@ +/* + * 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.http; + +import static org.apache.jena.fuseki.ServerTest.* ; +import org.apache.jena.atlas.junit.BaseTest ; +import org.apache.jena.atlas.web.HttpException ; +import org.apache.jena.fuseki.ServerTest ; +import org.apache.jena.riot.web.HttpOp ; +import org.apache.jena.web.HttpSC ; +import org.junit.AfterClass ; +import org.junit.Before ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.query.DatasetAccessor ; +import com.hp.hpl.jena.query.DatasetAccessorFactory ; +import com.hp.hpl.jena.rdf.model.Model ; +import com.hp.hpl.jena.rdf.model.ModelFactory ; + + +public class TestDatasetAccessorHTTP extends BaseTest +{ + //Model level testing. + + static final String datasetURI_not_1 = "http://localhost:"+port+"/junk" ; + static final String datasetURI_not_2 = serviceREST+"/not" ; + static final String datasetURI_not_3 = "http://localhost:"+port+datasetPath+"/not/data" ; + + @BeforeClass public static void beforeClass() { ServerTest.allocServer() ; } + @AfterClass public static void afterClass() { ServerTest.freeServer() ; } + @Before public void before() { ServerTest.resetServer() ; } + + @Test(expected=HttpException.class) + public void test_ds_1() + { + // Can't GET the dataset service. + try { + HttpOp.execHttpGet(serviceREST) ; + } catch (HttpException ex) { + assertTrue(HttpSC.isClientError(ex.getResponseCode())) ; + throw ex ; + } + } + + @Test(expected=HttpException.class) + public void test_ds_2() + { + try { + HttpOp.execHttpGet(datasetURI_not_1) ; + } catch (HttpException ex) { + assertEquals(HttpSC.NOT_FOUND_404, ex.getResponseCode()) ; + throw ex ; + } + } + + @Test(expected=HttpException.class) + public void test_ds_3() + { + try { + HttpOp.execHttpGet(datasetURI_not_2) ; + } catch (HttpException ex) { + assertEquals(HttpSC.NOT_FOUND_404, ex.getResponseCode()) ; + throw ex ; + } + } + + @Test + public void test_404_1() + { + // Not the right service. + DatasetAccessor du = DatasetAccessorFactory.createHTTP(datasetURI_not_1) ; + Model graph = du.getModel(gn99) ; + assertNull(graph) ; + } + + @Test + public void test_404_2() + { + DatasetAccessor du = DatasetAccessorFactory.createHTTP(datasetURI_not_2) ; + Model graph = du.getModel(gn99) ; + assertNull(graph) ; + } + + @Test + public void test_404_3() + { + // Right service, wrong graph + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + Model graph = du.getModel(gn99) ; + assertNull(graph) ; + } + + @Test public void head_01() + { + DatasetAccessor du = create() ; + boolean b = du.containsModel(gn1) ; + assertFalse("Blank remote dataset as a named graph", b) ; + } + + @Test public void head_02() + { + DatasetAccessor du = create() ; + du.putModel(gn1, model1) ; + boolean exists = du.containsModel(gn1) ; + assertTrue(exists) ; + exists = du.containsModel(gn2) ; + assertFalse("Expected gn2 not to exist (1)", exists) ; + + exists = du.containsModel(gn2) ; + assertFalse("Expected gn2 not to exist (2)", exists) ; + // Clearup + du.deleteModel(gn1) ; + } + + @Test public void get_01() + { + DatasetAccessor du = create() ; + Model graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + } + + @Test public void get_02() + { + DatasetAccessor du = create() ; + Model graph = du.getModel(gn1) ; + assertNull(graph) ; + } + + @Test public void delete_01() + { + DatasetAccessor du = create() ; + du.deleteDefault() ; + } + + @Test public void delete_02() + { + DatasetAccessor du = create() ; + du.deleteModel(gn1) ; + boolean exists = du.containsModel(gn1) ; + assertFalse("Expected gn1 not to exist", exists) ; + } + + @Test public void put_01() + { + DatasetAccessor du = create() ; + du.putModel(model1) ; + Model graph = du.getModel() ; + assertTrue(graph.isIsomorphicWith(model1)) ; + // Empty it. + du.deleteDefault() ; + graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + } + + @Test public void put_02() + { + DatasetAccessor du = create() ; + du.putModel(gn1, model1) ; + boolean exists = du.containsModel(gn1) ; + assertTrue(exists) ; + exists = du.containsModel(gn2) ; + assertFalse("Expected gn2 not to exist", exists) ; + + Model graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + graph = du.getModel(gn1) ; + assertTrue(graph.isIsomorphicWith(model1)) ; + + du.deleteModel(gn1) ; + exists = du.containsModel(gn1) ; + assertFalse("Expected gn1 not to exist", exists) ; + + graph = du.getModel(gn1) ; + assertNull(graph) ; + } + + @Test public void put_03() + { + DatasetAccessor du = create() ; + du.putModel(model1) ; + du.putModel(model2) ; // PUT overwrites + Model graph = du.getModel() ; + assertFalse(graph.isIsomorphicWith(model1)) ; + assertTrue(graph.isIsomorphicWith(model2)) ; + // Empty it. + du.deleteDefault() ; + graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + } + + @Test public void post_01() + { + DatasetAccessor du = create() ; + du.putModel(model1) ; + du.add(model2) ; // POST appends + Model graph = du.getModel() ; + + Model graph3 = ModelFactory.createDefaultModel() ; + graph3.add(model1) ; + graph3.add(model2) ; + + assertFalse(graph.isIsomorphicWith(model1)) ; + assertFalse(graph.isIsomorphicWith(model2)) ; + assertTrue(graph.isIsomorphicWith(graph3)) ; + // Empty it. + du.deleteDefault() ; + graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + } + + @Test public void post_02() + { + DatasetAccessor du = create() ; + du.add(model1) ; + du.add(model2) ; + Model graph = du.getModel() ; + + Model graph3 = ModelFactory.createDefaultModel() ; + graph3.add(model1) ; + graph3.add(model2) ; + + assertFalse(graph.isIsomorphicWith(model1)) ; + assertFalse(graph.isIsomorphicWith(model2)) ; + assertTrue(graph.isIsomorphicWith(graph3)) ; + // Empty it. + du.deleteDefault() ; + graph = du.getModel() ; + assertTrue(graph.isEmpty()) ; + } + + @Test public void clearup_1() + { + DatasetAccessor du = create() ; + du.deleteDefault() ; + du.deleteModel(gn1) ; + du.deleteModel(gn2) ; + du.deleteModel(gn99) ; + } + + static DatasetAccessor create() + { + return DatasetAccessorFactory.createHTTP(ServerTest.serviceREST) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetGraphAccessorHTTP.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetGraphAccessorHTTP.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetGraphAccessorHTTP.java new file mode 100644 index 0000000..7687b2c --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestDatasetGraphAccessorHTTP.java @@ -0,0 +1,43 @@ +/* + * 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.http; + +import org.apache.jena.fuseki.ServerTest ; +import org.apache.jena.web.AbstractTestDatasetGraphAccessor ; +import org.apache.jena.web.DatasetGraphAccessor ; +import org.apache.jena.web.DatasetGraphAccessorHTTP ; +import org.junit.AfterClass ; +import org.junit.Before ; +import org.junit.BeforeClass ; + +public class TestDatasetGraphAccessorHTTP extends AbstractTestDatasetGraphAccessor +{ + @BeforeClass public static void beforeClass() { ServerTest.allocServer() ; } + @AfterClass public static void afterClass() { ServerTest.freeServer() ; } + @Before public void before() { + ServerTest.resetServer() ; + } + + + @Override + protected DatasetGraphAccessor getDatasetUpdater() + { + return new DatasetGraphAccessorHTTP(ServerTest.serviceREST) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestHttpOp.java ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestHttpOp.java b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestHttpOp.java new file mode 100644 index 0000000..1c5ccd5 --- /dev/null +++ b/jena-fuseki1/src/test/java/org/apache/jena/fuseki/http/TestHttpOp.java @@ -0,0 +1,214 @@ +/** + * 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.http; + +import java.io.IOException ; + +import org.apache.jena.atlas.io.IO ; +import org.apache.jena.atlas.junit.BaseTest ; +import org.apache.jena.atlas.web.HttpException ; +import org.apache.jena.atlas.web.TypedInputStream ; +import org.apache.jena.fuseki.ServerTest ; +import org.apache.jena.riot.WebContent ; +import org.apache.jena.riot.system.IRILib ; +import org.apache.jena.riot.web.HttpOp ; +import org.apache.jena.web.HttpSC ; +import org.junit.AfterClass ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.sparql.engine.http.Params ; +import com.hp.hpl.jena.util.FileUtils ; + +// This a mixture of testing HttpOp and testing basic operation of the SPARQL server +// especially error cases abnd unusual usage that the higher level APIs don't use. +public class TestHttpOp extends BaseTest { + + static String pingURL = ServerTest.urlRoot+"ping.txt" ; + @BeforeClass public static void beforeClass() { ServerTest.allocServer() ; } + @AfterClass public static void afterClass() { ServerTest.freeServer() ; } + + static String graphURL = ServerTest.serviceREST+"?default" ; + static String queryURL = ServerTest.serviceQuery ; + static String updateURL = ServerTest.serviceUpdate ; + + static String simpleQuery = queryURL+"?query="+IRILib.encodeUriComponent("ASK{}") ; + + // Basic operations + + @Test public void httpGet_01() { + TypedInputStream in = HttpOp.execHttpGet(pingURL) ; + IO.close(in) ; + } + + @Test(expected=HttpException.class) + public void httpGet_02() { + try { + TypedInputStream in = HttpOp.execHttpGet(ServerTest.urlRoot+"does-not-exist") ; + IO.close(in) ; + } catch(HttpException ex) { + assertEquals(HttpSC.NOT_FOUND_404, ex.getResponseCode()) ; + throw ex ; + } + } + + @Test public void httpGet_03() throws IOException { + String x = HttpOp.execHttpGetString(pingURL) ; + String y = FileUtils.readWholeFileAsUTF8("pages/ping.txt") ; + assertEquals(y,x) ; + } + + @Test public void httpGet_04() { + String x = HttpOp.execHttpGetString(ServerTest.urlRoot+"does-not-exist") ; + assertNull(x) ; + } + + @Test public void httpGet_05() { + TypedInputStream in = HttpOp.execHttpGet(simpleQuery) ; + IO.close(in) ; + } + + // SPARQL Query + + @Test public void queryGet_01() { + TypedInputStream in = HttpOp.execHttpGet(simpleQuery) ; + IO.close(in) ; + } + + @Test(expected=HttpException.class) + public void queryGet_02() { + try { + // No query. + TypedInputStream in = HttpOp.execHttpGet(queryURL+"?query=") ; + IO.close(in) ; + } catch (HttpException ex) { + assertEquals(ex.getResponseCode(), HttpSC.BAD_REQUEST_400) ; + throw ex ; + } + } + +// @Test(expected=HttpException.class) +// public void queryGet_03() { +// try { +// // Service description. +// TypedInputStream in = HttpOp.execHttpGet(queryURL) ; +// IO.close(in) ; +// } catch (HttpException ex) { +// assertEquals(ex.getResponseCode(), HttpSC.NOT_FOUND_404) ; +// throw ex ; +// } +// } + + @Test(expected=HttpException.class) + public void httpPost_01() { + try { + HttpOp.execHttpPost(queryURL, "ASK{}", "text/plain") ; + } catch (HttpException ex) { + assertEquals(ex.getResponseCode(), HttpSC.UNSUPPORTED_MEDIA_TYPE_415) ; + throw ex ; + } + } + + @Test(expected=HttpException.class) + public void httpPost_02() { + try { + HttpOp.execHttpPost(queryURL, "ASK{}", WebContent.contentTypeSPARQLQuery) ; + } catch (HttpException ex) { + assertEquals(ex.getResponseCode(), HttpSC.UNSUPPORTED_MEDIA_TYPE_415) ; + throw ex ; + } + } + + @Test(expected=HttpException.class) + public void httpPost_03() { + try { + HttpOp.execHttpPost(queryURL, "ASK{}", WebContent.contentTypeOctets) ; + } catch (HttpException ex) { + assertEquals(ex.getResponseCode(), HttpSC.UNSUPPORTED_MEDIA_TYPE_415) ; + throw ex ; + } + } + + @Test public void httpPost_04() { + Params params = new Params() ; + params.addParam("query", "ASK{}") ; + TypedInputStream in = HttpOp.execHttpPostFormStream(queryURL, params, WebContent.contentTypeResultsJSON) ; + IO.close(in) ; + } + + @Test(expected=HttpException.class) + public void httpPost_05() { + Params params = new Params() ; + params.addParam("query", "ASK{}") ; + TypedInputStream in = null ; + try { + // Query to Update + in = HttpOp.execHttpPostFormStream(updateURL, params, WebContent.contentTypeResultsJSON) ; + } catch (HttpException ex) { + assertEquals(ex.getResponseCode(), HttpSC.BAD_REQUEST_400) ; + throw ex ; + } + finally { IO.close(in) ; } + } + + @Test public void httpPost_06() { + Params params = new Params() ; + params.addParam("request", "CLEAR ALL") ; + HttpOp.execHttpPostForm(updateURL, params) ; + } + + // GSP + @Test public void gsp_01() { + String x = HttpOp.execHttpGetString(graphURL, "application/rdf+xml") ; + assertTrue(x.contains("</")) ; + assertTrue(x.contains(":RDF")) ; + } + + @Test public void gsp_02() { + String x = HttpOp.execHttpGetString(graphURL, "application/n-triples") ; + assertTrue(x.isEmpty()) ; + } + + static String graphString = "@prefix : <http://example/> . :s :p :o ." ; + + @Test public void gsp_03() { + HttpOp.execHttpPut(graphURL, WebContent.contentTypeTurtle, graphString) ; + } + + @Test public void gsp_04() { + HttpOp.execHttpPut(graphURL, WebContent.contentTypeTurtle, graphString) ; + String s1 = HttpOp.execHttpGetString(graphURL, WebContent.contentTypeNTriples) ; + assertFalse(s1.isEmpty()) ; + HttpOp.execHttpDelete(graphURL) ; + String s2 = HttpOp.execHttpGetString(graphURL, WebContent.contentTypeNTriples) ; + assertTrue(s2.isEmpty()) ; + } + + @Test public void gsp_05() { + HttpOp.execHttpDelete(graphURL) ; + + HttpOp.execHttpPost(graphURL, WebContent.contentTypeTurtle, graphString) ; + String s1 = HttpOp.execHttpGetString(graphURL, WebContent.contentTypeNTriples) ; + assertFalse(s1.isEmpty()) ; + HttpOp.execHttpDelete(graphURL) ; + String s2 = HttpOp.execHttpGetString(graphURL, WebContent.contentTypeNTriples) ; + assertTrue(s2.isEmpty()) ; + } +} + http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/jena-fuseki1/src/test/resources/log4j.properties b/jena-fuseki1/src/test/resources/log4j.properties new file mode 100644 index 0000000..da8f386 --- /dev/null +++ b/jena-fuseki1/src/test/resources/log4j.properties @@ -0,0 +1,20 @@ +log4j.rootLogger=INFO,stdlog + +log4j.appender.stdlog=org.apache.log4j.ConsoleAppender +log4j.appender.stdlog.layout=org.apache.log4j.PatternLayout +log4j.appender.stdlog.layout.ConversionPattern=%d{HH:mm:ss} %-5p %-25c{1} :: %m%n + +# Jena Dependency log levels +log4j.logger.com.hp.hpl.jena.arq.info=INFO +log4j.logger.com.hp.hpl.jena.arq.exec=INFO +log4j.logger.com.hp.hpl.jena=WARN +log4j.logger.org.apache.jena=WARN +log4j.logger.org.apache.jena.riot=INFO + +# Jetty - Fuseki catches Jetty errors and reports them. +log4j.logger.org.eclipse.jetty=FATAL + +# Fuseki +log4j.logger.org.apache.jena.fuseki.Server=WARN +log4j.logger.org.apache.jena.fuseki.Fuseki=WARN +log4j.logger.org.apache.jena.fuseki=WARN \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/tdb.ttl ---------------------------------------------------------------------- diff --git a/jena-fuseki1/tdb.ttl b/jena-fuseki1/tdb.ttl new file mode 100644 index 0000000..6cc1130 --- /dev/null +++ b/jena-fuseki1/tdb.ttl @@ -0,0 +1,30 @@ +# 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. + +@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> . +@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#> . + +[] ja:loadClass "com.hp.hpl.jena.tdb.TDB" . +tdb:DatasetTDB rdfs:subClassOf ja:RDFDataset . +tdb:GraphTDB rdfs:subClassOf ja:Model . + + <#dataset> rdf:type tdb:DatasetTDB ; + tdb:location "DB" ; +## tdb:unionDefaultGraph true ; + . http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 568340d..4f20cc2 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ <module>jena-core</module> <module>jena-arq</module> <module>jena-tdb</module> - <!--<module>jena-fuseki</module>--> + <!--<module>jena-fuseki1</module>--> <module>jena-fuseki2</module> <!-- <module>jena-security</module> Lots of output and warnings --> @@ -110,7 +110,7 @@ <module>jena-sdb</module> - <module>jena-fuseki</module> + <module>jena-fuseki1</module> <module>jena-fuseki2</module> <module>jena-security</module>
