From c858d06cf0c095a309a8c364002c46aedea07a36 Mon Sep 17 00:00:00 2001
From: Nikolaus Krismer <niko@krismer.de>
Date: Tue, 11 Feb 2014 10:32:53 +0100
Subject: [PATCH] moved code into startupServlet renamed SocketConfiguration to
 ConfigurationContainer (since now it is not more than a container)

---
 .../it/unibz/inf/isochrone/util/Config.java   | 144 +++++---
 .../inf/isoga/service/AbstractService.java    |  99 +++++-
 .../isoga/service/ServiceConfiguration.java   |   6 +-
 .../inf/isoga/service/ServiceIsochrone.java   |   2 +-
 .../inf/isoga/servlet/StartupServlet.java     |  74 +++-
 .../websocket/ConfigurationContainer.java     | 159 +++++++++
 .../inf/isoga/websocket/JsonWebsocket.java    |   6 +-
 .../isoga/websocket/SocketConfiguration.java  | 324 ------------------
 8 files changed, 426 insertions(+), 388 deletions(-)
 create mode 100644 src/main/java/it/unibz/inf/isoga/websocket/ConfigurationContainer.java
 delete mode 100644 src/main/java/it/unibz/inf/isoga/websocket/SocketConfiguration.java

diff --git a/src/main/java/it/unibz/inf/isochrone/util/Config.java b/src/main/java/it/unibz/inf/isochrone/util/Config.java
index 2b4bfc43..8bb18f11 100644
--- a/src/main/java/it/unibz/inf/isochrone/util/Config.java
+++ b/src/main/java/it/unibz/inf/isochrone/util/Config.java
@@ -1,10 +1,15 @@
 package it.unibz.inf.isochrone.util;
 
+import it.geosolutions.geoserver.rest.GeoServerRESTManager;
+import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
+import it.geosolutions.geoserver.rest.GeoServerRESTReader;
 import it.unibz.inf.isochrone.db.ConnectionFactory;
 import it.unibz.inf.isochrone.util.EnumContainer.Dataset;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.InvalidPropertiesFormatException;
@@ -29,8 +34,10 @@ import java.util.Properties;
  * @version 2.2
  */
 public class Config {
-	protected Properties internalProperties;
-	protected final ConnectionFactory factory;
+	private final ConnectionFactory factory;
+	private final GeoServerRESTManager manager;
+	private Properties internalProperties;
+
 	protected short densityLimit = Short.MIN_VALUE;
 
 	// Constructors
@@ -39,10 +46,16 @@ public class Config {
 		this("config.xml");
 	}
 
-	public Config(final String fileName) {
-		appendPropertiesFromFile(fileName);
+	public Config(final Config config) {
+		if (config == null) {
+			throw new NullPointerException("Invalid config in clone constructor given!");
+		}
 
-		factory = initConnectionFactory();
+		internalProperties = new Properties();
+		appendProperties(config.internalProperties);
+
+		factory = config.factory;
+		manager = config.manager;
 	}
 
 	public Config(final Dataset dataset) {
@@ -50,21 +63,22 @@ public class Config {
 		appendPropertiesFromFile("config_" + dataset.toString().toLowerCase() + ".xml");
 
 		factory = initConnectionFactory();
+		manager = initManager();
 	}
 
-	public Config(final Config config) {
-		if (config == null) {
-			throw new NullPointerException("Invalid config in clone constructor given!");
-		}
-
-		internalProperties = new Properties();
-		appendProperties(config.internalProperties);
+	public Config(final String fileName) {
+		appendPropertiesFromFile(fileName);
 
-		factory = config.factory;
+		factory = initConnectionFactory();
+		manager = initManager();
 	}
 
 	// Public methods
 
+	public int getClientSRID() {
+		return Integer.parseInt(getProperty("cfg.clientSRID"));
+	}
+
 	public Connection getConnection() {
 		try {
 			return factory.getConnection();
@@ -75,74 +89,86 @@ public class Config {
 		return null;
 	}
 
-	/**
-	 * Returns the value of the entry specified by the passed <code>key</code>.
-	 *
-	 * @param key the key that identifies the entry
-	 * @return the value of the entry
-	 */
-	public String getProperty(final String key) {
-		if (internalProperties.getProperty(key) == null) {
-			return null;
-		}
+	public String getDaymarkerTable() {
+		return getProperty("tbl.dateCodes");
+	}
 
-		return internalProperties.getProperty(key).trim();
+	public String getDBName() {
+		return getProperty("org.postgresql.database");
+	}
+
+	public String getDBPassword() {
+		return getProperty("org.postgresql.password");
 	}
 
 	public boolean getDBPooling() {
 		return Boolean.parseBoolean(getProperty("db.pooling"));
 	}
 
-	public String getDBServerName() {
-		return getProperty("org.postgresql.servername");
+	public int getDBPort() {
+		return Integer.parseInt(getProperty("org.postgresql.port"));
 	}
 
-	public String getDBName() {
-		return getProperty("org.postgresql.database");
+	public String getDBServerName() {
+		return getProperty("org.postgresql.servername");
 	}
 
 	public String getDBUser() {
 		return getProperty("org.postgresql.username");
 	}
 
-	public String getDBPassword() {
-		return getProperty("org.postgresql.password");
+	public String getEdgeTable() {
+		return getProperty("tbl.links");
 	}
 
-	public int getDBPort() {
-		return Integer.parseInt(getProperty("org.postgresql.port"));
+	public GeoServerRESTPublisher getGeoServerPublisher() {
+		return manager.getPublisher();
 	}
 
-	public String getEdgeTable() {
-		return getProperty("tbl.links");
+	public GeoServerRESTReader getGeoServerReader() {
+		return manager.getReader();
 	}
 
-	public String getVertexTable() {
-		return getProperty("tbl.nodes");
-	}
+	/**
+	 * Returns the value of the entry specified by the passed <code>key</code>.
+	 *
+	 * @param key the key that identifies the entry
+	 * @return the value of the entry
+	 */
+	public String getProperty(final String key) {
+		if (internalProperties.getProperty(key) == null) {
+			return null;
+		}
 
-	public String getScheduleTable() {
-		return getProperty("tbl.times");
+		return internalProperties.getProperty(key).trim();
 	}
 
 	public String getRouteTable() {
 		return getProperty("tbl.routes");
 	}
 
-	public String getDaymarkerTable() {
-		return getProperty("tbl.dateCodes");
-	}
-
-	public int getClientSRID() {
-		return Integer.parseInt(getProperty("cfg.clientSRID"));
+	public String getScheduleTable() {
+		return getProperty("tbl.times");
 	}
 
 	public int getServerSRID() {
 		return Integer.parseInt(getProperty("sql.spatial.srid"));
 	}
 
+	public String getVertexTable() {
+		return getProperty("tbl.nodes");
+	}
+
 	// Protected methods
 
+	/**
+	 * This merges properties to the configuration.
+	 * Old values will be kept, but overwritten by new values (if the same property has been specified)
+	 */
+	protected void appendProperties(final Properties properties) {
+		internalProperties.putAll(properties);
+	}
+
 	/**
 	 * This appends properties from the given file to the configuration.
 	 * Old values will be kept, but overwritten by new values (if the same property has been specified)
@@ -173,14 +199,6 @@ public class Config {
 		}
 	}
 
-	/**
-	 * This merges properties to the configuration.
-	 * Old values will be kept, but overwritten by new values (if the same property has been specified)
-	 */
-	protected void appendProperties(final Properties properties) {
-		internalProperties.putAll(properties);
-	}
-
 	// Private methods
 
 	private ConnectionFactory initConnectionFactory() {
@@ -204,4 +222,24 @@ public class Config {
 		return f;
 	}
 
+	private GeoServerRESTManager initManager() {
+		GeoServerRESTManager m = null;
+		try {
+			final String restUrlStr = getProperty("rendering.server.rest.url");
+			final String username = getProperty("rendering.server.rest.username");
+			final String password = getProperty("rendering.server.rest.password");
+
+			final URL restURL = (restUrlStr == null) ? null : new URL(restUrlStr);
+			m = (restURL == null) ? null : new GeoServerRESTManager(restURL, username, password);
+		} catch (final MalformedURLException e) {
+			e.printStackTrace();
+		}
+
+		if (m == null) {
+			throw new RuntimeException("Manager is not defined... please check your configuration!");
+		}
+
+		return m;
+	}
+
 }
diff --git a/src/main/java/it/unibz/inf/isoga/service/AbstractService.java b/src/main/java/it/unibz/inf/isoga/service/AbstractService.java
index 80490244..0119a879 100644
--- a/src/main/java/it/unibz/inf/isoga/service/AbstractService.java
+++ b/src/main/java/it/unibz/inf/isoga/service/AbstractService.java
@@ -1,18 +1,31 @@
 package it.unibz.inf.isoga.service;
 
-import it.unibz.inf.isoga.websocket.SocketConfiguration;
+import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
+import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
+import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
+import it.unibz.inf.isochrone.util.Config;
+import it.unibz.inf.isoga.db.DbUtility;
+import it.unibz.inf.isoga.db.TableEntry;
+import it.unibz.inf.isoga.geometry.BBox;
+import it.unibz.inf.isoga.util.DSetConfig;
+import it.unibz.inf.isoga.websocket.ConfigurationContainer;
 
+import java.sql.Connection;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * @author Nikolaus Krismer
  */
 public abstract class AbstractService implements IService {
-	protected final SocketConfiguration socketConfig;
+	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractService.class.getName());
+	protected final ConfigurationContainer socketConfig;
 
 	public AbstractService() {
-		socketConfig = SocketConfiguration.getInstance();
+		socketConfig = ConfigurationContainer.getInstance();
 	}
 
 	// Getter methods
@@ -25,4 +38,84 @@ public abstract class AbstractService implements IService {
 		return reqParamList;
 	}
 
+	// Protected methods
+
+	/**
+	 * Creates the database tables and new layers for every session.
+	 */
+	protected void registerLayers(final Connection connection, final DSetConfig dSetConfig) {
+		final Config globalConfig = ConfigurationContainer.getGlobalConfig();
+		final GeoServerRESTPublisher publisher = globalConfig.getGeoServerPublisher();
+		final String ds = globalConfig.getProperty("rendering.server.rest.datastore");
+		final String ws = globalConfig.getProperty("rendering.server.rest.workspace");
+		final BBox serverExtend = dSetConfig.getServerExtent();
+		final int serverSrid = dSetConfig.getServerSRID();
+		final String srs = "EPSG:" + serverSrid;
+
+		// register edge layer
+		final TableEntry edgeTableEntry = dSetConfig.getEdgeTableEntry();
+		DbUtility.deleteGeometryMetadata(connection, edgeTableEntry);
+		DbUtility.createTargetEdgeTable(connection, edgeTableEntry.getTableName());
+		DbUtility.insertGeometryMetadata(connection, edgeTableEntry, serverSrid);
+		DbUtility.createSpatialIndex(connection, edgeTableEntry);
+		final GSFeatureTypeEncoder edgeFeatureTypeEncoder = getFeatureEncoder(edgeTableEntry, serverExtend, srs);
+		final GSLayerEncoder edgeLayerEncoder = new GSLayerEncoder();
+		edgeLayerEncoder.setDefaultStyle("STYLE_ISO_EDGES");
+		if (!publisher.publishDBLayer(ws, ds, edgeFeatureTypeEncoder, edgeLayerEncoder)) {
+			LOGGER.debug("Could not register edge layer \"" + edgeFeatureTypeEncoder.getName() + "\"");
+			throw new RuntimeException("Couldn't register edge layer on the GeoServer");
+		}
+		LOGGER.debug("Successfully registered edge layer \"" + edgeFeatureTypeEncoder.getName() + "\"");
+
+		// register vertex table
+		final TableEntry vertexTableEntry = dSetConfig.getVertexTableEntry();
+		final TableEntry annotatedTableEntry = dSetConfig.getVertexAnnotatedTableEntry();
+		DbUtility.createVertexAnnotationTable(connection, annotatedTableEntry.getTableName());
+		DbUtility.deleteGeometryMetadata(connection, vertexTableEntry);
+		DbUtility.createTargetVertexTable(connection, vertexTableEntry.getTableName());
+		DbUtility.insertGeometryMetadata(connection, vertexTableEntry, serverSrid);
+		DbUtility.createSpatialIndex(connection, vertexTableEntry);
+		final GSFeatureTypeEncoder vertexFeatureTypeEncoder = getFeatureEncoder(vertexTableEntry, serverExtend, srs);
+		final GSLayerEncoder vertexLayerEncoder = new GSLayerEncoder();
+		vertexLayerEncoder.setDefaultStyle("STYLE_VERTICES_EXPIRATION");
+		if (!publisher.publishDBLayer(ws, ds, vertexFeatureTypeEncoder, vertexLayerEncoder)) {
+			LOGGER.debug("Could not register vertex layer \"" + vertexFeatureTypeEncoder.getName() + "\"");
+			throw new RuntimeException("Couldn't register vertex layer on the GeoServer");
+		}
+		LOGGER.debug("Successfully registered vertex layer \"" + vertexFeatureTypeEncoder.getName() + "\"");
+
+		final TableEntry areaBufferTableEntry = dSetConfig.getAreaBufferTableEntry();
+		DbUtility.deleteGeometryMetadata(connection, areaBufferTableEntry);
+		DbUtility.createTargetBufferTable(connection, areaBufferTableEntry.getTableName());
+		DbUtility.insertGeometryMetadata(connection, areaBufferTableEntry, serverSrid);
+		DbUtility.createSpatialIndex(connection, areaBufferTableEntry);
+		final GSFeatureTypeEncoder bufferFeatureTypeEncoder = getFeatureEncoder(areaBufferTableEntry, serverExtend, srs);
+		final GSLayerEncoder bufferLayerEncoder = new GSLayerEncoder();
+		bufferLayerEncoder.setDefaultStyle("STYLE_ISO_AREA");
+		if (!publisher.publishDBLayer(ws, ds, bufferFeatureTypeEncoder, bufferLayerEncoder)) {
+			LOGGER.warn("Could not register feature layer \"" + bufferFeatureTypeEncoder.getName() + "\"");
+			throw new RuntimeException("Couldn't register areaBuffer layer on the GeoServer");
+		}
+		LOGGER.debug("Successfully registered feature layer \"" + bufferFeatureTypeEncoder.getName() + "\"");
+
+		dSetConfig.register();
+	}
+
+	// Private methods
+
+	private GSFeatureTypeEncoder getFeatureEncoder(final TableEntry tEntry, final BBox serverExtend, final String srs) {
+		final double xMax = serverExtend.getMaxX();
+		final double yMax = serverExtend.getMaxY();
+		final double xMin = serverExtend.getMinX();
+		final double yMin = serverExtend.getMinY();
+
+		final GSFeatureTypeEncoder bufferFeatureTypeEncoder = new GSFeatureTypeEncoder();
+		bufferFeatureTypeEncoder.setName(tEntry.getTableName());
+		bufferFeatureTypeEncoder.setTitle(tEntry.getDescription());
+		bufferFeatureTypeEncoder.setSRS(srs);
+		bufferFeatureTypeEncoder.setNativeBoundingBox(xMin, yMin, xMax, yMax, srs);
+
+		return bufferFeatureTypeEncoder;
+	}
+
 }
diff --git a/src/main/java/it/unibz/inf/isoga/service/ServiceConfiguration.java b/src/main/java/it/unibz/inf/isoga/service/ServiceConfiguration.java
index ecadfeb0..786a2d9a 100644
--- a/src/main/java/it/unibz/inf/isoga/service/ServiceConfiguration.java
+++ b/src/main/java/it/unibz/inf/isoga/service/ServiceConfiguration.java
@@ -5,7 +5,7 @@ import it.unibz.inf.isochrone.util.Config;
 import it.unibz.inf.isochrone.util.EnumContainer.Dataset;
 import it.unibz.inf.isoga.util.DSetConfig;
 import it.unibz.inf.isoga.util.IsogaConfig;
-import it.unibz.inf.isoga.websocket.SocketConfiguration;
+import it.unibz.inf.isoga.websocket.ConfigurationContainer;
 
 import java.sql.Connection;
 
@@ -31,7 +31,7 @@ public class ServiceConfiguration extends AbstractService {
 	@Override
 	public JSONObject onJsonMessage(final Session session, final JSONObject jsonObject) {
 		final String clientId = session.getId();
-		final Config globalConfig = SocketConfiguration.getGlobalConfig();
+		final Config globalConfig = ConfigurationContainer.getGlobalConfig();
 		socketConfig.setClientConfig(clientId, new IsogaConfig(globalConfig));
 
 		final JSONArray allClientDatasets = new JSONArray();
@@ -58,7 +58,7 @@ public class ServiceConfiguration extends AbstractService {
 
 		for (Dataset dataset : PREREGISTERING_DATASETS) {
 			final DSetConfig clientDSetConfig = socketConfig.getClientDatasetConfig(clientId, dataset);
-			socketConfig.registerLayers(connection, clientDSetConfig);
+			registerLayers(connection, clientDSetConfig);
 		}
 	}
 
diff --git a/src/main/java/it/unibz/inf/isoga/service/ServiceIsochrone.java b/src/main/java/it/unibz/inf/isoga/service/ServiceIsochrone.java
index e284c1a4..62ab654b 100644
--- a/src/main/java/it/unibz/inf/isoga/service/ServiceIsochrone.java
+++ b/src/main/java/it/unibz/inf/isoga/service/ServiceIsochrone.java
@@ -101,7 +101,7 @@ public class ServiceIsochrone extends AbstractService {
 
 		// register layers which have not been preregistered in ServiceConfiguration class
 		if (!dSetConfig.isRegistered()) {
-			socketConfig.registerLayers(config.getConnection(), dSetConfig);
+			registerLayers(config.getConnection(), dSetConfig);
 		}
 
 		try {
diff --git a/src/main/java/it/unibz/inf/isoga/servlet/StartupServlet.java b/src/main/java/it/unibz/inf/isoga/servlet/StartupServlet.java
index eee8aea0..6b5b8e76 100644
--- a/src/main/java/it/unibz/inf/isoga/servlet/StartupServlet.java
+++ b/src/main/java/it/unibz/inf/isoga/servlet/StartupServlet.java
@@ -1,10 +1,29 @@
 package it.unibz.inf.isoga.servlet;
 
+import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
+import it.geosolutions.geoserver.rest.GeoServerRESTReader;
+import it.geosolutions.geoserver.rest.decoder.RESTLayerList;
+import it.unibz.inf.isochrone.util.Config;
+import it.unibz.inf.isoga.db.DbUtility;
+import it.unibz.inf.isoga.websocket.JsonWebsocket;
+import it.unibz.inf.isoga.websocket.ConfigurationContainer;
+
+import java.sql.Connection;
+import java.util.List;
+
 import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @WebServlet(loadOnStartup = 1)
-public class StartupServlet {
+public class StartupServlet extends HttpServlet {
+	private static final long serialVersionUID = 7599924678364708340L;
+	private static final Logger LOGGER = LoggerFactory.getLogger(JsonWebsocket.class.getName());
+	private static final int SLEEP_TIME = 1000;
 
+	@Override
 	public void init() {
 		// TODO: Implement startup checks
 
@@ -14,6 +33,59 @@ public class StartupServlet {
 		// 4) Is the geoserver reachable?
 		// 5) Can we connect to the geoserver with given username/password?
 		// 6) Does the geoserver contain the specified workspace, datasource, ...
+
+		initCleanupThread();
+	}
+
+	private void initCleanupThread() {
+		final Thread t = new Thread() {
+			@Override
+			public void run() {
+				final Config config = ConfigurationContainer.getGlobalConfig();
+				final GeoServerRESTReader reader = config.getGeoServerReader();
+				while (!reader.existGeoserver()) {
+					try {
+						sleep(SLEEP_TIME);
+					} catch (final InterruptedException e1) {
+						e1.printStackTrace();
+					}
+				}
+
+				removeLayers(config);
+				dropTables(config);
+			}
+
+			private void dropTables(final Config config) {
+				final String[] regexpTables = new String[] {"%_iso_edg_%", "%_iso_nod_%", "%_iso_nan_%", "%_iso_are_%"};
+				final Connection connection = config.getConnection();
+
+				LOGGER.info("Dropping tables");
+				for (String regexp : regexpTables) {
+					DbUtility.dropTablesByRegexp(connection, regexp);
+					LOGGER.debug(" - table \"" + regexp + "\" dropped");
+				}
+			}
+
+			private void removeLayers(final Config config) {
+				final GeoServerRESTPublisher publisher = config.getGeoServerPublisher();
+				final GeoServerRESTReader reader = config.getGeoServerReader();
+
+				final RESTLayerList layers = reader.getLayers();
+				if (layers != null) {
+					final String ws = ConfigurationContainer.getGlobalConfig().getProperty("rendering.server.rest.workspace");
+					LOGGER.info("Removing layers");
+
+					final List<String> layerNames = layers.getNames();
+					for (final String layerName : layerNames) {
+						publisher.removeLayer(ws, layerName);
+						LOGGER.debug(" - layer \"" + layerName + "\" removed");
+					}
+				}
+
+				publisher.reload();
+			}
+		};
+		t.start();
 	}
 
 }
diff --git a/src/main/java/it/unibz/inf/isoga/websocket/ConfigurationContainer.java b/src/main/java/it/unibz/inf/isoga/websocket/ConfigurationContainer.java
new file mode 100644
index 00000000..4e252a0f
--- /dev/null
+++ b/src/main/java/it/unibz/inf/isoga/websocket/ConfigurationContainer.java
@@ -0,0 +1,159 @@
+package it.unibz.inf.isoga.websocket;
+
+import it.unibz.inf.isochrone.util.Config;
+import it.unibz.inf.isochrone.util.EnumContainer.Dataset;
+import it.unibz.inf.isochrone.util.Point;
+import it.unibz.inf.isoga.db.IsogaDatabase;
+import it.unibz.inf.isoga.geometry.BBox;
+import it.unibz.inf.isoga.util.DSetConfig;
+import it.unibz.inf.isoga.util.IsogaConfig;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ConfigurationContainer {
+	private static final Logger LOGGER = LoggerFactory.getLogger(JsonWebsocket.class.getName());
+	private static final String FORMAT_DATE = "MM'/'dd'/'yyyy' 'HH':'mm";
+	private static final int INITAL_DSET_SIZE = 5;
+
+	private static ConfigurationContainer instance = null;
+
+	private static final Config GLOBAL_CONFIG;
+	private final Map<String, IsogaConfig> clientConfigMap;
+	private final Map<String, Map<Dataset, DSetConfig>> clientDatasets;
+	private final Collection<DSetConfig> datasetConfigs;
+
+	static {
+		GLOBAL_CONFIG = new Config();
+	}
+
+	private ConfigurationContainer() {
+		clientConfigMap = new HashMap<String, IsogaConfig>();
+		clientDatasets = new HashMap<String, Map<Dataset, DSetConfig>>();
+		datasetConfigs = new ArrayList<DSetConfig>(INITAL_DSET_SIZE);
+
+		initDatasetConfigurations();
+	}
+
+	public static ConfigurationContainer getInstance() {
+		if (instance == null) {
+			instance = new ConfigurationContainer();
+		}
+
+		return instance;
+	}
+
+	// Getter methods
+
+	public static Config getGlobalConfig() {
+		return GLOBAL_CONFIG;
+	}
+
+	public IsogaConfig getClientConfig(final String clientId) {
+		if (!clientConfigMap.containsKey(clientId)) {
+			return null;
+		}
+
+		return clientConfigMap.get(clientId);
+	}
+
+	public DSetConfig getClientDatasetConfig(final String clientId, final Dataset dataset) {
+		if (!clientDatasets.containsKey(clientId)) {
+			return null;
+		}
+
+		return clientDatasets.get(clientId).get(dataset);
+	}
+
+	public Collection<DSetConfig> getClientDatasetConfigList(final String clientId) {
+		if (!clientDatasets.containsKey(clientId)) {
+			return Collections.emptyList();
+		}
+
+		return clientDatasets.get(clientId).values();
+	}
+
+	public Collection<DSetConfig> getDatasetConfigurations() {
+		return datasetConfigs;
+	}
+
+	public void setClientConfig(final String clientId, final IsogaConfig config) {
+		clientConfigMap.put(clientId, config);
+	}
+
+	public void setClientDSetConfig(final String clientId, final DSetConfig datasetConfig) {
+		if (!clientDatasets.containsKey(clientId)) {
+			clientDatasets.put(clientId, new HashMap<Dataset, DSetConfig>());
+		}
+
+		clientDatasets.get(clientId).put(datasetConfig.getDataset(), datasetConfig);
+	}
+
+	// Private methods
+
+	private void initDatasetConfigurations() {
+		LOGGER.info("Initializing dataset configuration files");
+
+		final String dataSetStr = GLOBAL_CONFIG.getProperty("cfg.datasets");
+		final String[] dataSets = (dataSetStr == null) ? new String[0] : dataSetStr.split(",");
+		for (final String dSet : dataSets) {
+			final Dataset dataSet = Dataset.valueOf(dSet.toUpperCase());
+			if (dataSet == null) {
+				LOGGER.warn("Invalid dataset \"" + dSet + "\" specified. It is not configured in the server enum!");
+				continue;
+			}
+
+			final IsogaConfig config = new IsogaConfig("config_" + dataSet.toString().toLowerCase() + ".xml");
+			final String areaBufferTable = config.getProperty("tbl.isoAreaBuffer");
+			final String arrivalTime = config.getProperty("client.tArrival");
+			final String[] poiProperty = config.getProperty("client.poi").split(",");
+			final String ws = config.getProperty("rendering.server.rest.workspace");
+			final double lower2 = Double.parseDouble(config.getProperty("sql.spatial.dim2.lower"));
+			final double lower1 = Double.parseDouble(config.getProperty("sql.spatial.dim1.lower"));
+			final double upper1 = Double.parseDouble(config.getProperty("sql.spatial.dim1.upper"));
+			final double upper2 = Double.parseDouble(config.getProperty("sql.spatial.dim2.upper"));
+
+			final Point lowerCorner = new Point(lower1, lower2);
+			final Point upperCorner = new Point(upper1, upper2);
+			final BBox serverBBox = new BBox(lowerCorner, upperCorner);
+
+			final Calendar targetTime = Calendar.getInstance();
+			try {
+				DateFormat dateFormatter = new SimpleDateFormat(FORMAT_DATE);
+				targetTime.setTimeInMillis(dateFormatter.parse(arrivalTime).getTime());
+			} catch (final ParseException e) {
+				e.printStackTrace();
+			}
+
+			final IsogaDatabase db = new IsogaDatabase(config);
+			final BBox clientBBox = new BBox(db.transform(lowerCorner), db.transform(upperCorner));
+			final Point queryPoint = db.transform(new Point(Double.valueOf(poiProperty[0]), Double.valueOf(poiProperty[1])));
+
+			final DSetConfig dSetConfig = new DSetConfig.Builder(dataSet)
+				.serverMBR(serverBBox)
+				.clientMBR(clientBBox)
+				.time(targetTime)
+				.queryPoint(queryPoint)
+				.serverSRID(config.getServerSRID())
+				.workspace(ws)
+				.edgeLayer(config.getDestinationEdgeTableEntry().getTableName())
+				.vertexLayer(config.getDestinationVertexTableEntry().getTableName())
+				.vertexAnnotatedTableName(config.getDestinationVertexAnnotatedTableEntry().getTableName())
+				.areaBufferLayer(areaBufferTable)
+				.build();
+
+			datasetConfigs.add(dSetConfig);
+		}
+	}
+
+}
diff --git a/src/main/java/it/unibz/inf/isoga/websocket/JsonWebsocket.java b/src/main/java/it/unibz/inf/isoga/websocket/JsonWebsocket.java
index ac7a209e..853f701d 100644
--- a/src/main/java/it/unibz/inf/isoga/websocket/JsonWebsocket.java
+++ b/src/main/java/it/unibz/inf/isoga/websocket/JsonWebsocket.java
@@ -86,12 +86,12 @@ public class JsonWebsocket {
 	@OnClose
 	public void onClose(final Session session, final CloseReason closeReason) {
 		final String clientId = session.getId();
-		final Config globalConfig = SocketConfiguration.getGlobalConfig();
+		final Config globalConfig = ConfigurationContainer.getGlobalConfig();
 		final Connection connection = globalConfig.getConnection();
 		final String ws = globalConfig.getProperty("rendering.server.rest.workspace");
+		final GeoServerRESTPublisher publisher = globalConfig.getGeoServerPublisher();
 
-		final SocketConfiguration socketConf = SocketConfiguration.getInstance();
-		final GeoServerRESTPublisher publisher = socketConf.getGeoServerPublisher();
+		final ConfigurationContainer socketConf = ConfigurationContainer.getInstance();
 		final Collection<DSetConfig> allClientDatasetConfigs = socketConf.getClientDatasetConfigList(clientId);
 		for (final DSetConfig clientDSetConfig : allClientDatasetConfigs) {
 			if (clientDSetConfig.isRegistered()) {
diff --git a/src/main/java/it/unibz/inf/isoga/websocket/SocketConfiguration.java b/src/main/java/it/unibz/inf/isoga/websocket/SocketConfiguration.java
deleted file mode 100644
index d3000aa3..00000000
--- a/src/main/java/it/unibz/inf/isoga/websocket/SocketConfiguration.java
+++ /dev/null
@@ -1,324 +0,0 @@
-package it.unibz.inf.isoga.websocket;
-
-import it.geosolutions.geoserver.rest.GeoServerRESTManager;
-import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
-import it.geosolutions.geoserver.rest.GeoServerRESTReader;
-import it.geosolutions.geoserver.rest.decoder.RESTLayerList;
-import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
-import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
-import it.unibz.inf.isochrone.util.Config;
-import it.unibz.inf.isochrone.util.EnumContainer.Dataset;
-import it.unibz.inf.isochrone.util.Point;
-import it.unibz.inf.isoga.db.DbUtility;
-import it.unibz.inf.isoga.db.IsogaDatabase;
-import it.unibz.inf.isoga.db.TableEntry;
-import it.unibz.inf.isoga.geometry.BBox;
-import it.unibz.inf.isoga.util.DSetConfig;
-import it.unibz.inf.isoga.util.IsogaConfig;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.sql.Connection;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class SocketConfiguration {
-	private static final Logger LOGGER = LoggerFactory.getLogger(JsonWebsocket.class.getName());
-	private static final String FORMAT_DATE = "MM'/'dd'/'yyyy' 'HH':'mm";
-	private static final int SLEEP_TIME = 1000;
-	private static final int INITAL_DSET_SIZE = 5;
-
-	private static SocketConfiguration instance = null;
-
-	private static final Config GLOBAL_CONFIG;
-	private final Map<String, IsogaConfig> clientConfigMap;
-	private final Map<String, Map<Dataset, DSetConfig>> clientDatasets;
-	private final Collection<DSetConfig> datasetConfigs;
-
-	private GeoServerRESTManager manager;
-
-	static {
-		GLOBAL_CONFIG = new Config();
-	}
-
-	private SocketConfiguration() {
-		clientConfigMap = new HashMap<String, IsogaConfig>();
-		clientDatasets = new HashMap<String, Map<Dataset, DSetConfig>>();
-		datasetConfigs = new ArrayList<DSetConfig>(INITAL_DSET_SIZE);
-
-		initManager();
-		initDatasetConfigurations();
-		initCleanupThread();
-	}
-
-	public static SocketConfiguration getInstance() {
-		if (instance == null) {
-			instance = new SocketConfiguration();
-		}
-
-		return instance;
-	}
-
-	// Getter methods
-
-	public static Config getGlobalConfig() {
-		return GLOBAL_CONFIG;
-	}
-
-	public IsogaConfig getClientConfig(final String clientId) {
-		if (!clientConfigMap.containsKey(clientId)) {
-			return null;
-		}
-
-		return clientConfigMap.get(clientId);
-	}
-
-	public DSetConfig getClientDatasetConfig(final String clientId, final Dataset dataset) {
-		if (!clientDatasets.containsKey(clientId)) {
-			return null;
-		}
-
-		return clientDatasets.get(clientId).get(dataset);
-	}
-
-	public Collection<DSetConfig> getClientDatasetConfigList(final String clientId) {
-		if (!clientDatasets.containsKey(clientId)) {
-			return Collections.emptyList();
-		}
-
-		return clientDatasets.get(clientId).values();
-	}
-
-	public Collection<DSetConfig> getDatasetConfigurations() {
-		return datasetConfigs;
-	}
-
-	public void setClientConfig(final String clientId, final IsogaConfig config) {
-		clientConfigMap.put(clientId, config);
-	}
-
-	public void setClientDSetConfig(final String clientId, final DSetConfig datasetConfig) {
-		if (!clientDatasets.containsKey(clientId)) {
-			clientDatasets.put(clientId, new HashMap<Dataset, DSetConfig>());
-		}
-
-		clientDatasets.get(clientId).put(datasetConfig.getDataset(), datasetConfig);
-	}
-
-	public GeoServerRESTPublisher getGeoServerPublisher() {
-		return manager.getPublisher();
-	}
-
-	public GeoServerRESTReader getGeoServerReader() {
-		return manager.getReader();
-	}
-
-	/**
-	 * Creates the database tables and new layers for every session.
-	 */
-	public void registerLayers(final Connection connection, final DSetConfig dSetConfig) {
-		final Config globalConfig = getGlobalConfig();
-		final GeoServerRESTPublisher publisher = getGeoServerPublisher();
-		final String ds = globalConfig.getProperty("rendering.server.rest.datastore");
-		final String ws = globalConfig.getProperty("rendering.server.rest.workspace");
-		final BBox serverExtend = dSetConfig.getServerExtent();
-		final int serverSrid = dSetConfig.getServerSRID();
-		final String srs = "EPSG:" + serverSrid;
-
-		// register edge layer
-		final TableEntry edgeTableEntry = dSetConfig.getEdgeTableEntry();
-		DbUtility.deleteGeometryMetadata(connection, edgeTableEntry);
-		DbUtility.createTargetEdgeTable(connection, edgeTableEntry.getTableName());
-		DbUtility.insertGeometryMetadata(connection, edgeTableEntry, serverSrid);
-		DbUtility.createSpatialIndex(connection, edgeTableEntry);
-		final GSFeatureTypeEncoder edgeFeatureTypeEncoder = getFeatureEncoder(edgeTableEntry, serverExtend, srs);
-		final GSLayerEncoder edgeLayerEncoder = new GSLayerEncoder();
-		edgeLayerEncoder.setDefaultStyle("STYLE_ISO_EDGES");
-		if (!publisher.publishDBLayer(ws, ds, edgeFeatureTypeEncoder, edgeLayerEncoder)) {
-			LOGGER.debug("Could not register edge layer \"" + edgeFeatureTypeEncoder.getName() + "\"");
-			throw new RuntimeException("Couldn't register edge layer on the GeoServer");
-		}
-		LOGGER.debug("Successfully registered edge layer \"" + edgeFeatureTypeEncoder.getName() + "\"");
-
-		// register vertex table
-		final TableEntry vertexTableEntry = dSetConfig.getVertexTableEntry();
-		final TableEntry annotatedTableEntry = dSetConfig.getVertexAnnotatedTableEntry();
-		DbUtility.createVertexAnnotationTable(connection, annotatedTableEntry.getTableName());
-		DbUtility.deleteGeometryMetadata(connection, vertexTableEntry);
-		DbUtility.createTargetVertexTable(connection, vertexTableEntry.getTableName());
-		DbUtility.insertGeometryMetadata(connection, vertexTableEntry, serverSrid);
-		DbUtility.createSpatialIndex(connection, vertexTableEntry);
-		final GSFeatureTypeEncoder vertexFeatureTypeEncoder = getFeatureEncoder(vertexTableEntry, serverExtend, srs);
-		final GSLayerEncoder vertexLayerEncoder = new GSLayerEncoder();
-		vertexLayerEncoder.setDefaultStyle("STYLE_VERTICES_EXPIRATION");
-		if (!publisher.publishDBLayer(ws, ds, vertexFeatureTypeEncoder, vertexLayerEncoder)) {
-			LOGGER.debug("Could not register vertex layer \"" + vertexFeatureTypeEncoder.getName() + "\"");
-			throw new RuntimeException("Couldn't register vertex layer on the GeoServer");
-		}
-		LOGGER.debug("Successfully registered vertex layer \"" + vertexFeatureTypeEncoder.getName() + "\"");
-
-		final TableEntry areaBufferTableEntry = dSetConfig.getAreaBufferTableEntry();
-		DbUtility.deleteGeometryMetadata(connection, areaBufferTableEntry);
-		DbUtility.createTargetBufferTable(connection, areaBufferTableEntry.getTableName());
-		DbUtility.insertGeometryMetadata(connection, areaBufferTableEntry, serverSrid);
-		DbUtility.createSpatialIndex(connection, areaBufferTableEntry);
-		final GSFeatureTypeEncoder bufferFeatureTypeEncoder = getFeatureEncoder(areaBufferTableEntry, serverExtend, srs);
-		final GSLayerEncoder bufferLayerEncoder = new GSLayerEncoder();
-		bufferLayerEncoder.setDefaultStyle("STYLE_ISO_AREA");
-		if (!publisher.publishDBLayer(ws, ds, bufferFeatureTypeEncoder, bufferLayerEncoder)) {
-			LOGGER.warn("Could not register feature layer \"" + bufferFeatureTypeEncoder.getName() + "\"");
-			throw new RuntimeException("Couldn't register areaBuffer layer on the GeoServer");
-		}
-		LOGGER.debug("Successfully registered feature layer \"" + bufferFeatureTypeEncoder.getName() + "\"");
-
-		dSetConfig.register();
-	}
-
-	// Private methods
-
-	private GSFeatureTypeEncoder getFeatureEncoder(final TableEntry tEntry, final BBox serverExtend, final String srs) {
-		final double xMax = serverExtend.getMaxX();
-		final double yMax = serverExtend.getMaxY();
-		final double xMin = serverExtend.getMinX();
-		final double yMin = serverExtend.getMinY();
-
-		final GSFeatureTypeEncoder bufferFeatureTypeEncoder = new GSFeatureTypeEncoder();
-		bufferFeatureTypeEncoder.setName(tEntry.getTableName());
-		bufferFeatureTypeEncoder.setTitle(tEntry.getDescription());
-		bufferFeatureTypeEncoder.setSRS(srs);
-		bufferFeatureTypeEncoder.setNativeBoundingBox(xMin, yMin, xMax, yMax, srs);
-
-		return bufferFeatureTypeEncoder;
-	}
-
-	private void initCleanupThread() {
-		final Thread t = new Thread() {
-			@Override
-			public void run() {
-				final GeoServerRESTReader reader = getGeoServerReader();
-				while (!reader.existGeoserver()) {
-					try {
-						sleep(SLEEP_TIME);
-					} catch (final InterruptedException e1) {
-						e1.printStackTrace();
-					}
-				}
-
-				removeLayers();
-				dropTables();
-			}
-
-			private void dropTables() {
-				final String[] regexpTables = new String[] {"%_iso_edg_%", "%_iso_nod_%", "%_iso_nan_%", "%_iso_are_%"};
-				final Connection connection = GLOBAL_CONFIG.getConnection();
-
-				LOGGER.info("Dropping tables");
-				for (String regexp : regexpTables) {
-					DbUtility.dropTablesByRegexp(connection, regexp);
-					LOGGER.debug(" - table \"" + regexp + "\" dropped");
-				}
-			}
-
-			private void removeLayers() {
-				final GeoServerRESTPublisher publisher = getGeoServerPublisher();
-				final GeoServerRESTReader reader = getGeoServerReader();
-
-				final RESTLayerList layers = reader.getLayers();
-				if (layers != null) {
-					final String ws = GLOBAL_CONFIG.getProperty("rendering.server.rest.workspace");
-					LOGGER.info("Removing layers");
-
-					final List<String> layerNames = layers.getNames();
-					for (final String layerName : layerNames) {
-						publisher.removeLayer(ws, layerName);
-						LOGGER.debug(" - layer \"" + layerName + "\" removed");
-					}
-				}
-
-				publisher.reload();
-			}
-		};
-		t.start();
-	}
-
-	private void initDatasetConfigurations() {
-		final String dataSetStr = GLOBAL_CONFIG.getProperty("cfg.datasets");
-		final String[] dataSets = (dataSetStr == null) ? new String[0] : dataSetStr.split(",");
-		for (final String dSet : dataSets) {
-			final Dataset dataSet = Dataset.valueOf(dSet.toUpperCase());
-			if (dataSet == null) {
-				continue;
-			}
-
-			final IsogaConfig config = new IsogaConfig("config_" + dataSet.toString().toLowerCase() + ".xml");
-			final String areaBufferTable = config.getProperty("tbl.isoAreaBuffer");
-			final String arrivalTime = config.getProperty("client.tArrival");
-			final String[] poiProperty = config.getProperty("client.poi").split(",");
-			final String ws = config.getProperty("rendering.server.rest.workspace");
-			final double lower2 = Double.parseDouble(config.getProperty("sql.spatial.dim2.lower"));
-			final double lower1 = Double.parseDouble(config.getProperty("sql.spatial.dim1.lower"));
-			final double upper1 = Double.parseDouble(config.getProperty("sql.spatial.dim1.upper"));
-			final double upper2 = Double.parseDouble(config.getProperty("sql.spatial.dim2.upper"));
-
-			final Point lowerCorner = new Point(lower1, lower2);
-			final Point upperCorner = new Point(upper1, upper2);
-			final BBox serverBBox = new BBox(lowerCorner, upperCorner);
-
-			final Calendar targetTime = Calendar.getInstance();
-			try {
-				DateFormat dateFormatter = new SimpleDateFormat(FORMAT_DATE);
-				targetTime.setTimeInMillis(dateFormatter.parse(arrivalTime).getTime());
-			} catch (final ParseException e) {
-				e.printStackTrace();
-			}
-
-			final IsogaDatabase db = new IsogaDatabase(config);
-			final BBox clientBBox = new BBox(db.transform(lowerCorner), db.transform(upperCorner));
-			final Point queryPoint = db.transform(new Point(Double.valueOf(poiProperty[0]), Double.valueOf(poiProperty[1])));
-
-			final DSetConfig dSetConfig = new DSetConfig.Builder(dataSet)
-				.serverMBR(serverBBox)
-				.clientMBR(clientBBox)
-				.time(targetTime)
-				.queryPoint(queryPoint)
-				.serverSRID(config.getServerSRID())
-				.workspace(ws)
-				.edgeLayer(config.getDestinationEdgeTableEntry().getTableName())
-				.vertexLayer(config.getDestinationVertexTableEntry().getTableName())
-				.vertexAnnotatedTableName(config.getDestinationVertexAnnotatedTableEntry().getTableName())
-				.areaBufferLayer(areaBufferTable)
-				.build();
-
-			datasetConfigs.add(dSetConfig);
-		}
-	}
-
-	private void initManager() {
-		try {
-			final String restUrlStr = GLOBAL_CONFIG.getProperty("rendering.server.rest.url");
-			final String username = GLOBAL_CONFIG.getProperty("rendering.server.rest.username");
-			final String password = GLOBAL_CONFIG.getProperty("rendering.server.rest.password");
-
-			final URL restURL = (restUrlStr == null) ? null : new URL(restUrlStr);
-			manager = (restURL == null) ? null : new GeoServerRESTManager(restURL, username, password);
-		} catch (final MalformedURLException e) {
-			e.printStackTrace();
-		}
-
-		if (manager == null) {
-			throw new RuntimeException("Manager is not defined... please check your configuration!");
-		}
-	}
-
-}
-- 
GitLab