package cc.blynk.server.launcher; import cc.blynk.server.Holder; import cc.blynk.server.api.http.HttpAPIServer; import cc.blynk.server.api.http.HttpsAPIServer; import cc.blynk.server.application.AppServer; import cc.blynk.server.core.BaseServer; import cc.blynk.server.core.model.AppName; import cc.blynk.server.hardware.HardwareSSLServer; import cc.blynk.server.hardware.HardwareServer; import cc.blynk.server.hardware.MQTTHardwareServer; import cc.blynk.utils.JarUtil; import cc.blynk.utils.LoggerUtil; import cc.blynk.utils.SHA256Util; import cc.blynk.utils.ServerProperties; import cc.blynk.utils.properties.GCMProperties; import cc.blynk.utils.properties.MailProperties; import cc.blynk.utils.properties.SmsProperties; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.io.File; import java.net.BindException; import java.security.Security; import java.util.Map; /** * Entry point for server launch. * * By default starts 7 servers on different ports: * * 1 server socket for SSL/TLS Hardware (8441 default) * 1 server socket for plain tcp/ip Hardware (8442 default) * 1 server socket for SSL/TLS Applications (8443 default) * 1 server socket for HTTP API (8080 default) * 1 server socket for HTTPS API (9443 default) * 1 server socket for MQTT (8440 default) * 1 server socket for Administration UI (7443 default) * * In addition launcher start all related to business logic threads like saving user profiles thread, timers * processing thread, properties reload thread and shutdown hook tread. * * The Blynk Project. * Created by Dmitriy Dumanskiy. * Created on 2/16/2015. */ public class ServerLauncher { //required for QR generation static { System.setProperty("java.awt.headless", "true"); } public static void main(String[] args) throws Exception { Map<String, String> cmdProperties = ArgumentsParser.parse(args); ServerProperties serverProperties = new ServerProperties(cmdProperties); LoggerUtil.configureLogging(serverProperties); //required for logging dynamic context System.setProperty("data.folder", serverProperties.getProperty("data.folder")); //required to avoid dependencies within model to server.properties System.setProperty("terminal.strings.pool.size", serverProperties.getProperty("terminal.strings.pool.size", "25")); System.setProperty("initial.energy", serverProperties.getProperty("initial.energy", "2000")); boolean isUnpacked = JarUtil.unpackStaticFiles("static/"); ServerProperties mailProperties = new MailProperties(cmdProperties); ServerProperties smsProperties = new SmsProperties(cmdProperties); ServerProperties gcmProperties = new GCMProperties(cmdProperties); Security.addProvider(new BouncyCastleProvider()); boolean restore = Boolean.parseBoolean(cmdProperties.get(ArgumentsParser.RESTORE_OPTION)); start(serverProperties, mailProperties, smsProperties, gcmProperties, isUnpacked, restore); } private static void start(ServerProperties serverProperties, ServerProperties mailProperties, ServerProperties smsProperties, ServerProperties gcmProperties, boolean isUnpacked, boolean restore) { final Holder holder = new Holder(serverProperties, mailProperties, smsProperties, gcmProperties, restore); final BaseServer[] servers = new BaseServer[] { new HardwareServer(holder), new HardwareSSLServer(holder), new AppServer(holder), new HttpAPIServer(holder), new HttpsAPIServer(holder, isUnpacked), new MQTTHardwareServer(holder) }; if (startServers(servers)) { //Launching all background jobs. JobLauncher.start(holder, servers); System.out.println(); System.out.println("Blynk Server " + JarUtil.getServerVersion() + " successfully started."); String path = new File(System.getProperty("logs.folder")).getAbsolutePath().replace("/./", "/"); System.out.println("All server output is stored in folder '" + path + "' file."); holder.sslContextHolder.generateInitialCertificates(holder.props); createSuperUser(holder); } } private static void createSuperUser(Holder holder) { String email = holder.props.getProperty("admin.email", "admin@blynk.cc"); String pass = holder.props.getProperty("admin.pass", "admin"); if (!holder.userDao.isSuperAdminExists()) { System.out.println("Your Admin login email is " + email); System.out.println("Your Admin password is " + pass); String hash = SHA256Util.makeHash(pass, email); holder.userDao.add(email, hash, AppName.BLYNK, true); } } private static boolean startServers(BaseServer[] servers) { //start servers try { for (BaseServer server : servers) { server.start(); } return true; } catch (BindException bindException) { System.out.println("Server ports are busy. Most probably server already launched. See " + new File(System.getProperty("logs.folder")).getAbsolutePath() + " for more info."); } catch (Exception e) { System.out.println("Error starting Blynk server. Stopping."); } return false; } }