952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
241 lines
9.9 KiB
PHP
241 lines
9.9 KiB
PHP
<?php
|
|
define('PHP_MINIMUM_VERSION', 70401);
|
|
/**
|
|
* common directives for rabbitMQ daemons to load environment configuration:
|
|
* - set directory paths
|
|
* - install the autoloader
|
|
* - install the amqp library (rabbitMQ) if required (defined in constants)
|
|
* - declare globals
|
|
* - load the common files/functions
|
|
* - initialize the singleton configuration global
|
|
*
|
|
* this file should be required by ALL rabbitMQ daemons (brokers)
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* HISTORY:
|
|
* --------
|
|
* 06-07-17 MKS initial coding
|
|
* 06-13-17 mks reversed the config file paradigm - the default is now to load a development-level
|
|
* configuration and overwrite it with the env.xml file, if it exists.
|
|
* 05-31-18 mks CORE-1011: update for new XML broker services configuration
|
|
* 06-08-18 mks CORE-1034: deprecated prodBox XML tag
|
|
* 06-13-18 mks CORE-1048: improved diagnostic logging/start-up messages, deprecated node-check
|
|
* 06-15-18 mks CORE-1045: deprecated CONFIG_ID_NODE tag
|
|
* 07-10-18 mks CORE-773: replaced echo statements with consoleLog()
|
|
* 07-24-18 mks CORE-1097: cleaning up logging output
|
|
* 09-02-18 mks DB-43: Parse exception-handling wrappers around require statements
|
|
* 11-29-18 mks DB-51: cleaning up debug/log messages
|
|
* 05-23-19 mks DB-116: work-around for array_key_first() (PHP 7.3 only function)
|
|
* 10-12-20 mks DB-156: fixed debug check for broker services
|
|
*
|
|
*/
|
|
$eos = (isset($_SERVER['HTTP_USER_AGENT'])) ? '<br />' : PHP_EOL;
|
|
$res = 'BOOT: '; // console log identifier
|
|
|
|
function gt(): string
|
|
{
|
|
global $res;
|
|
$cs = ' [ S]';
|
|
return('[' . date("d/m/y@H:i:s", time()) . ']' . $cs . $res);
|
|
}
|
|
|
|
// add a version check for php
|
|
if (PHP_VERSION_ID < PHP_MINIMUM_VERSION) exit ('A version of PHP >= 7.4.1 is required to run Namaste.' . PHP_EOL);
|
|
|
|
$topDir = dirname( __DIR__ );
|
|
if (!file_exists($topDir . '/logs')) { // <-- using the logs literal because constants not loaded yet
|
|
echo gt() . 'ERROR - LOG DIRECTORY DOES NOT EXIST - NAMASTE CANNOT RUN.' . PHP_EOL;
|
|
echo gt() . 'Please fix this problem immediately.' . PHP_EOL . PHP_EOL;
|
|
die();
|
|
}
|
|
|
|
// set-up the log files
|
|
$logFile = $topDir . '/logs/namaste.log';
|
|
$logErrors = $topDir . '/logs/namaste_err.log';
|
|
$logs = [ $logFile, $logErrors ];
|
|
foreach ($logs as $log) {
|
|
if (!file_exists($log)) {
|
|
echo gt() . 'Creating logfile: ' . $log . PHP_EOL;
|
|
touch($log);
|
|
}
|
|
}
|
|
|
|
// redirect i/o for console logging
|
|
if (!isset($_REDIRECT)) $_REDIRECT = true;
|
|
if ($_REDIRECT) {
|
|
@fclose(STDIN);
|
|
@fclose(STDOUT);
|
|
@fclose(STDERR);
|
|
}
|
|
@$STDIN = fopen('/dev/null', 'r');
|
|
if (!@$STDOUT = fopen($logFile, 'a+b')) {
|
|
echo gt() . 'Error - unable to open ' . $logFile . ' for logging' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
if (!@$STDERR = fopen($logErrors, 'a+b')) {
|
|
if (!$STDOUT) {
|
|
echo gt() . 'Error - unable to open ' . $logErrors . ' for error logging' . PHP_EOL;
|
|
} else {
|
|
fwrite($STDOUT, gt() . 'Error - unable to open: ' . $logErrors . ' for error logging' . PHP_EOL);
|
|
}
|
|
exit(1);
|
|
}
|
|
// =-=-=-=-= from this point forward, must use fwrite(STDERR|STDOUT) for console logging =-=-=-=-=
|
|
|
|
fwrite($STDOUT, gt() . 'Loading common files...' . PHP_EOL);
|
|
// load the files stored in the common directory
|
|
foreach(glob($topDir . '/common/*.php') as $filename) {
|
|
fwrite($STDOUT, gt() . 'Loading: ' . $filename . PHP_EOL);
|
|
try {
|
|
/** @noinspection PhpIncludeInspection */
|
|
require_once($filename);
|
|
} catch (ParseError $p) {
|
|
echo gt() . 'Caught parse exception in ' . $filename . PHP_EOL;
|
|
echo gt() . $p->getMessage() . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// ---------------------- system constants and error messages are now available -------------------------
|
|
|
|
$classesDir = $topDir . DIR_CLASSES;
|
|
$configDir = $topDir . DIR_CONFIG;
|
|
$amqpLib = $topDir . DIR_LIB;
|
|
$templateDir = $topDir . DIR_CLASSES . DIR_TEMPLATE;
|
|
$logDir = $topDir . DIR_LOGS;
|
|
date_default_timezone_set(STRING_SYS_TZ);
|
|
|
|
fwrite($STDOUT, gt() . 'Loading framework autoloader...' . PHP_EOL);
|
|
try {
|
|
/** @noinspection PhpIncludeInspection */
|
|
require($topDir . FILE_AUTOLOADER);
|
|
} catch (ParseError $p) {
|
|
echo gt() . 'Caught parse exception in ' . $topDir . FILE_AUTOLOADER . PHP_EOL;
|
|
echo gt() . $p->getMessage() . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
if(file_exists($classesDir)) {
|
|
Autoloader::register_directory($classesDir);
|
|
Autoloader::register_directory($templateDir);
|
|
}
|
|
|
|
fwrite($STDOUT, gt() . 'Loading vendor-library autoloader...' . PHP_EOL);
|
|
// php-amqplib load (v2)
|
|
if (!file_exists($amqpLib)) {
|
|
fwrite($STDERR, getDateTime() . CON_SYSTEM . $res . ERROR_LIB_404 . $amqpLib . PHP_EOL);
|
|
die();
|
|
}
|
|
|
|
try {
|
|
$loadFile = $amqpLib . '/vendor/autoload.php';
|
|
/** @noinspection PhpIncludeInspection */
|
|
require_once $loadFile;
|
|
} catch (ParseError $p) {
|
|
echo gt() . 'Caught parse exception in ' . $loadFile . PHP_EOL;
|
|
echo gt() . $p->getMessage() . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
use /** @noinspection PhpUnusedAliasInspection */ PhpAmqpLib\Connection\AMQPStreamConnection;
|
|
use /** @noinspection PhpUnusedAliasInspection */ PhpAmqpLib\Channel\AMQPChannel;
|
|
use /** @noinspection PhpUnusedAliasInspection */ PhpAmqpLib\Message\AMQPMessage;
|
|
|
|
// check to ensure required functions are installed and supported on the server.
|
|
// if not, then error to the console and exit.
|
|
|
|
// pcntl extension is disabled in Apache PHP but enabled in cli-PHP
|
|
if (!extension_loaded('pcntl') and !isset($_SERVER['HTTP_USER_AGENT'])) {
|
|
consoleLog($res, CON_ERROR, 'API for Process Control may be missing. See: http://www.php.net/manual/en/pcntl.installation.php');
|
|
}
|
|
if (extension_loaded('pcntl') and isset($_SERVER['HTTP_USER_AGENT'])) {
|
|
consoleLog($res, CON_ERROR, 'PCNTL extension SHOULD NOT BE LOADED IN APACHE-PHP! (SECURITY VIOLATION)');
|
|
exit(1);
|
|
}
|
|
|
|
/**
|
|
* initialize the static configuration object which is used throughout the framework
|
|
*
|
|
* Since there does not exist a way to gracefully handle errors via the error object,
|
|
* we have to output generated errors to STDOUT and let the console operator proceed
|
|
* from there with whatever diagnostics we supplied.
|
|
*
|
|
* generally speaking, we load the namaste.xml configuration -- which, by design, is
|
|
* a development-level configuration file.
|
|
*
|
|
* the env.xml file is optional -- if it exists, it will be loaded and duplicate keys
|
|
* in the namaste.xml file will be replaced by the env.xml elements.
|
|
*
|
|
*/
|
|
fwrite($STDOUT, gt() . 'Loading base configuration....' . PHP_EOL);
|
|
if (!file_exists($configDir . FILE_BASE_CONFIG)) {
|
|
fwrite($STDERR, gt() . ' [ !] COMMON - could not locate base configuration file.' . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' [ !] check that ' . FILE_BASE_CONFIG . ' exists in the' . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' [ !] directory: ' . $configDir . '.' . PHP_EOL);
|
|
} else {
|
|
// load the base configuration
|
|
if (!gasConfig::singleton($configDir . FILE_BASE_CONFIG, FILE_TYPE_XML)) {
|
|
fwrite($STDERR, gt() . ' [ !] COMMON - could not load base configuration file.' . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' [ !] file: ' . FILE_BASE_CONFIG . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' [ !] directory: ' . $configDir . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
}
|
|
// make sure a base config was loaded
|
|
if (empty(gasConfig::$settings)) {
|
|
fwrite($STDERR, gt() . ' [ !] COMMON - unknown error raised loading base configuration file - program ends.' . PHP_EOL);
|
|
}
|
|
if (!isset(gasConfig::$settings[CONFIG_ID][CONFIG_ID_ENV])) {
|
|
fwrite($STDERR, gt() . ' [ !] COMMON - Have not defined environment status relative to an environment.' . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' Check the base configuration file: ' . FILE_BASE_CONFIG . PHP_EOL);
|
|
fwrite($STDERR, gt() . ' for the xml-label: ' . CONFIG_ID_ENV . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
|
|
fwrite($STDOUT, gt() . 'Loading and layering env configuration....' . PHP_EOL);
|
|
// load the environment configuration -- if an error occurs loading the env.xml file, then execution will cease.
|
|
if (file_exists($configDir . FILE_ENV_CONFIG)) {
|
|
gasConfig::addConfig($configDir . FILE_ENV_CONFIG, FILE_TYPE_XML);
|
|
if (!gasConfig::$status) {
|
|
fwrite($STDERR, gt() . ' [ !] COMMON - Unable to successfully load the namaste.xml file.' . PHP_EOL);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// set the rabbitMQ debug if namaste has debug on in the XML under broker-services
|
|
define('AMQP_DEBUG', ((gasConfig::$settings[CONFIG_BROKER_SERVICES][CONFIG_BROKER_DEBUG]) ? true : false));
|
|
|
|
// deprecated via CORE-1011
|
|
//// these are the only valid node names
|
|
//fwrite($STDOUT, gt() . 'Validating service environments....' . PHP_EOL);
|
|
//$validNodes = [ CONFIG_ID_NODE_NAMASTE, CONFIG_ID_NODE_ADMIN, CONFIG_ID_NODE_DEV ];
|
|
//if (!in_array(gasConfig::$settings[CONFIG_ID][CONFIG_ID_NODE], $validNodes)) {
|
|
// $msg = sprintf(' [ X] COMMON - check the configuration: %s is not a valid node id (cfg.id.nodename)', gasConfig::$settings[CONFIG_ID][CONFIG_ID_NODE]);
|
|
// fwrite($STDERR, $msg);
|
|
// exit(1);
|
|
//}
|
|
|
|
// initialize the global objects - failures for each object are generated within the object's constructors
|
|
// and are sent to stdout...
|
|
// initialize the global Resource Manager object
|
|
fwrite($STDOUT, gt() . $res . 'Loading resource manager....' . PHP_EOL);
|
|
if (!isset(gasResourceManager::$available) or !gasResourceManager::$available) {
|
|
gasResourceManager::singleton();
|
|
if (!gasResourceManager::$IPL) {
|
|
consoleLog($res, CON_ERROR, ERROR_FW_IPL);
|
|
} else {
|
|
gasResourceManager::$available = true;
|
|
}
|
|
}
|
|
|
|
// initialize the global Memcache object
|
|
fwrite($STDOUT, gt() . $res . 'Loading memcache manager....' . PHP_EOL);
|
|
if (!isset(gasCache::$available) or !gasCache::$available) {
|
|
gasCache::singleton();
|
|
}
|
|
|
|
fwrite($STDOUT, gt() . $res . 'Loading static manager....' . PHP_EOL);
|
|
if (!isset(gasStatic::$available) or !gasStatic::$available) {
|
|
gasStatic::singleton();
|
|
}
|