public static void stopServices() throws Exception {
    MySqlPortal.stop();

    TemporaryTable.onStopServices();

    if (GroupManager.getCoordinationServices() != null)
      GroupManager.getCoordinationServices().unRegisterWithGroup();

    Host.hostStop();

    Agent.stopServices();
    CatalogDAOFactory.shutdown();
    AutoIncrementTracker.clearCache();
    RangeDistributionModel.clearCache();
    RandomDistributionModel.clearCache();
    SiteProviderFactory.closeSiteProviders();
    ExternalServiceFactory.closeExternalServices();
    GroupManager.shutdown();
    DirectConnectionCache.clearConnectionCache();
  }
  public static <T> BootstrapHost startServices(Class<T> bootstrapClass, Properties props)
      throws Exception {

    String url = props.getProperty(DBHelper.CONN_URL);
    String database = props.getProperty(DBHelper.CONN_DBNAME, PEConstants.CATALOG);

    // Fail to start if we don't have a valid catalog connection URL
    if (StringUtils.isBlank(url))
      throw new PEException(
          "Value for " + DBHelper.CONN_URL + " not specified in server configuration");

    if (StringUtils.isBlank(database))
      throw new PEException(
          "Value for " + DBHelper.CONN_DBNAME + " not specified in server configuration");

    // Attempt to load the JDBC driver - fail early if it isn't available
    DBHelper.loadDriver(props.getProperty(DBHelper.CONN_DRIVER_CLASS));

    props.put(
        DBHelper.CONN_URL,
        CatalogURL.buildCatalogBaseUrlFrom(props.getProperty(DBHelper.CONN_URL)).toString());
    props.put(DBHelper.CONN_DBNAME, database);
    DBHelper helper = new DBHelper(props);
    int catalogAccessible = 1;
    try {
      // Check that we can connect to the database and that the catalog database exists
      helper.connect();

      // and also check that it is a valid catalog
      helper.executeQuery("SELECT name FROM " + database + ".user_table");
    } catch (Exception e) {
      String message = e.getMessage();
      if (message != null && message.startsWith("Error using")) catalogAccessible = -1;
      else catalogAccessible = 0;
      if (catalogAccessible == 0)
        throw new Exception(
            "A DVE catalog couldn't be found at '"
                + url
                + "' with name '"
                + database
                + "' - use dve_config to set the connection credentials for the server (error was "
                + message
                + ")");
    } finally {
      helper.disconnect();
    }

    if (catalogAccessible == -1) {
      new CatalogHelper(bootstrapClass).createBootstrapCatalog();
    }

    // Temporarily set the log level to info so that the below message will print and force the
    // header to print
    Level logLevel =
        logger.getLevel(); // this is needed in case an explicit level is set on this category
    Level effectiveLevel =
        logger
            .getEffectiveLevel(); // if an explicit level isn't set, this gets the level from the
                                  // hierarchy
    logger.setLevel(Level.INFO);

    if (catalogAccessible == -1) {
      logger.info("INSTALLED BOOTSTRAP CATALOG " + database + " AT " + url);
    }

    logger.info("Starting DVE server using:");
    logger.info("... Catalog URL      : " + url);
    logger.info("... Catalog database : " + database);
    logger.info("... Catalog User     : "******"Resetting log level back to: " + effectiveLevel);
    logger.setLevel(logLevel);

    // We have to initialize the Group Manager before anything else.
    GroupManager.initialize(props);
    GroupManager.getCoordinationServices().registerWithGroup(props);

    CatalogDAOFactory.setup(props);

    SchemaSourceFactory.reset();

    ErrorMapper.initialize();

    Agent.setPluginProvider(SimpleMQPlugin.PROVIDER);
    Agent.startServices(props);

    BootstrapHost host = new BootstrapHost(bootstrapClass.getName(), props);

    ClusterLock genLock =
        GroupManager.getCoordinationServices()
            .getClusterLock(RangeDistributionModel.GENERATION_LOCKNAME);
    String reason = "boostrapping system";
    genLock.sharedLock(null, reason);
    genLock.sharedUnlock(null, reason);

    TemporaryTable.onStartServices();

    MySqlPortal.start(props);

    return host;
  }