package com.intrbiz.bergamot.ui; import java.util.UUID; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Level; import org.apache.log4j.Logger; import com.intrbiz.accounting.AccountingManager; import com.intrbiz.balsa.BalsaApplication; import com.intrbiz.balsa.engine.impl.session.HazelcastSessionEngine; import com.intrbiz.balsa.util.Util; import com.intrbiz.bergamot.accounting.BergamotAccountingQueueConsumer; import com.intrbiz.bergamot.accounting.consumer.BergamotLoggingConsumer; import com.intrbiz.bergamot.cluster.ClusterManager; import com.intrbiz.bergamot.config.UICfg; import com.intrbiz.bergamot.data.BergamotDB; import com.intrbiz.bergamot.health.HealthAgent; import com.intrbiz.bergamot.health.HealthTracker; import com.intrbiz.bergamot.model.Site; import com.intrbiz.bergamot.ui.action.BergamotAgentActions; import com.intrbiz.bergamot.ui.action.CheckActions; import com.intrbiz.bergamot.ui.action.ConfigChangeActions; import com.intrbiz.bergamot.ui.action.ContactActions; import com.intrbiz.bergamot.ui.action.DispatchResultAction; import com.intrbiz.bergamot.ui.action.ExecuteCheckAction; import com.intrbiz.bergamot.ui.action.SchedulerActions; import com.intrbiz.bergamot.ui.action.TeamActions; import com.intrbiz.bergamot.ui.action.TimePeriodActions; import com.intrbiz.bergamot.ui.action.U2FAActions; import com.intrbiz.bergamot.ui.api.APIRouter; import com.intrbiz.bergamot.ui.api.AgentAPIRouter; import com.intrbiz.bergamot.ui.api.AlertsAPIRouter; import com.intrbiz.bergamot.ui.api.ClusterAPIRouter; import com.intrbiz.bergamot.ui.api.CommandAPIRouter; import com.intrbiz.bergamot.ui.api.CommentsAPIRouter; import com.intrbiz.bergamot.ui.api.ConfigAPIRouter; import com.intrbiz.bergamot.ui.api.ContactAPIRouter; import com.intrbiz.bergamot.ui.api.DowntimeAPIRouter; import com.intrbiz.bergamot.ui.api.GroupAPIRouter; import com.intrbiz.bergamot.ui.api.HostAPIRouter; import com.intrbiz.bergamot.ui.api.LamplighterAPIRouter; import com.intrbiz.bergamot.ui.api.LocationAPIRouter; import com.intrbiz.bergamot.ui.api.MetricsAPIRouter; import com.intrbiz.bergamot.ui.api.ResourceAPIRouter; import com.intrbiz.bergamot.ui.api.ServiceAPIRouter; import com.intrbiz.bergamot.ui.api.StatsAPIRouter; import com.intrbiz.bergamot.ui.api.TeamAPIRouter; import com.intrbiz.bergamot.ui.api.TestAPIRouter; import com.intrbiz.bergamot.ui.api.TimePeriodAPIRouter; import com.intrbiz.bergamot.ui.api.TrapAPIRouter; import com.intrbiz.bergamot.ui.api.UtilAPIRouter; import com.intrbiz.bergamot.ui.express.BergamotCSSVersion; import com.intrbiz.bergamot.ui.express.BergamotJSVersion; import com.intrbiz.bergamot.ui.express.BergamotUpdateURL; import com.intrbiz.bergamot.ui.router.AboutRouter; import com.intrbiz.bergamot.ui.router.AlertsRouter; import com.intrbiz.bergamot.ui.router.ClusterRouter; import com.intrbiz.bergamot.ui.router.CommandRouter; import com.intrbiz.bergamot.ui.router.ContactRouter; import com.intrbiz.bergamot.ui.router.DashboardRouter; import com.intrbiz.bergamot.ui.router.ErrorRouter; import com.intrbiz.bergamot.ui.router.GroupsRouter; import com.intrbiz.bergamot.ui.router.HealthRouter; import com.intrbiz.bergamot.ui.router.HostRouter; import com.intrbiz.bergamot.ui.router.LocationRouter; import com.intrbiz.bergamot.ui.router.LoginRouter; import com.intrbiz.bergamot.ui.router.ProfileRouter; import com.intrbiz.bergamot.ui.router.ResourceRouter; import com.intrbiz.bergamot.ui.router.ServiceRouter; import com.intrbiz.bergamot.ui.router.StatsRouter; import com.intrbiz.bergamot.ui.router.TeamRouter; import com.intrbiz.bergamot.ui.router.TimePeriodRouter; import com.intrbiz.bergamot.ui.router.TrapRouter; import com.intrbiz.bergamot.ui.router.admin.AdminRouter; import com.intrbiz.bergamot.ui.router.admin.ClusterAdminRouter; import com.intrbiz.bergamot.ui.router.admin.CommandAdminRouter; import com.intrbiz.bergamot.ui.router.admin.ConfigAdminRouter; import com.intrbiz.bergamot.ui.router.admin.ConfigChangeAdminRouter; import com.intrbiz.bergamot.ui.router.admin.ContactAdminRouter; import com.intrbiz.bergamot.ui.router.admin.CredentialAdminRouter; import com.intrbiz.bergamot.ui.router.admin.GroupAdminRouter; import com.intrbiz.bergamot.ui.router.admin.HostAdminRouter; import com.intrbiz.bergamot.ui.router.admin.LocationAdminRouter; import com.intrbiz.bergamot.ui.router.admin.ResourceAdminRouter; import com.intrbiz.bergamot.ui.router.admin.SecurityDomainAdminRouter; import com.intrbiz.bergamot.ui.router.admin.ServiceAdminRouter; import com.intrbiz.bergamot.ui.router.admin.TeamAdminRouter; import com.intrbiz.bergamot.ui.router.admin.TimePeriodAdminRouter; import com.intrbiz.bergamot.ui.router.admin.TrapAdminRouter; import com.intrbiz.bergamot.ui.router.agent.AgentRouter; import com.intrbiz.bergamot.ui.router.command.CommandEditorRouter; import com.intrbiz.bergamot.ui.router.global.FirstInstallRouter; import com.intrbiz.bergamot.ui.router.global.GlobalAdminRouter; import com.intrbiz.bergamot.ui.router.global.GlobalUtilsAdminRouter; import com.intrbiz.bergamot.ui.security.BergamotSecurityEngine; import com.intrbiz.bergamot.updater.UpdateServer; import com.intrbiz.configuration.Configurable; import com.intrbiz.crypto.SecretKey; import com.intrbiz.data.DataManager; import com.intrbiz.data.cache.HazelcastCacheProvider; import com.intrbiz.lamplighter.data.LamplighterDB; import com.intrbiz.queue.QueueManager; import com.intrbiz.queue.rabbit.RabbitPool; import com.intrbiz.util.pool.database.DatabasePool; /** * The Bergamot web interface */ public class BergamotApp extends BalsaApplication implements Configurable<UICfg> { public static final class VERSION { public static final String NAME = "Bergamot Monitoring"; public static final String NUMBER = "3.0.0"; public static final String CODE_NAME = "Red Snow"; public static final class COMPONENTS { public static final String JS = "v1.5.1"; public static final String CSS = "v1.7.1"; } } private UICfg config; private ClusterManager clusterManager; private UpdateServer updateServer; private final UUID id = UUID.randomUUID(); private boolean loggingConfigured = false; public BergamotApp() { super(); } public UUID id() { return id; } @Override public void configure(UICfg cfg) throws Exception { this.config = cfg; } @Override public UICfg getConfiguration() { return this.config; } /** * Override the default configuration method */ protected void configureLogging() { if (! this.loggingConfigured) { // TODO // configure logging to terminal BasicConfigurator.configure(); Logger.getRootLogger().setLevel(Level.toLevel(this.config.getLogging().getLevel().toUpperCase())); // only run logging config once this.loggingConfigured = true; } } protected int getListenerPort(String listenerType, int defaultPort) { if ("scgi".equalsIgnoreCase(listenerType)) return this.config.getListen().getScgiPort(); return Integer.getInteger("balsa." + listenerType + ".port", defaultPort); } protected int getListenerThreadCount(String listenerType, int defaultThreadCount) { if ("scgi".equalsIgnoreCase(listenerType)) return this.config.getListen().getScgiWorkers(); return Integer.getInteger("balsa." + listenerType + ".workers", Integer.getInteger("balsa.workers", defaultThreadCount)); } @Override protected void setupEngines() throws Exception { // TODO: Don't bother sending metric yet // Setup Gerald - Service name: Bergamot.UI, send every minute // Gerald.theMole().from(this.getInstanceName()).period(1, TimeUnit.MINUTES); // task engine /* * TODO: disable the shared task engine as we are getting issues with * serialising Apache Log4J Loggers * taskEngine(new HazelcastTaskEngine()); */ // session engine sessionEngine(new HazelcastSessionEngine()); // security engine securityEngine(new BergamotSecurityEngine()); // setup the application security key if (! Util.isEmpty(this.getConfiguration().getSecurityKey())) { // set the key this.getSecurityEngine().applicationKey(SecretKey.fromString(this.getConfiguration().getSecurityKey())); } // setup accounting AccountingManager.getInstance().registerConsumer("logger", new BergamotLoggingConsumer()); AccountingManager.getInstance().registerConsumer("queue", new BergamotAccountingQueueConsumer()); AccountingManager.getInstance().bindRootConsumer("logger"); AccountingManager.getInstance().bindRootConsumer("queue"); // setup ClusterManager to manage our critical // resources across the cluster this.clusterManager = new ClusterManager(); // websocket update server this.updateServer = new UpdateServer(this.config.getListen().getWebsocketPort()); } @Override protected void setupFunctions() throws Exception { // express functions immutableFunction(new BergamotUpdateURL()); immutableFunction(new BergamotJSVersion()); immutableFunction(new BergamotCSSVersion()); } @Override protected void setupActions() throws Exception { // some actions action(new ExecuteCheckAction()); action(new SchedulerActions()); action(new DispatchResultAction()); action(new TimePeriodActions()); action(new TeamActions()); action(new ContactActions()); action(new ConfigChangeActions()); action(new CheckActions()); action(new BergamotAgentActions()); action(new U2FAActions()); } @Override protected void setupRouters() throws Exception { // health check router router(new HealthRouter()); // Setup the application routers router(new ErrorRouter()); router(new LoginRouter()); router(new DashboardRouter()); router(new GroupsRouter()); router(new ServiceRouter()); router(new HostRouter()); router(new LocationRouter()); router(new TrapRouter()); router(new ClusterRouter()); router(new ResourceRouter()); router(new TeamRouter()); router(new ContactRouter()); router(new TimePeriodRouter()); router(new ProfileRouter()); router(new StatsRouter()); router(new CommandRouter()); router(new AlertsRouter()); // Agent router(new AgentRouter()); // About router(new AboutRouter()); // Admin router(new AdminRouter()); router(new ContactAdminRouter()); router(new TeamAdminRouter()); router(new TimePeriodAdminRouter()); router(new CommandAdminRouter()); router(new LocationAdminRouter()); router(new GroupAdminRouter()); router(new HostAdminRouter()); router(new ServiceAdminRouter()); router(new TrapAdminRouter()); router(new ClusterAdminRouter()); router(new ResourceAdminRouter()); router(new ConfigChangeAdminRouter()); router(new ConfigAdminRouter()); router(new SecurityDomainAdminRouter()); router(new CredentialAdminRouter()); // Command Editor router(new CommandEditorRouter()); // Global Stuff router(new FirstInstallRouter()); router(new GlobalAdminRouter()); router(new GlobalUtilsAdminRouter()); // API router(new APIRouter()); router(new MetricsAPIRouter()); router(new AlertsAPIRouter()); router(new HostAPIRouter()); router(new LocationAPIRouter()); router(new GroupAPIRouter()); router(new ClusterAPIRouter()); router(new ServiceAPIRouter()); router(new TrapAPIRouter()); router(new ResourceAPIRouter()); router(new TimePeriodAPIRouter()); router(new CommandAPIRouter()); router(new ContactAPIRouter()); router(new TeamAPIRouter()); router(new TestAPIRouter()); router(new CommentsAPIRouter()); router(new DowntimeAPIRouter()); router(new ConfigAPIRouter()); router(new StatsAPIRouter()); router(new UtilAPIRouter()); router(new AgentAPIRouter()); router(new LamplighterAPIRouter()); } @Override protected void startApplication() throws Exception { // setup healthcheck tracker HealthTracker.getInstance().init(); // setup healthcheck agent HealthAgent.getInstance().init("ui", "bergamot-ui"); // setup the database BergamotDB.install(); try (BergamotDB db = BergamotDB.connect()) { System.out.println("Database module: " + db.getName() + " " + db.getVersion()); } LamplighterDB.install(); try (LamplighterDB db = LamplighterDB.connect()) { System.out.println("Database module: " + db.getName() + " " + db.getVersion()); } // don't bother starting scheduler etc on ui only nodes if (!Boolean.getBoolean("bergamot.ui.only")) { // start the cluster manager this.clusterManager.start(this.getInstanceName()); // register sites with the cluster manager try (BergamotDB db = BergamotDB.connect()) { for (Site site : db.listSites()) { if (! site.isDisabled()) this.clusterManager.registerSite(site); } } } // start the update websocket server this.updateServer.start(); // Start Gerald // Gerald.theMole().start(); System.out.println("Application startup finished"); } public ClusterManager getClusterManager() { return this.clusterManager; } public UpdateServer getUpdateServer() { return updateServer; } public static void main(String[] args) throws Exception { try { // read config UICfg config = UICfg.loadConfiguration(); System.out.println("Using configuration: "); System.out.println(config.toString()); // create the application BergamotApp bergamotApp = new BergamotApp(); bergamotApp.configure(config); // Setup logging ASAP bergamotApp.configureLogging(); // compile database System.out.println("Compiling DB"); BergamotDB.load(); LamplighterDB.load(); // setup the cache System.out.println("Setting up Hazelcast"); DataManager.get().registerCacheProvider("hazelcast", new HazelcastCacheProvider(BergamotApp.getApplicationInstanceName())); DataManager.get().registerDefaultCacheProvider(DataManager.get().cacheProvider("hazelcast")); // setup the queue manager System.out.println("Setting up RabbitMQ"); QueueManager.getInstance().registerDefaultBroker(new RabbitPool(config.getBroker().getUrl(), config.getBroker().getUsername(), config.getBroker().getPassword())); // setup data manager System.out.println("Setting up PostgreSQL"); DataManager.getInstance().registerDefaultServer(DatabasePool.Default.with().postgresql().url(config.getDatabase().getUrl()).username(config.getDatabase().getUsername()).password(config.getDatabase().getPassword()).build()); // start the app System.out.println("Starting Bergamot UI"); bergamotApp.start(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } public static String getApplicationInstanceName() { return BalsaApplication.getApplicationInstanceName(BergamotApp.class); } }