Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
This commit is contained in:
172
classes/gacLogClient.class.inc
Normal file
172
classes/gacLogClient.class.inc
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* gacLogClient -- class definition
|
||||
*
|
||||
* this is the class for declaring a logClient for use in testing, or within the framework when we need to publish
|
||||
* a log event to another queue.
|
||||
*
|
||||
* This class simply abstracts the RabbitMQ processes so that you don't have to re-write all the RMQ code every
|
||||
* time you want to publish a message to the log exchange.
|
||||
*
|
||||
* IMPORTANT NOTE:
|
||||
* ---------------
|
||||
* Whenever you add a qualifying queue to the pantheon, you'll need to update the constructor class, adding the queue
|
||||
* name to the $validQueues member, and to the switch-case statement that assigns the correct environment.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-18-19 mks DB-136: original coding
|
||||
* 12-04-19 mks DB-140: PHP 7.4 compliance
|
||||
* 01-07-20 mks DB-150: PHP 7.4 member variable casting
|
||||
*
|
||||
*/
|
||||
|
||||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use PhpAmqpLib\Exception\AMQPRuntimeException;
|
||||
use PhpAmqpLib\Exception\AMQPTimeoutException;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
|
||||
|
||||
class gacLogClient {
|
||||
private ?object $rabbitConnection;
|
||||
private AMQPChannel $rabbitChannel;
|
||||
private string $res = 'BRCL: ';
|
||||
// if you add to the log-exchange bindings, for either service or source, remember to update these arrays as needed
|
||||
private array $validTypes = [ EXCHANGE_SOURCE_LOGS, EXCHANGE_SOURCE_METRICS, STAR ];
|
||||
public string $status;
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* the constructor instantiates the class and establishes a connection to the RMQ Log Exchange.
|
||||
*
|
||||
* other client classes, such as BrokerClient, require a queue name to be passed to the constructor because these
|
||||
* clients are connecting directly to the queues to publish an event. This client, instead, connects to the
|
||||
* log exchange (instead of a queue) and publishes to the exchange.
|
||||
*
|
||||
* Within the bindings for the exchange which are coded in the brokers for each of the exchange queues, are the
|
||||
* configuration directives for how messages are routed by the exchange to the destination queues. Messages
|
||||
* published to the exchange can be routed to one, several, or all of the queues bound to the exchange.
|
||||
*
|
||||
* That is why there isn't a string parameter passed to this class' constructor - because this client connects
|
||||
* to the exchange and not to a broker specified by the input parameter.
|
||||
*
|
||||
* method returns an implicit boolean via a class member (status) indicating whether or not the resource management
|
||||
* was successful and attempts to provide diagnostics via logging, cli output, or via the status member variable.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-18-19 mks DB-136: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
register_shutdown_function(array($this, '__destruct'));
|
||||
$this->status = false;
|
||||
try {
|
||||
// fetch the AMQPStreamConnection to the Admin service
|
||||
$this->rabbitConnection = gasResourceManager::fetchResource(RESOURCE_ADMIN);
|
||||
if (is_null($this->rabbitConnection)) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
consoleLog($this->res, CON_ERROR, $hdr . ERROR_RESOURCE_404 . RESOURCE_ADMIN);
|
||||
return;
|
||||
}
|
||||
$this->rabbitChannel = $this->rabbitConnection->channel();
|
||||
// connect the channel to the logging exchange
|
||||
$this->rabbitChannel->exchange_declare(EXCHANGE_NAME_TOPIC_LOGS, EXCHANGE_TYPE_TOPIC, false, false, false);
|
||||
$this->status = true;
|
||||
} catch (AMQPRuntimeException | AMQPTimeoutException | Throwable $t) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
consoleLog($this->res, CON_ERROR, $hdr . ERROR_THROWABLE_EXCEPTION);
|
||||
consoleLog($this->res, CON_ERROR, $hdr . $t->getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* call() -- public method
|
||||
*
|
||||
* This method is invoked outside of the class and is the entry point for publishing a message request to the
|
||||
* logging exchange. It creates a new AMQP message and publishes it to the exchange, defined in the constructor),
|
||||
* and then blocks-and-waits for a response from the remote (vault) service.
|
||||
*
|
||||
* There are two input parameters to this method:
|
||||
*
|
||||
* $_data -- this is the payload data that, untouched, is converted into an AMQPMessage class object
|
||||
* $_route -- this defines how the exchange will handle the incoming message (<service>.<source> format)
|
||||
*
|
||||
* For exchange routing, the $_route is required and critical for delivering a successful message request to
|
||||
* the logging exchange. The following values are valid routes with the default route set to STAR:
|
||||
*
|
||||
* EXCHANGE_SOURCE_METRICS, EXCHANGE_SOURCE_LOGS, STAR
|
||||
*
|
||||
* Publishing a message is exception trapped and will generate a log message at the warn level if tripped.
|
||||
*
|
||||
* The method returns a boolean to the calling client if the message was successfully published to the exchange.
|
||||
* Since logging is fire-n-forget, we can't know if the message was accepted... if a false value is returned,
|
||||
* then the client should check the console log as their request failed routing validation.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param $_data -- the payload to be converted to an AMQPMessage class object
|
||||
* @param $_route -- The declared route for the message request ( defaults to: * )
|
||||
*
|
||||
* @return bool -- indicates if the message was successfully published or not
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-18-19 mks DB-136: original coding
|
||||
*
|
||||
*/
|
||||
public function call(string $_data, string $_route = STAR): bool
|
||||
{
|
||||
// validate the routing string for the exchange...
|
||||
if (!in_array($_route, $this->validTypes)) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
$msg = sprintf(ERROR_SERVICE_SOURCE_UNK, $_route);
|
||||
consoleLog($this->res, CON_ERROR, $hdr . $msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create and publish the message to the logging exchange
|
||||
try {
|
||||
$rabbitMessage = new AMQPMessage((string)$_data);
|
||||
$this->rabbitChannel->basic_publish($rabbitMessage, EXCHANGE_NAME_TOPIC_LOGS, $_route);
|
||||
consoleLog($this->res, CON_SUCCESS, SUCCESS_PUBLISHED . $_route);
|
||||
} catch (AMQPTimeoutException | AMQPRuntimeException | Throwable $e) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
consoleLog($this->res, CON_ERROR, $hdr . $e->getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
//
|
||||
// destructor is registered shut-down function in constructor -- so any recovery
|
||||
// efforts should go in this method.
|
||||
try {
|
||||
$this->rabbitChannel->close();
|
||||
$this->rabbitConnection->close();
|
||||
} catch (AMQPTimeoutException | AMQPRuntimeException | Throwable $t) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
consoleLog($this->res, CON_ERROR, $hdr . ERROR_THROWABLE_EXCEPTION);
|
||||
consoleLog($this->res, CON_ERROR, $hdr . $t->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user