use of org.apache.jena.fuseki.servlets.ActionService in project jena by apache.
the class ExFuseki_03_AddService_ContentType method main.
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.alloc("http://example/special3", "special3", "Custom operation");
// Service endpoint name.
String endpointName = "special";
String contentType = "application/special";
// The handled for the new operation.
ActionService customHandler = new DemoService();
FusekiServer server = FusekiServer.create().port(PORT).verbose(true).registerOperation(myOperation, contentType, customHandler).add(DATASET, DatasetGraphFactory.createTxnMem(), true).addEndpoint(DATASET, endpointName, myOperation).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;
try {
// Dataset endpoint name : POST, with Content-type.
try (TypedInputStream stream = HttpOp.httpPostStream(datasetURL, contentType, BodyPublishers.ofString(""), "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();
}
}
use of org.apache.jena.fuseki.servlets.ActionService in project jena by apache.
the class FusekiConfig method buildEndpoint.
/**
* Parse {@code fuseki:endpoint}
* <pre>
* fuseki:endpoint [
* fuseki:operation fuseki:Query ;
* fuseki:opImplementation <java:package.Class>
* fuseki:allowedUsers (....) ;
*
* ja:context [ ja:cxtName "arq:queryTimeout" ; ja:cxtValue "1000" ] ;
* ja:context [ ja:cxtName "arq:queryLimit" ; ja:cxtValue "10000" ] ;
* ja:context [ ja:cxtName "tdb:defaultUnionGraph" ; ja:cxtValue "true" ] ;
*
* and specials:
* fuseki:timeout "1000,1000" ;
* fuseki:queryLimit 1000;
* arq:unionGraph true;
* ] ;
* </pre>
*/
private static Endpoint buildEndpoint(Resource fusekiService, Resource endpoint) {
// Endpoints are often blank nodes so use fusekiService in error messages.
// fuseki:operation
RDFNode opResource = getZeroOrOne(endpoint, pOperation);
Operation op = null;
if (opResource != null) {
if (!opResource.isResource() || opResource.isAnon())
throw exception("Blank node endpoint operation in service %s", nodeLabel(fusekiService));
Node opRef = opResource.asNode();
op = Operation.get(opRef);
}
// fuseki:implementation - checking only, not active.
if (op == null) {
RDFNode rImpl = getZeroOrOne(endpoint, pImplementation);
if (rImpl == null)
throw exception("No implementation for fuseki:operation '%s' in service %s", nodeLabel(opResource), nodeLabel(fusekiService));
// Global registry. Replace existing registry.
Pair<Operation, ActionService> x = BuildLib.loadOperationActionService(rImpl);
Operation op2 = x.getLeft();
ActionService proc = x.getRight();
if (op2 == null)
throw exception("Failed to load implementation for fuseki:operation '%s' in service %s", nodeLabel(opResource), nodeLabel(fusekiService));
op = op2;
// Using a blank node (!) for the operation means this is safe!
// OperationRegistry.get().register(op2, proc);
}
// fuseki:allowedUsers
AuthPolicy authPolicy = FusekiConfig.allowedUsers(endpoint);
// fuseki:name
RDFNode epNameR = getZeroOrOne(endpoint, pEndpointName);
String epName = null;
if (epNameR == null) {
// // Make required to give "" for dataset, not default to dataset if missing.
// throw exception("No service name for endpoint", fusekiService, ep, pServiceName);
epName = Endpoint.DatasetEP.string;
} else {
if (!epNameR.isLiteral())
throw exception("Not a literal for service name for endpoint", fusekiService, endpoint, pEndpointName);
epName = epNameR.asLiteral().getLexicalForm();
}
Context cxt = parseContext(endpoint);
// Per-endpoint context.
// Could add special names:
// fuseki:timeout
// fuseki:queryLimit
// fuseki:unionDefaultGraph
Endpoint ep = Endpoint.create().operation(op).endpointName(epName).authPolicy(authPolicy).context(cxt).build();
return ep;
}
use of org.apache.jena.fuseki.servlets.ActionService in project jena by apache.
the class BuildLib method loadOperationActionService.
/**
* Load a class (an {@link ActionService}) and create an {@link Operation} for it.
*/
/*package*/
static Pair<Operation, ActionService> loadOperationActionService(RDFNode implementation) {
String classURI = implementation.isLiteral() ? implementation.asLiteral().getLexicalForm() : ((Resource) implementation).getURI();
String javaScheme = "java:";
String fileScheme = "file:";
String scheme = null;
if (classURI.startsWith(javaScheme)) {
scheme = javaScheme;
} else if (classURI.startsWith(fileScheme)) {
scheme = fileScheme;
} else {
Fuseki.configLog.error("Class to load is not 'java:' or 'file:': " + classURI);
throw new FusekiConfigException("Not a 'java:' or 'file:' class reference: " + classURI);
}
String className = classURI.substring(scheme.length());
ActionService action = null;
try {
Class<?> cls;
if (Objects.equals(scheme, fileScheme)) {
try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { new URL(classURI) })) {
cls = Class.forName(className, true, urlClassLoader);
}
} else {
cls = Class.forName(className);
}
Constructor<?> x = cls.getConstructor();
action = (ActionService) x.newInstance();
} catch (ClassNotFoundException ex) {
throw new FusekiConfigException("Class not found: " + className);
} catch (Exception ex) {
throw new FusekiConfigException("Can't create object from " + className);
}
Operation op = Operation.alloc(NodeFactory.createBlankNode(), classURI, classURI);
return Pair.create(op, action);
}
use of org.apache.jena.fuseki.servlets.ActionService in project jena by apache.
the class ExFuseki_01_NamedService method main.
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.alloc("http://example/special1", "special1", "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 DemoService();
FusekiServer server = FusekiServer.create().port(PORT).verbose(true).registerOperation(myOperation, customHandler).add(DATASET, DatasetGraphFactory.createTxnMem(), true).addEndpoint(DATASET, endpointName, myOperation).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.httpGetString(customOperationURL);
System.out.print(s1);
if (s1 == null)
System.out.println();
// Service endpoint name : POST
try (TypedInputStream stream = HttpOp.httpPostStream(customOperationURL, "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.httpDelete(customOperationURL);
throw new IllegalStateException("DELETE succeeded");
} catch (HttpException ex) {
if (ex.getStatusCode() != 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();
}
}
use of org.apache.jena.fuseki.servlets.ActionService in project jena by apache.
the class ExFuseki_02_Config_DataService method main.
public static void main(String... args) {
// Register a new operation
Operation myOperation = Operation.alloc("http://example/special2", "special2", "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 = DataService.newBuilder(dsg).addEndpoint(myOperation, customEndpoint).addEndpoint(Operation.Query, queryEndpoint).build();
// This will be the code to handled for the operation.
ActionService customHandler = new DemoService();
FusekiServer server = FusekiServer.create().port(PORT).verbose(true).registerOperation(myOperation, customHandler).add(DATASET, dataService).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 = QueryExecution.service(queryOperationURL, query)) {
qExec.execAsk();
}
// Try the usual default name, which is not configured in the DataService so expect a 404.
try (QueryExecution qExec = QueryExecution.service(SERVER_URL + DATASET + "/sparql", query)) {
qExec.execAsk();
throw new RuntimeException("Didn't fail");
} catch (QueryExceptionHTTP ex) {
if (ex.getStatusCode() != HttpSC.NOT_FOUND_404) {
throw new RuntimeException("Not a 404", ex);
}
}
// Make an HTTP GET to the custom operation.
// Service endpoint name : GET
String s1 = HttpOp.httpGetString(customOperationURL);
if (s1 == null)
throw new RuntimeException("Failed: " + customOperationURL);
} finally {
server.stop();
}
}
Aggregations