Commit fdaaeb6e authored by Daniel Eggert's avatar Daniel Eggert
Browse files

refactored gms-index-mediator into its own repository

parent 55ba0ddd
This diff is collapsed.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.potsdam.gfz</groupId>
<artifactId>gms-index-mediator</artifactId>
<version>0.0.1</version>
<name>gms-index-mediator</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<geotools.version>15.0</geotools.version>
<generatedSources.path>generated-sources/java</generatedSources.path>
<generatedSources.folder>${project.build.directory}/${generatedSources.path}</generatedSources.folder>
<version.template.file>src/main/resources/Version.java.template</version.template.file>
<version.file.path>/de/potsdam/gfz/gms/indexmediator/Version.java</version.file.path>
<version.file>${generatedSources.folder}${version.file.path}</version.file>
</properties>
<repositories>
<repository>
<id>GeoSolutions</id>
<url>http://maven.geo-solutions.it/</url>
</repository>
</repositories>
<build>
<plugins>
<!-- Copies the start/stop script into the target folder -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/bin/</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>de.potsdam.gfz.gms.indexmediator.SpatialIndexMediatorServer</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>.svg</resource>
<resource>.properties</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>clear target folder after uber-jar was build</id>
<phase>package</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>${project.build.directory}</directory>
<excludes>
<exclude>${project.build.finalName}.jar</exclude>
<exclude>*.sh</exclude>
<exclude>${generatedSources.path}${version.file.path}</exclude>
</excludes>
</fileset>
</filesets>
<followSymlinks>false</followSymlinks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${generatedSources.folder}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Buildnumber plugin extracting the git buildnumber and build-timestamp,
needs SCM to be set -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<!-- <phase>validate</phase> -->
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Generates the Version.java file and replacing the buildnumber with
the current git buildnumber extracted by the buildnumber-maven-plugin -->
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${version.template.file}</file>
<outputFile>${version.file}</outputFile>
<replacements>
<replacement>
<token>@buildnumber@</token>
<value>${buildNumber}</value>
</replacement>
<replacement>
<token>@buildtime@</token>
<value>${timestamp}</value>
</replacement>
</replacements>
</configuration>
</plugin>
</plugins>
<!-- Tells the eclipse maven addon to include the replace goal in its lifecycle -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>create</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>false</runOnIncremental>
</execute>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>replace</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>false</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<scm>
<connection>scm:git:git://gitext.gfz-potsdam.de:geomultisens/gms-modules.git</connection>
</scm>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>[1.7.12,)</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>[1.7.12,)</version>
</dependency>
<dependency>
<groupId>de.potsdam.gfz</groupId>
<artifactId>gms-database</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>de.potsdam.gfz</groupId>
<artifactId>gms-utils-core</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>de.potsdam.gfz</groupId>
<artifactId>gms-module-interfaces</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
</project>
#!/bin/bash
MODULE="index-mediator-server"
RUN_PATH="."
RUN_CMD="java -Xmx12G -jar $RUN_PATH/gms-index-mediator-0.0.1.jar"
RUN_USER="gms"
RUN_SHELL="/bin/bash"
RUN_PID="$RUN_PATH/$MODULE.pid"
# usage function
function usage {
echo "Usage : $MODULE start|stop|restart|status"
}
# status function
function status {
if [ -f $RUN_PID ]
then
PID=$(cat $RUN_PID 2>/dev/null)
echo "$MODULE is running with pid $PID"
else
echo "$MODULE is not running"
fi
}
# start function
function start {
if [ -f $RUN_PID ]
then
echo "$MODULE is already running."
else
su -s $RUN_SHELL -c "
exec $RUN_CMD > /dev/null &
disown \$!
echo \$! > '$RUN_PID'" $RUN_USER
fi
}
# stop function
function stop {
if [ -f $RUN_PID ]
then
PID=$(cat $RUN_PID 2>/dev/null)
kill "$PID" 2>/dev/null
echo "$MODULE stopped"
else
echo "$MODULE not running"
fi
rm -f $RUN_PID
}
if [ $# -lt 1 ]
then
usage
exit
fi
case $1 in
start)
# start
start
# print status
status
;;
status)
status
exit
;;
stop)
stop
exit
;;
restart)
# stop any runniing process
stop
# give the process time to die
sleep 1
# start a new one
start
;;
*)
usage
exit
;;
esac
/*******************************************************************************
* Copyright (C) 2018 Daniel Eggert (daniel.eggert@gfz-potsdam.de)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
/**
*
*/
package de.potsdam.gfz.gms.indexmediator;
import static de.potsdam.gfz.gms.indexmediator.SpatialIndexMediatorServer.LOG;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.vividsolutions.jts.geom.Envelope;
import de.potsdam.gfz.gms.database.indexes.SceneIndex;
import de.potsdam.gfz.gms.database.indexes.SceneIndex.SceneData;
import de.potsdam.gfz.gms.database.indexmediator.MediatorConstants;
import de.potsdam.gfz.gms.database.shared.Timestamp;
/**
* @author Daniel Eggert (daniel.eggert@gfz-potsdam.de)
*
*/
public class Connection implements Runnable {
private static final byte SIZE_OF_BYTE = 1;
private static final byte SIZE_OF_SHORT = 2;
private static final byte SIZE_OF_INT = 4;
@SuppressWarnings("unused")
private static final byte SIZE_OF_FLOAT = 4;
private static final byte SIZE_OF_LONG = 8;
private static final byte SIZE_OF_DOUBLE = 8;
private final Socket socket;
private final ExecutorService queryWorker;
private final SceneIndex index;
private final long queryTimeoutMillis;
private Future<?> latestQueryFuture = null;
public Connection(Socket socket, SceneIndex index, long queryTimeoutMillis) {
this.socket = socket;
this.queryWorker = Executors.newSingleThreadExecutor();
this.index = index;
this.queryTimeoutMillis = queryTimeoutMillis;
}
@Override
public void run() {
String remoteHost = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
LOG.debug("Starting communication with " + remoteHost);
try (DataInputStream in = new DataInputStream(socket.getInputStream()); DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
while (!socket.isClosed()) {
try {
// receive msg
LOG.trace("reading message header...");
byte msg = in.readByte();
switch (msg) {
case MediatorConstants.HELLO_MSG:
handleHello(out);
break;
case MediatorConstants.COUNT_QUERY_MSG:
handleCountQuery(in, out);
break;
case MediatorConstants.FULL_SCENE_QUERY_MSG:
handleFullSceneQuery(in, out);
break;
case MediatorConstants.SCENE_META_QUERY_MSG:
handleMetaSceneQuery(in, out);
break;
case MediatorConstants.SCENE_BOUNDS_QUERY_MSG:
handleSceneBoundsQuery(in, out);
break;
case MediatorConstants.DISCONNECT_MSG:
// disconnect received - kill the connection
try {
socket.close();
} catch (Throwable t) {
// ignore anything regarding close operations
}
// LOG.info("disconnect received");
return;
case MediatorConstants.GET_VERSION_MSG:
handleVersionQuery(in, out);
break;
}
} catch (Throwable t) {
if (t instanceof IOException) {
// disconnect
break;
} else {
LOG.error("Unexpected error: ", t);
Thread.sleep(1000l);
}
}
}
} catch (Throwable e) {
LOG.error("unexpected disconnect from " + remoteHost + ", reason: " + e.getMessage());
}
if (!socket.isClosed()) {
try {
socket.close();
} catch (Throwable e1) {
}
}
// LOG.info("connection died.");
if (latestQueryFuture != null) {
latestQueryFuture.cancel(true);
}
queryWorker.shutdownNow();
LOG.debug("terminating communication with " + remoteHost);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
@Override
protected void finalize() throws Throwable {
queryWorker.shutdownNow();
}
/**
* @param in
* @param out
* @throws IOException
*/
public void handleCountQuery(DataInputStream in, DataOutputStream out) throws IOException {
// get query data
// first the envelope data
Envelope e = new Envelope(in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble());
// second the timestamps
long start = in.readLong();
long end = in.readLong();
int seasoncode = in.readInt();
byte maxCloudCover = in.readByte();
byte minProclevel = in.readByte();
byte dayNight = in.readByte();
Map<Short, Integer> count = index.countScenesGroupedByDatasets(e, new Timestamp(start), new Timestamp(end), seasoncode, maxCloudCover, minProclevel, dayNight);
// compile answer
out.writeByte(MediatorConstants.COUNT_QUERY_MSG);
out.writeShort((short) count.size());
for (Entry<Short, Integer> entry : count.entrySet()) {
out.writeShort(entry.getKey());
out.writeInt(entry.getValue());
}
out.flush();
}
private static final List<Integer> TIMEOUT_LIST = Collections.unmodifiableList(Arrays.asList(new Integer(0)));
private Future<List<Integer>> placeScenesForDatasetQuery(final Envelope e, final Timestamp start, final Timestamp end, final int seasoncode, final byte minCloudcover,
final byte maxCloudcover, final short datasetid, final byte minProclevel, final byte maxProclevel, final byte dayNight) throws Exception {
Callable<List<Integer>> query = new Callable<List<Integer>>() {
@Override
public List<Integer> call() throws Exception {
return index.getScenesForDataset(e, start, end, seasoncode, minCloudcover, maxCloudcover, datasetid, minProclevel, maxProclevel, dayNight);
}
};
return queryWorker.submit(query);