/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.fuseki.embedded;
import static org.apache.jena.fuseki.embedded.TestEmbeddedFuseki.dataset ;
import static org.apache.jena.fuseki.embedded.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.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 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server1 = FusekiEmbeddedServer.create().setPort(port).add("/ds1", dsg).build() ;
// Same port - Bbad.
FusekiEmbeddedServer server2 = FusekiEmbeddedServer.create().setPort(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 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server1 = FusekiEmbeddedServer.create().setPort(port1).add("/ds1", dsg).build() ;
// Different port - good
int port2 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server2 = FusekiEmbeddedServer.create().setPort(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 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server1 = FusekiEmbeddedServer.create().setPort(port1).add("/ds", dsg1).build().start() ;
Txn.executeWrite(dsg1, ()->dsg1.add(q1));
int port2 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server2 = FusekiEmbeddedServer.create().setPort(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 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server1 = FusekiEmbeddedServer.create().setPort(port1).add("/ds1", dsg).build().start() ;
Txn.executeWrite(dsg, ()->dsg.add(q1));
int port2 = FusekiTestServer.choosePort() ;
FusekiEmbeddedServer server2 = FusekiEmbeddedServer.create().setPort(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 ;
}
}