Moved external http server to a daemon
This commit is contained in:
parent
ee89eeb39d
commit
870be06255
3 changed files with 102 additions and 61 deletions
|
|
@ -1,17 +1,13 @@
|
||||||
package se.hal;
|
package se.hal;
|
||||||
|
|
||||||
|
|
||||||
|
import se.hal.daemon.HalExternalWebDaemon;
|
||||||
import se.hal.intf.*;
|
import se.hal.intf.*;
|
||||||
import se.hal.page.HalAlertManager;
|
import se.hal.page.HalAlertManager;
|
||||||
import se.hal.struct.PluginConfig;
|
import se.hal.struct.PluginConfig;
|
||||||
import se.hal.util.HalAcmeDataStore;
|
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
import zutil.net.acme.AcmeChallengeFactory;
|
|
||||||
import zutil.net.acme.AcmeClient;
|
|
||||||
import zutil.net.acme.AcmeHttpChallengeFactory;
|
|
||||||
import zutil.net.acme.AcmeManualDnsChallengeFactory;
|
|
||||||
import zutil.net.http.HttpPage;
|
import zutil.net.http.HttpPage;
|
||||||
import zutil.net.http.HttpServer;
|
import zutil.net.http.HttpServer;
|
||||||
import zutil.net.http.page.HttpFilePage;
|
import zutil.net.http.page.HttpFilePage;
|
||||||
|
|
@ -19,9 +15,6 @@ import zutil.net.http.page.HttpRedirectPage;
|
||||||
import zutil.plugin.PluginData;
|
import zutil.plugin.PluginData;
|
||||||
import zutil.plugin.PluginManager;
|
import zutil.plugin.PluginManager;
|
||||||
|
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
@ -31,8 +24,6 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN;
|
|
||||||
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_PORT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for Hal
|
* Main class for Hal
|
||||||
|
|
@ -46,12 +37,10 @@ public class HalServer {
|
||||||
private static List<HalDaemon> daemons = new ArrayList<>();
|
private static List<HalDaemon> daemons = new ArrayList<>();
|
||||||
|
|
||||||
private static HttpServer http;
|
private static HttpServer http;
|
||||||
private static HttpServer httpExternal;
|
private static HalExternalWebDaemon httpExternal;
|
||||||
|
|
||||||
private static PluginManager pluginManager;
|
private static PluginManager pluginManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
try {
|
try {
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
@ -78,54 +67,6 @@ public class HalServer {
|
||||||
|
|
||||||
logger.info("Working directory: " + FileUtil.find(".").getAbsolutePath());
|
logger.info("Working directory: " + FileUtil.find(".").getAbsolutePath());
|
||||||
|
|
||||||
// ------------------------------------
|
|
||||||
// Initialize External HttpServer
|
|
||||||
// ------------------------------------
|
|
||||||
|
|
||||||
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN) && HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT)) {
|
|
||||||
String externalServerUrl = "https://" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN) +
|
|
||||||
":" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_PORT);
|
|
||||||
|
|
||||||
HalAcmeDataStore acmeDataStore = new HalAcmeDataStore();
|
|
||||||
X509Certificate certificate = acmeDataStore.getCertificate();
|
|
||||||
|
|
||||||
if (!AcmeClient.isCertificateValid(certificate)) {
|
|
||||||
// Prepare ACME Client
|
|
||||||
AcmeClient acme;
|
|
||||||
HttpServer tmpHttpServer = null;
|
|
||||||
|
|
||||||
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
|
|
||||||
acme = new AcmeClient(acmeDataStore, new AcmeManualDnsChallengeFactory());
|
|
||||||
} else if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
|
|
||||||
tmpHttpServer = new HttpServer(80);
|
|
||||||
tmpHttpServer.start();
|
|
||||||
|
|
||||||
acme = new AcmeClient(acmeDataStore, new AcmeHttpChallengeFactory(tmpHttpServer));
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown config value for " + externalServerUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request certificate and start the external webserver
|
|
||||||
|
|
||||||
acme.addDomain(HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
|
|
||||||
acme.prepareRequest();
|
|
||||||
certificate = acme.requestCertificate();
|
|
||||||
acmeDataStore.storeCertificate(certificate);
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
if (tmpHttpServer != null) {
|
|
||||||
tmpHttpServer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT), acmeDataStore.getDomainKeyPair().getPrivate(), certificate);
|
|
||||||
httpExternal.start();
|
|
||||||
|
|
||||||
logger.info("External https server up and running at: " + externalServerUrl);
|
|
||||||
} else {
|
|
||||||
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Initialize Plugins
|
// Initialize Plugins
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
@ -166,6 +107,9 @@ public class HalServer {
|
||||||
for (Iterator<HalDaemon> it = pluginManager.getSingletonIterator(HalDaemon.class); it.hasNext(); ) {
|
for (Iterator<HalDaemon> it = pluginManager.getSingletonIterator(HalDaemon.class); it.hasNext(); ) {
|
||||||
HalDaemon daemon = it.next();
|
HalDaemon daemon = it.next();
|
||||||
registerDaemon(daemon);
|
registerDaemon(daemon);
|
||||||
|
|
||||||
|
if (daemon instanceof HalExternalWebDaemon) // Keep a reference of the external web server
|
||||||
|
httpExternal = (HalExternalWebDaemon) daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
|
||||||
96
hal-core/src/se/hal/daemon/HalExternalWebDaemon.java
Normal file
96
hal-core/src/se/hal/daemon/HalExternalWebDaemon.java
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
package se.hal.daemon;
|
||||||
|
|
||||||
|
import org.shredzone.acme4j.exception.AcmeException;
|
||||||
|
import se.hal.HalContext;
|
||||||
|
import se.hal.intf.HalDaemon;
|
||||||
|
import se.hal.util.HalAcmeDataStore;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.acme.AcmeClient;
|
||||||
|
import zutil.net.acme.AcmeHttpChallengeFactory;
|
||||||
|
import zutil.net.acme.AcmeManualDnsChallengeFactory;
|
||||||
|
import zutil.net.http.HttpPage;
|
||||||
|
import zutil.net.http.HttpServer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN;
|
||||||
|
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_PORT;
|
||||||
|
|
||||||
|
|
||||||
|
public class HalExternalWebDaemon implements HalDaemon {
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
private HttpServer httpExternal;
|
||||||
|
private String externalServerUrl;
|
||||||
|
private HalAcmeDataStore acmeDataStore = new HalAcmeDataStore();
|
||||||
|
private X509Certificate certificate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiate(ScheduledExecutorService executor) {
|
||||||
|
// ------------------------------------
|
||||||
|
// Initialize External HttpServer
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN) && HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT)) {
|
||||||
|
externalServerUrl = "https://" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN) + ":" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_PORT);
|
||||||
|
certificate = acmeDataStore.getCertificate();
|
||||||
|
|
||||||
|
renewCertificate();
|
||||||
|
startHttpServer();
|
||||||
|
} else {
|
||||||
|
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.severe("Was unable to initiate external web server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renewCertificate() throws AcmeException, IOException {
|
||||||
|
if (!AcmeClient.isCertificateValid(certificate)) {
|
||||||
|
// Prepare ACME Client
|
||||||
|
AcmeClient acme;
|
||||||
|
HttpServer tmpHttpServer = null;
|
||||||
|
|
||||||
|
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
|
||||||
|
acme = new AcmeClient(acmeDataStore, new AcmeManualDnsChallengeFactory());
|
||||||
|
} else if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
|
||||||
|
tmpHttpServer = new HttpServer(80);
|
||||||
|
tmpHttpServer.start();
|
||||||
|
|
||||||
|
acme = new AcmeClient(acmeDataStore, new AcmeHttpChallengeFactory(tmpHttpServer));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unknown config value for " + externalServerUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request certificate and start the external webserver
|
||||||
|
|
||||||
|
acme.addDomain(HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
|
||||||
|
acme.prepareRequest();
|
||||||
|
certificate = acme.requestCertificate();
|
||||||
|
acmeDataStore.storeCertificate(certificate);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
if (tmpHttpServer != null) {
|
||||||
|
tmpHttpServer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startHttpServer() throws GeneralSecurityException, IOException {
|
||||||
|
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT), acmeDataStore.getDomainKeyPair().getPrivate(), certificate);
|
||||||
|
httpExternal.start();
|
||||||
|
|
||||||
|
logger.info("External https server up and running at: " + externalServerUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPage(String url, HttpPage page) {
|
||||||
|
if (httpExternal != null)
|
||||||
|
httpExternal.setPage(url, page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
{"se.hal.intf.HalAbstractControllerManager": "se.hal.EventControllerManager"},
|
{"se.hal.intf.HalAbstractControllerManager": "se.hal.EventControllerManager"},
|
||||||
{"se.hal.intf.HalAbstractControllerManager": "se.hal.SensorControllerManager"},
|
{"se.hal.intf.HalAbstractControllerManager": "se.hal.SensorControllerManager"},
|
||||||
|
|
||||||
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.HalExternalWebDaemon"},
|
||||||
{"se.hal.intf.HalDaemon": "se.hal.daemon.HalMulticastDnsDaemon"},
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.HalMulticastDnsDaemon"},
|
||||||
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataAggregatorDaemon"},
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataAggregatorDaemon"},
|
||||||
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataCleanupDaemon"},
|
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataCleanupDaemon"},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue