/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb; import java.io.File; import java.net.URL; import org.voltcore.common.Constants; import org.voltcore.utils.InstanceId; import org.voltdb.probe.MeshProber; import org.voltdb.utils.MiscUtils; /** * Wraps VoltDB in a Thread */ public class ServerThread extends Thread { VoltDB.Configuration m_config; public ServerThread(VoltDB.Configuration config) { m_config = config; if (m_config.m_pathToLicense == null) { m_config.m_pathToLicense = getTestLicensePath(); } if (m_config.m_leader == null) { m_config.m_leader = ""; } if (m_config.m_coordinators == null || m_config.m_coordinators.isEmpty()) { m_config.m_coordinators = MeshProber.hosts(m_config.m_internalPort); } if (m_config.m_startAction != StartAction.PROBE) { m_config.m_hostCount = VoltDB.UNDEFINED; } if (!m_config.validate()) { System.exit(-1); } // Disable loading the EE if running against HSQL. m_config.m_noLoadLibVOLTDB = m_config.m_backend == BackendTarget.HSQLDB_BACKEND; m_config.m_forceVoltdbCreate = true; if (config.m_startAction == StartAction.INITIALIZE || config.m_startAction == StartAction.GET) { VoltDB.ignoreCrash = true; } setName("ServerThread"); } public ServerThread(String pathToCatalog, BackendTarget target) { m_config = new VoltDB.Configuration(); m_config.m_pathToCatalog = pathToCatalog; m_config.m_backend = target; if (m_config.m_pathToLicense == null) { m_config.m_pathToLicense = getTestLicensePath(); } m_config.m_leader = ""; m_config.m_coordinators = MeshProber.hosts(m_config.m_internalPort); VoltDB.instance().setMode(OperationMode.INITIALIZING); // Disable loading the EE if running against HSQL. m_config.m_noLoadLibVOLTDB = m_config.m_backend == BackendTarget.HSQLDB_BACKEND; m_config.m_forceVoltdbCreate = true; setName("ServerThread"); } public ServerThread(String pathToCatalog, String pathToDeployment, BackendTarget target) { m_config = new VoltDB.Configuration(); m_config.m_pathToCatalog = pathToCatalog; m_config.m_pathToDeployment = pathToDeployment; m_config.m_backend = target; if (m_config.m_pathToLicense == null) { m_config.m_pathToLicense = getTestLicensePath(); } m_config.m_leader = ""; m_config.m_coordinators = MeshProber.hosts(m_config.m_internalPort); VoltDB.instance().setMode(OperationMode.INITIALIZING); // Disable loading the EE if running against HSQL. m_config.m_noLoadLibVOLTDB = m_config.m_backend == BackendTarget.HSQLDB_BACKEND; m_config.m_forceVoltdbCreate = true; if (!m_config.validate()) { System.exit(-1); } setName("ServerThread"); } public ServerThread(String pathToCatalog, String pathToDeployment, int internalPort, int zkPort, BackendTarget target) { this(pathToCatalog, pathToDeployment, Constants.DEFAULT_INTERNAL_PORT, internalPort, zkPort, target); } private ServerThread(String pathToCatalog, String pathToDeployment, int leaderPort, int internalPort, int zkPort, BackendTarget target) { m_config = new VoltDB.Configuration(); m_config.m_pathToCatalog = pathToCatalog; m_config.m_pathToDeployment = pathToDeployment; m_config.m_backend = target; if (m_config.m_pathToLicense == null) { m_config.m_pathToLicense = getTestLicensePath(); } m_config.m_leader = MiscUtils.getHostnameColonPortString("localhost", leaderPort); m_config.m_coordinators = MeshProber.hosts(internalPort); m_config.m_internalPort = internalPort; m_config.m_zkInterface = "127.0.0.1:" + zkPort; VoltDB.instance().setMode(OperationMode.INITIALIZING); // Disable loading the EE if running against HSQL. m_config.m_noLoadLibVOLTDB = m_config.m_backend == BackendTarget.HSQLDB_BACKEND; m_config.m_forceVoltdbCreate = true; if (!m_config.validate()) { System.exit(-1); } setName("ServerThread"); } @Override public void run() { VoltDB.initialize(m_config); VoltDB.instance().run(); } //Call this if you are doing init only or action GET public void initialize() { VoltDB.initialize(m_config); } //Call this if you are doing init only or action GET public void cli() { VoltDB.cli(m_config); } public void waitForInitialization() { // Wait until the server has actually started running. while (!VoltDB.instance().isRunning() || VoltDB.instance().getMode() == OperationMode.INITIALIZING) { Thread.yield(); } } public void waitForRejoin() { while (!VoltDB.instance().isRunning() || VoltDB.instance().getMode() == OperationMode.INITIALIZING || VoltDB.instance().rejoining()) { Thread.yield(); } } public void waitForClientInterface() { while (!VoltDB.instance().isRunning() || VoltDB.instance().getClientInterface() == null || !VoltDB.instance().getClientInterface().isAcceptingConnections()) { Thread.yield(); } } public void shutdown() throws InterruptedException { assert Thread.currentThread() != this; VoltDB.instance().shutdown(this); this.join(); while (VoltDB.instance().isRunning()) { Thread.sleep(1); } } /** * For tests only, mostly with ServerThread or LocalCluster: * * Provide a valid license in the case where license checking * is enabled. * * Outside tests, the license file probably won't exist. */ public static String getTestLicensePath() { // magic license stored in the voltdb enterprise code URL resource = ServerThread.class.getResource("valid_dr_active_subscription.xml"); // in the community edition, any non-empty string // should work fine here, as it won't be checked if (resource == null) return "[community]"; // return the filesystem path File licxml = new File(resource.getFile()); return licxml.getPath(); } public InstanceId getInstanceId() { return VoltDB.instance().getHostMessenger().getInstanceId(); } }