Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stack-clients/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-client:
image: ghcr.io/theworldavatar/stack-client${IMAGE_SUFFIX}:1.54.1
image: ghcr.io/theworldavatar/stack-client${IMAGE_SUFFIX}:1.55.0
secrets:
- blazegraph_password
- postgis_password
Expand Down
4 changes: 2 additions & 2 deletions stack-clients/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.cmclinnovations</groupId>
<artifactId>stack-clients</artifactId>
<version>1.54.1</version>
<version>1.55.0</version>

<name>Stack Clients</name>
<url>https://theworldavatar.io</url>
Expand Down Expand Up @@ -116,7 +116,7 @@
<dependency>
<groupId>uk.ac.cam.cares.jps</groupId>
<artifactId>jps-base-lib</artifactId>
<version>1.48.0</version>
<version>1.49.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-annotations -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.cmclinnovations.stack.clients.timeseries;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.time.Instant;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.cmclinnovations.stack.clients.core.EndpointNames;
import com.cmclinnovations.stack.clients.ontop.OntopClient;
import com.cmclinnovations.stack.clients.utils.LocalTempDir;
import com.cmclinnovations.stack.services.OntopService;
import com.cmclinnovations.stack.services.ServiceManager;
import com.cmclinnovations.stack.services.config.ServiceConfig;

import uk.ac.cam.cares.jps.base.exception.JPSRuntimeException;
import uk.ac.cam.cares.jps.base.timeseries.TimeSeriesRDBClientOntop;

public class TimeSeriesRDBClient<T> extends TimeSeriesRDBClientOntop<T> {

private static final String UNIX_TRS = "http://dbpedia.org/resource/Unix_time";
private static final String GENERIC_TRS = "http://example.org/TRS_placeholder";

/**
* Logger for error output.
*/
private static final Logger LOGGER = LogManager.getLogger(TimeSeriesRDBClient.class);

// IRI of temporal reference system, used in ontop mapping to indicate reference
// of time, e.g. Unix
private final String trsIri;

// name of ontop container
private String ontopName = "ontop-timeseries";

public TimeSeriesRDBClient(Class<T> timeClass) {
this(timeClass, null);
}

public TimeSeriesRDBClient(Class<T> timeClass, String trsIri) {
super(timeClass);
if (null != trsIri) {
this.trsIri = trsIri;
LOGGER.info("TRS is set to {}", trsIri);
} else {
if (Instant.class == timeClass) {
this.trsIri = UNIX_TRS;
LOGGER.info("Time class is Instant, TRS is set to {}", UNIX_TRS);
} else {
this.trsIri = GENERIC_TRS;
LOGGER.info("Time class is not Instant, TRS is set to {}", GENERIC_TRS);
}
}
}

public void setOntopName(String ontopName) {
this.ontopName = ontopName;
}

@Override
public List<Integer> bulkInitTimeSeriesTable(List<List<String>> dataIRIs, List<List<Class<?>>> dataClasses,
List<String> tsIRIs, Integer srid, Connection conn) {
List<Integer> result = super.bulkInitTimeSeriesTable(dataIRIs, dataClasses, tsIRIs, srid, conn);

// spin up a new ontop container if it does not exist
configureOntop();

return result;
}

public void configureOntop() {
String stackName = System.getenv("STACK_NAME");
if (stackName == null) {
LOGGER.warn("STACK_NAME not detected, skipping Ontop intialisation");
return;
}

ServiceManager serviceManager = new ServiceManager(false);

ServiceConfig newOntopServiceConfig = serviceManager.duplicateServiceConfig(EndpointNames.ONTOP, ontopName);
newOntopServiceConfig.setEnvironmentVariable(OntopService.ONTOP_DB_NAME, "postgres");

newOntopServiceConfig.getEndpoints()
.replaceAll((endpointName, connection) -> new com.cmclinnovations.stack.services.config.Connection(
connection.getUrl(),
connection.getUri(),
URI.create(connection.getExternalPath().toString()
.replace(EndpointNames.ONTOP, ontopName))));
serviceManager.initialiseService(stackName, ontopName);

OntopClient ontopClient = OntopClient.getInstance(ontopName);

// create temporary file for ontop mapping
try (LocalTempDir tempDir = new LocalTempDir()) {

String obda = prepareMapping();

Path filePath = tempDir.getPath().resolve("ontop.obda");
Files.write(filePath, obda.getBytes());

// sends obda to container
ontopClient.updateOBDA(filePath);
} catch (IOException e) {
throw new JPSRuntimeException("Failed to write ontop mapping into temporary folder", e);
}
}

/**
* set TRS in Ontop mapping
*
* @return
*/
private String prepareMapping() {
// read template from resources folder
try (InputStream is = TimeSeriesRDBClient.class.getResourceAsStream("timeseries_ontop_template.obda")) {
return IOUtils.toString(is, StandardCharsets.UTF_8)
.replace("[TRS_REPLACE]", trsIri).replace("[SCHEMA]", getSchema());
} catch (IOException e) {
throw new JPSRuntimeException("Error while reading timeseries_ontop_template.obda", e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[PrefixDeclaration]
obda: https://w3id.org/obda/vocabulary#
geo: http://www.opengis.net/ont/geosparql#
timeprefix: http://www.w3.org/2006/time#
timeseries: https://www.theworldavatar.com/kg/ontotimeseries/

[MappingDeclaration] @collection [[
mappingId time_series_data_[SCHEMA]
target timeseries:data/[SCHEMA]/{data_iri_index} timeseries:hasObservation timeseries:observation/[SCHEMA]/{id} .
timeseries:observation/[SCHEMA]/{id} a timeseries:Observation ;
timeseries:observationOf timeseries:data/[SCHEMA]/{data_iri_index} ;
timeseries:hasResult timeseries:result/[SCHEMA]/{id} ;
timeprefix:hasTime timeseries:time/[SCHEMA]/{id} .
timeseries:time/[SCHEMA]/{id} a timeprefix:Instant ;
timeprefix:inXSDDateTime {time_as_timestamp} ;
timeprefix:inTimePosition timeseries:timePosition/[SCHEMA]/{id}.
timeseries:timePosition/[SCHEMA]/{id} a timeprefix:TimePosition ;
timeprefix:numericPosition {time_as_number} ;
timeprefix:unitType timeprefix:unitSecond ;
timeprefix:hasTRS <[TRS_REPLACE]> .
timeseries:result/[SCHEMA]/{id} a timeseries:Result ;
timeseries:hasValue {"double precision"}, {wkt}^^geo:wktLiteral, {int};
timeseries:hasUnit {unit} .
source SELECT id, time_as_number, time_as_timestamp, data_iri_index, "double precision", ST_AsText("geometry(Point,4326)") AS wkt, int, unit FROM "[SCHEMA]".time_series_data

mappingId equivalent_iri_[SCHEMA]
target <{data_iri}> obda:isCanonicalIRIOf timeseries:data/[SCHEMA]/{data_iri_index} .
source SELECT data_iri, data_iri_index from "[SCHEMA]".time_series_data_iri
]]
2 changes: 1 addition & 1 deletion stack-data-uploader/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-data-uploader:
image: ghcr.io/theworldavatar/stack-data-uploader${IMAGE_SUFFIX}:1.54.1
image: ghcr.io/theworldavatar/stack-data-uploader${IMAGE_SUFFIX}:1.55.0
secrets:
- blazegraph_password
- postgis_password
Expand Down
4 changes: 2 additions & 2 deletions stack-data-uploader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.cmclinnovations</groupId>
<artifactId>stack-data-uploader</artifactId>
<version>1.54.1</version>
<version>1.55.0</version>

<name>Stack Data Uploader</name>
<url>https://theworldavatar.io</url>
Expand Down Expand Up @@ -38,7 +38,7 @@
<dependency>
<groupId>com.cmclinnovations</groupId>
<artifactId>stack-clients</artifactId>
<version>1.54.1</version>
<version>1.55.0</version>
</dependency>

<dependency>
Expand Down
2 changes: 1 addition & 1 deletion stack-manager/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
stack-manager:
image: ghcr.io/theworldavatar/stack-manager${IMAGE_SUFFIX}:1.54.1
image: ghcr.io/theworldavatar/stack-manager${IMAGE_SUFFIX}:1.55.0
environment:
EXTERNAL_PORT: "${EXTERNAL_PORT-3838}"
STACK_BASE_DIR: "${STACK_BASE_DIR}"
Expand Down
4 changes: 2 additions & 2 deletions stack-manager/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>com.cmclinnovations</groupId>
<artifactId>stack-manager</artifactId>
<version>1.54.1</version>
<version>1.55.0</version>

<name>Stack Manager</name>
<url>https://theworldavatar.io</url>
Expand Down Expand Up @@ -38,7 +38,7 @@
<dependency>
<groupId>com.cmclinnovations</groupId>
<artifactId>stack-clients</artifactId>
<version>1.54.1</version>
<version>1.55.0</version>
</dependency>

<dependency>
Expand Down
Loading