Skip to content
Snippets Groups Projects
Commit 53ec1693 authored by Andreas Schärtl's avatar Andreas Schärtl
Browse files

uloapi: add /statistics HTML demo

- This also works just as well as a REST endpoint.

- Most likely this is just a demo. But it works for that.
parent dddbf2bf
No related branches found
No related tags found
No related merge requests found
Showing
with 154 additions and 24 deletions
uloapi
======
This repository contains the `uloapi` codebase, a JVM (Java) project
that uses the RDF4J library [1] which I might end up using for
connecting MMT to the data set extracted/indexed from MathHub.
Running
-------
To build and start the demo, first make sure the configuration file
`uloapi.properties` is to your liking. Once ready, simply run
mvn compile exec:java
to run the demo. To compile all classes including dependencies in one
single JAR, run
mvn install
References
----------
[1] https://rdf4j.org/
......@@ -83,5 +83,10 @@
<artifactId>spark-template-freemarker</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>19.0.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package info.mathhub.uloapi.html;
import org.eclipse.jetty.http.HttpStatus;
import spark.ModelAndView;
import spark.Request;
import spark.Response;
import spark.Route;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.*;
import spark.template.freemarker.FreeMarkerEngine;
import java.util.HashMap;
......@@ -13,6 +12,8 @@ import java.util.Map;
public class Errors {
private Errors() {};
private static final Logger log = LoggerFactory.getLogger(Errors.class);
/**
* Singleton instance of the Freemarker engine for use with errors.
* Used in {@link Errors#createError}.
......@@ -35,7 +36,22 @@ public class Errors {
return createError(HttpStatus.INTERNAL_SERVER_ERROR_500).handle(request, response);
};
private static Route createError(int status) {
public static final ExceptionHandler<Exception> exceptionHandler = (exception, request, response) -> {
final Map<String, Object> model = new HashMap<>();
model.put("exception_message", exception.getMessage());
try {
createError(HttpStatus.INTERNAL_SERVER_ERROR_500, model).handle(request, response);
} catch (Exception e) {
log.error(e.getMessage());
for (final StackTraceElement element : e.getStackTrace()) {
log.error(element.toString());
}
}
};
@SafeVarargs
private static Route createError(int status, Map<String, Object> ...additionalModels) {
return (Request request, Response response) -> {
// set content type
......@@ -44,8 +60,12 @@ public class Errors {
// prepare model
final Map<String, Object> model = new HashMap<>();
model.put("status", status);
model.put("description", HttpStatus.getMessage(status));
model.put("http_status", status);
model.put("http_description", HttpStatus.getMessage(status));
for (final Map<String, Object> additionalModel : additionalModels) {
model.putAll(additionalModel);
}
// render
......
......@@ -12,9 +12,10 @@ public class Main {
public static void main(String[] args) {
get("/", Routes.index, new FreeMarkerEngine());
get("/statistics", Routes.statistics, new FreeMarkerEngine());
notFound(Errors.notFound);
internalServerError(Errors.internalServerError);
notFound(Errors.notFound);
after(Filters.setHtmlContentType);
}
......
package info.mathhub.uloapi.html;
import info.mathhub.uloapi.query.Query;
import info.mathhub.uloapi.query.Statistics;
import spark.*;
import java.util.HashMap;
......@@ -15,4 +16,16 @@ public class Routes {
public static final TemplateViewRoute index = (Request request, Response response) -> {
return new ModelAndView(null, "index.flt");
};
public static final TemplateViewRoute statistics = (Request request, Response response) -> {
final Query query = Query.getSingleton();
final Statistics statistics = query.getStatistics();
final Map<String, Object> model = new HashMap<>();
model.put("statistics_num_triplets", statistics.numTriplets);
model.put("statistics_is_writeable", Boolean.toString(statistics.isWriteable));
model.put("statistics_data_dir", statistics.dataDir);
return new ModelAndView(model, "statistics.flt");
};
}
......@@ -2,6 +2,8 @@ package info.mathhub.uloapi.query;
import info.mathhub.uloapi.config.Config;
import java.io.File;
public class Query {
private final String serverUrl;
private final String repository;
......@@ -22,11 +24,23 @@ public class Query {
}
public Statistics getStatistics() {
final GraphDB.Operation<Long> operation = (manager, repository, connection) -> {
return connection.size();
final GraphDB.Operation<Statistics> operation = (manager, repository, connection) -> {
final Statistics statistics = new Statistics();
statistics.isWriteable = repository.isWritable();
statistics.numTriplets = connection.size();
{
final File dataDir = repository.getDataDir();
if (dataDir != null) {
statistics.dataDir = dataDir.getAbsolutePath();
}
}
return statistics;
};
final long numTriplets = GraphDB.execute(this.serverUrl, this.repository, operation);
return new Statistics(numTriplets);
return GraphDB.execute(this.serverUrl, this.repository, operation);
}
}
package info.mathhub.uloapi.query;
import org.jetbrains.annotations.NotNull;
/**
* Contains statistic information about the backing storage.
*/
......@@ -9,7 +11,15 @@ public class Statistics {
*/
public long numTriplets;
Statistics(long numTriplets) {
this.numTriplets = numTriplets;
}
/**
* Whether the data in this repository is writeable. If it isn't,
* it is only readable.
*/
public boolean isWriteable;
/**
* The directory on the server where the data is stored.
*/
@NotNull
public String dataDir = "unknown";
}
......@@ -18,12 +18,30 @@
font-size: 12pt;
}
nav {
border-bottom: solid 1px;
padding-bottom: 1em;
padding-top: 1em;
}
code {
font-family: monospace;
}
a {
color: blue;
}
h1 {
display: inline-block;
font-weight: bold;
}
</style>
</head>
<body>
<nav>
<h1><a href="/">uloapi</a></h1> | <a href="/statistics">Statistics</a> | <a href="/queries">Queries</a>
</nav>
<main>
<@page_main/>
</main>
......
<#include "base.flt">
<#macro page_title>
Error ${status}
Error ${http_status}
</#macro>
<#macro page_main>
<h1>Error ${status}: ${description}</h1>
<p>Grow old or die trying.</p>
<h2>Error ${http_status}: ${http_description}</h2>
<#if message?has_content>
<code>
${exception_message}
</code>
</#if>
</#macro>
<@display_page/>
......@@ -5,9 +5,9 @@
</#macro>
<#macro page_main>
<h1>ULO/RDF Endpoint</h1>
<h2>ULO/RDF Endpoint</h2>
<p>This is a technology demo of an ULO/RDF Endpoint.</p>
<h2>Introduction</h2>
<h3>Introduction</h3>
<p>
Working with RDF triplets is somewhat easy with the <a href="https://rdf4j.org">RDF4J</a> library.
This demo uses RDF4J to illustrate that (1) a connection to an existing database can be established
......@@ -18,10 +18,6 @@
It is no incident that this demo is hacked together with a JVM-based stack. Potential integration
into MMT should be easier with lessons learned from this demo.
</p>
<h2>Demos</h2>
<ul>
<li><a href="/statistics">Show (not every interesting) Statistics</a> about the imported ULO/RDF dataset.</li>
</ul>
</#macro>
<@display_page/>
\ No newline at end of file
<#include "base.flt">
<#macro page_title>
Statistics
</#macro>
<#macro page_main>
<h2>Statistics</h2>
<p>
Show not very interesting statistics about the connected database. Illustrates
that we made a connection and can take a look at imported data.
</p>
<h3>Counts</h3>
<ul>
<li>Total Triplets in Repository: <code>${statistics_num_triplets}</code></li>
<li>Repository Writeable: <code>${statistics_is_writeable}</code></li>
<li>Repository Data directory: <code>${statistics_data_dir}</code></li>
</ul>
</#macro>
<@display_page/>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment