package org.simantics.district.maps.server;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import org.yaml.snakeyaml.Yaml;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.StartedProcess;
-import org.zeroturnaround.exec.stream.slf4j.Slf4jStream;
+import org.zeroturnaround.exec.stream.slf4j.Slf4jDebugOutputStream;
import org.zeroturnaround.process.PidProcess;
import org.zeroturnaround.process.PidUtil;
import org.zeroturnaround.process.Processes;
public class TileserverMapnik {
private static final Logger LOGGER = LoggerFactory.getLogger(TileserverMapnik.class);
- private static final String[] ADDITIONAL_DEPENDENCIES = new String[] { "tilelive-vector@3.9.4", "tilelive-tmstyle@0.6.0" };
private SystemProcess process;
private Path serverRoot;
return running.get();
}
- public void start() throws Exception {
+ public void start(Optional<TileserverStartListener> listener) throws Exception {
// check if existing server is left hanging
if (Files.exists(getPid())) {
String pid = new String(Files.readAllBytes(getPid()));
}
// check that npm dependencies are satisfied
- if (checkAndInstall(null)) {
- checkAndInstall(ADDITIONAL_DEPENDENCIES[0]);
- checkAndInstall(ADDITIONAL_DEPENDENCIES[1]);
- }
+// if (checkAndInstall(null, listener)) {
+// checkAndInstall(ADDITIONAL_DEPENDENCIES[0], listener);
+// checkAndInstall(ADDITIONAL_DEPENDENCIES[1], listener);
+// }
checkConfigJson();
checkTm2Styles();
if (process != null && process.isAlive())
return;
- StartedProcess startedProcess = new ProcessExecutor().directory(serverRoot.resolve("tileserver-mapnik").toFile()).destroyOnExit().environment(getEnv())
- .command(NodeJS.executable().toString(), getTessera().toString(), "-c", getConfigJson().toString(), "-p", Integer.toString(MapsServerPreferences.defaultPort()))
- .redirectOutput(Slf4jStream.ofCaller().asDebug()).start();
+ Path tileliveTesseraWin = serverRoot.resolve("dist").resolve("node.exe").normalize().toAbsolutePath();
+ StartedProcess startedProcess = new ProcessExecutor().directory(serverRoot.resolve("dist").toFile()).destroyOnExit().environment(getEnv())
+ .command(tileliveTesseraWin.toString(), "-c", getConfigJson().toString(), "-p", Integer.toString(MapsServerPreferences.defaultPort()))
+ .redirectOutput(new Slf4jDebugOutputStream(LOGGER) {
+
+ @Override
+ protected void processLine(String line) {
+ // Convert to UTF-8 string
+ String utf8Line = new String(line.getBytes(), StandardCharsets.UTF_8);
+ log.debug(utf8Line);
+ }
+ }).start();
Process nativeProcess = startedProcess.getProcess();
process = Processes.newStandardProcess(nativeProcess);
int pid = PidUtil.getPid(nativeProcess);
+ LOGGER.info("Writing pid-file to {} with pid={}", getPid(), pid);
Files.write(getPid(), (pid + "").getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
running.set(true);
+ listener.ifPresent(TileserverStartListener::started);
}
private Map<String, String> getEnv() {
return serverRoot.resolve("pid");
}
- public void restart() throws Exception {
+ public void restart(Optional<TileserverStartListener> listener) throws Exception {
stop();
- start();
+ start(listener);
}
- private boolean checkIfInstalled(String module) throws Exception {
- String tileserverMapnik = tileserverMapnikRoot().toString();
- int retVal;
- try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
- if (module == null) {
- retVal = NodeJS.npm(output, "--prefix", tileserverMapnik, "list");
- } else {
- retVal = NodeJS.npm(output, "--prefix", tileserverMapnik, "list", module);
- }
- String outputString = new String(output.toByteArray(), StandardCharsets.UTF_8);
- }
- return retVal == 0;
- }
-
- private boolean install(String module) throws Exception {
- String tileserverMapnik = tileserverMapnikRoot().toString();
- int retVal;
- if (module == null)
- retVal = NodeJS.npm(null, "--prefix", tileserverMapnik, "install", "--save");
- else
- retVal = NodeJS.npm(null, "--prefix", tileserverMapnik, "install", module, "--save");
- if (retVal != 0)
- LOGGER.warn("Could not install module " + module == null ? "package.json" : module + "! " + retVal);
- return retVal == 0;
- }
-
- private boolean checkAndInstall(String module) throws Exception {
- boolean installed = checkIfInstalled(module);
- if (!installed)
- install(module);
- return !installed;
- }
+// private boolean checkIfInstalled(String module) throws Exception {
+// String tileserverMapnik = tileserverMapnikRoot().toString();
+// int retVal;
+// try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+// if (module == null) {
+// retVal = NodeJS.npm(output, "--prefix", tileserverMapnik, "list");
+// } else {
+// retVal = NodeJS.npm(output, "--prefix", tileserverMapnik, "list", module);
+// }
+// String outputString = new String(output.toByteArray(), StandardCharsets.UTF_8);
+// }
+// return retVal == 0;
+// }
+//
+// private int install(String module, Optional<TileserverStartListener> listener) throws Exception {
+// String tileserverMapnik = tileserverMapnikRoot().toString();
+// int retVal;
+// if (module == null) {
+// listener.ifPresent(l -> l.installing("Installing tileserver-mapnik"));
+// retVal = NodeJS.npm(null, "--prefix", tileserverMapnik, "install", "--save");
+// } else {
+// retVal = NodeJS.npm(null, "--prefix", tileserverMapnik, "install", module, "--save");
+// }
+// if (retVal != 0)
+// LOGGER.warn("Could not install module " + module == null ? "package.json" : module + "! " + retVal);
+// return retVal;
+// }
+//
+// private boolean checkAndInstall(String module, Optional<TileserverStartListener> listener) throws Exception {
+// LOGGER.info("Installing module {}", String.valueOf(module));
+// boolean installed = checkIfInstalled(module);
+// if (!installed) {
+// int installSuccessfull = install(module, listener);
+// if (installSuccessfull != 0) {
+// LOGGER.warn("Installation of module {} failed!", String.valueOf(module));
+// listener.ifPresent(l -> l.installationFailed(module, installSuccessfull));
+// }
+// } else {
+// LOGGER.info("Module {} was already installed", String.valueOf(module));
+// }
+// return !installed;
+// }
- private Path tileserverMapnikRoot() {
+ @SuppressWarnings("unused")
+ private Path tileserverMapnikRoot() {
return serverRoot.resolve("tileserver-mapnik").toAbsolutePath();
}
}
private Path getICU() {
- return serverRoot.resolve("tileserver-mapnik/node_modules/tilelive-vector/node_modules/mapnik/lib/binding/node-v46-win32-x64/share/icu").toAbsolutePath();
+ return serverRoot.resolve("dist/share/icu").toAbsolutePath();
}
- private Path getTessera() {
+ @SuppressWarnings("unused")
+ private Path getTessera() {
return serverRoot.resolve("tileserver-mapnik/bin/tessera.js").toAbsolutePath();
}
return getDataDirectory().resolve(MapsServerPreferences.currentMBTiles());
}
+ @SuppressWarnings("unchecked")
public void checkTm2Styles() {
Path tm2 = getStyleDirectory();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tm2)) {
return results;
}
+ public static interface TileserverStartListener {
+
+ void installing(String module);
+
+ void installationFailed(String module, int returnValue);
+
+ void started();
+ }
}