Files
namaste/classes/gacBrokerHelper.class.inc
gramps 373ebc8c93 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.
2026-04-05 09:49:30 -07:00

354 lines
16 KiB
PHP

<?php
/**
* Class gacBrokerHelper
*
* There are certain events that are duplicated across the different services. These events, at the broker levels, had
* their processing code/logic pulled and moved to this helper class.
*
* BrokerHelper is a vector for eliminating redundant code across the broker services.
*
*
* @author mike@givingassistant.org
* @version 1.0
*
* HISTORY:
* ========
* 07-17-20 mks DB-156: original coding
*
*/
class gacBrokerHelper
{
private int $queryRecordLimit;
private string $res = 'BH : ';
public bool $status;
public string $state;
private ?gacErrorLogger $logger;
public function __construct()
{
$this->logger = new gacErrorLogger();
$this->queryRecordLimit = intval(gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_RECORD_LIMIT]);
$this->state = STATE_INITIALIZED;
$this->status = true;
}
/**
* create() -- public method
*
* This method was taken from the write-broker's create event. This method handles the class method invocations
* for creating a new class record. There are three input parameters to this method:
*
* $_request -- this is the broker request containing all three parts (event, data and meta-data)
* $_aryRetData -- call-by-reference object which is a broker's return payload array
* $_msg -- call-by-reference string which is the generated console message
*
* This method calculates the query record limit (one of the XML configurable parameters) and returns immediately
* if the number of submitted records exceeds the XML-stated limitation.
*
* Next, we instantiate a factory object based on the current meta-data payload and we'll return immediately if we
* were unable to instantiate a factory class successfully.
*
* We copy off the widget (data class object) and invoke the create() method. On successful return, we cache-map
* the outbound payload and build the aryRetData container based on those results.
*
* The method returns a boolean indicating whether or not the record(s) were successfully created.
*
*
* @author mike@givingassistant.org
* @version 1.0
*
* @param array $_request
* @param array|null $_aryRetData
* @param string $_msg
* @return bool|null
*
*
* HISTORY:
* ========
* 07-17-20 mks DB-156: original coding completed
*
*/
public function create(array $_request, ?array &$_aryRetData, string &$_msg):?bool
{
$rc = false;
$errors = [];
if (count($_request[BROKER_DATA]) > $this->queryRecordLimit) {
$_msg = ERROR_RECORD_LIMIT_EXCEEDED . $this->queryRecordLimit;
$this->logger->error($_msg);
$_aryRetData = buildReturnPayload([false, STATE_DATA_ERROR, $_msg, null]);
return $rc;
}
try {
/** @var gacMongoDB $widget */
if (is_null($widget = grabWidget($_request[BROKER_META_DATA], '', $errors))) {
foreach ($errors as $error)
$this->logger->error($error);
$_aryRetData = buildReturnPayload([false, STATE_FRAMEWORK_FAIL, ERROR_FACTORY_LOAD_BROKER . BROKER_REQUEST_CREATE, null]);
return $rc;
}
$widget->_createRecord($_request[BROKER_DATA]);
if ($widget->status) {
if (gasCache::mapOutboundPayload($widget, $errors)) {
$_aryRetData = buildReturnPayload([true, STATE_SUCCESS, $widget->queryResults, $widget->getCK()]);
$rc = true;
} else {
$_aryRetData = buildReturnPayload([false, $widget->state, $widget->eventMessages, null]);
$_msg = ERROR_CACHE_MAP_FAIL . ' tercero payload';
$this->logger->warn($_msg);
consoleLog($this->res, CON_ERROR, $_msg);
}
} else {
$widget->eventMessages[] = FAIL_EVENT . BROKER_REQUEST_CREATE;
$_aryRetData = buildReturnPayload([FALSE, $widget->state, $widget->eventMessages, null]);
}
if (is_object($widget)) $widget->__destruct();
unset($widget);
} catch (TypeError | Throwable $t) {
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
@handleExceptionMessaging($hdr, $t->getMessage(), $errors, true);
$_aryRetData = buildReturnPayload([false, STATE_FAIL, ERROR_EXCEPTION, null]);
}
return $rc;
}
/**
* fetch() -- public function
*
* The fetch method was culled from the read broker event processing for the same event. It allows us to access
* the fetch code from either the appServer or Tercero brokers.
*
* There are three input parameters to this method:
*
* $_request -- this is the array of event data submitted (Request, Data, Meta)
* $_aryRetData -- call-by-reference parameter which is the array returned to the calling client
* $_msg -- call by reference parameter that carries the console log message back to the calling client
*
* The method returns a boolean variable indicating if the fetch completed successfully or not. The data returned
* in the fetch operation is implicitly returned via the method's input parameters.
*
* The method instantiates a factory object which builds the schema-widget which is then used to execute
* the request query to fetch the data - the results of which are bundled-up and returned back to the
* calling client.
*
* In this implementation, I've removed support for the remoteFetchRequest() method call because validateMetaData()
* is now handling the tercero re-directs.
*
* @author mike@givingassistant.org
* @version 1.0
*
*
* @param array $_request
* @param array|null $_aryRetData
* @param string|null $_msg
* @return bool
*
*
* HISTORY:
* ========
* 08-03-20 mks DB-157: original coding completed
*
*/
public function fetch(array $_request, ?array &$_aryRetData = null, ?string &$_msg = null):bool
{
$errors = array();
$rc = false;
try {
// cant instantiate remote-service objects in production, so we'll inject an skip
// directive for the env-check... todo -- qualify this!
/** @var gacMongoDB $objClass */
if (is_null($objClass = grabWidget($_request[BROKER_META_DATA], '', $errors))) {
foreach ($errors as $error)
$this->logger->error($error);
$_aryRetData = buildReturnPayload([false, STATE_DATA_ERROR, ERROR_FACTORY_LOAD_BROKER . BROKER_REQUEST_CREATE, null]);
} else {
// CORE-1013 ---------------------------------------------------------------
$objClass->_fetchRecords($_request[BROKER_DATA]);
if ($objClass->status) {
$rc = true;
$_msg = SUCCESS_EVENT . BROKER_REQUEST_FETCH;
$queryMeta = [
STRING_REC_COUNT_RET => $objClass->recordsReturned,
STRING_REC_COUNT_QUERY => $objClass->recordsInQuery,
STRING_REC_COUNT_TOT => $objClass->recordsInCollection
];
if ($objClass->state == STATE_NOT_FOUND and $objClass->count == 0) {
$retData = [STRING_QUERY_RESULTS => null, STRING_QUERY_DATA => $queryMeta];
} else {
// cacheMapping call
if (!gasCache::mapOutboundPayload($objClass, $errors)) {
$queryResults = $objClass->getData();
} else {
// cache mapping succeeded - return the cache key
$queryResults = $objClass->getCK();
}
$retData = [STRING_QUERY_RESULTS => $queryResults, STRING_QUERY_DATA => $queryMeta];
}
$_aryRetData = buildReturnPayload([true, $objClass->state, $objClass->eventMessages, $retData]);
} else {
$_msg = FAIL_EVENT . BROKER_REQUEST_FETCH;
$_aryRetData = buildReturnPayload([false, $objClass->state, $objClass->eventMessages, null]);
}
if (is_object($objClass)) $objClass->__destruct();
unset($objClass);
}
} catch (Throwable | TypeError $t) {
$hdr = sprintf(basename(__METHOD__), __LINE__);
@handleExceptionMessaging($hdr, $t->getMessage(), $errors, true);
$_aryRetData = buildReturnPayload([false, STATE_FRAMEWORK_FAIL, ERROR_EXCEPTION, null]);
}
return $rc;
}
/**
* update() -- public function
*
* This function was populated using code from the write-broker update event. The code was moved to the BH class
* so that it could be accessed by either the appServer:wBroker or tercero:userBroker brokers to process an
* update request.
*
* The function requires three input parameters:
*
* $_request -- this is the request payload as received by the broker, post-validation processing
* $_aryRetData -- this is a call-by-reference parameter that will contain the return payload that is sent back
* to the calling client on completion
* $_msg -- this is a string, a call-by-reference parameter, that will contain the event message for the
* console log.
*
* The method itself returns a boolean value to indicate if processing successfully completed or not.
*
*
* @author mike@givingassistant.org
* @version 1.0
*
* @param array $_request
* @param array|null $_aryRetData
* @param string|null $_msg
* @return bool
*
*
* HISTORY:
* ========
* 08-04-20 mks DB-157: original coding happy birthday dad!
*
*/
public function update(array $_request, ?array &$_aryRetData = null, ?string &$_msg = null):bool
{
$rc = false;
$errors = [];
$objEvent = new gacFactory($_request[BROKER_META_DATA], FACTORY_EVENT_NEW_CLASS, '', $errors);
if (!$objEvent->status) {
$msg = ERROR_FACTORY_LOAD_BROKER . BROKER_REQUEST_CREATE;
$_msg = $msg;
$errors[] = $msg;
$_aryRetData = buildReturnPayload([false, STATE_FRAMEWORK_FAIL, $errors, null]);
$this->logger->fatal($msg);
} else {
/** @var gacMongoDB | gacPDO $objClass */
$objClass = $objEvent->widget;
if ($objClass->schema == TEMPLATE_DB_MONGO) {
if (isset($request[BROKER_META_DATA][META_LIMIT]) and $_request[BROKER_META_DATA][META_LIMIT] !== 1)
$request[BROKER_DATA][STRING_QUERY_OPTIONS][STRING_MULTI] = true;
else
$request[BROKER_DATA][STRING_QUERY_OPTIONS][STRING_MULTI] = false;
}
$objClass->_updateRecord($_request[BROKER_DATA]);
if ($objClass->status) {
$rc = true;
$_msg = SUCCESS_EVENT . BROKER_REQUEST_UPDATE;
try {
if ($objClass->state == STATE_NOT_FOUND) {
$_aryRetData = buildReturnPayload([false, STATE_NOT_FOUND, $objClass->eventMessages, null]);
} else {
$queryResults = (!gasCache::mapOutboundPayload($objClass, $errors)) ? $objClass->getData() : $objClass->getCK();
$_aryRetData = buildReturnPayload([true, STATE_SUCCESS, $objClass->queryResults, $queryResults]);
}
} catch (TypeError | Throwable $t) {
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __FILE__);
$msg = ERROR_EXCEPTION;
$this->logger->error($hdr . $msg);
$this->logger->error($t->getMessage());
$_aryRetData = buildReturnPayload([false, STATE_FAIL, $msg, null]);
$_msg = FAIL_EVENT . $hdr . $t->getMessage();
}
} else {
$_msg = FAIL_EVENT . BROKER_REQUEST_UPDATE;
$_aryRetData = buildReturnPayload([false, $objClass->state, $objClass->eventMessages, null]);
}
if (is_object($objClass)) $objClass->__destruct();
unset($objClass);
}
if (is_object($objEvent)) $objEvent->__destruct();
unset($objEvent);
return $rc;
}
/**
* delete() -- public method
*
* This method is the delete block formerly located in the write-broker, moved to the broker helper so that the
* code is equally accessible by either appServer:wBroker or tercero:uBroker brokers.
*
* There are three input parameters to this method:
*
* $_request -- this is an array containing the processed data payload from the broker event request
* $_aryRetData -- call-by-reference array that will contain the return payload to be sent back to the client
* $_msg -- call-by-reference string that will contain the console log message from processing
*
* The method returns a boolean indicating if the routine successfully processed to completion or not.
*
*
* @author mike@givingassistant.org
* @version 1.0
*
* @param array $_request
* @param array|null $_aryRetData
* @param string|null $_msg
* @return bool
*
*
* HISTORY:
* ========
* 08-05-20 mks DB-157: original coding completed
*
*/
public function delete(array $_request, ?array &$_aryRetData = null, ?string &$_msg = null): bool
{
$rc = false;
$errors = [];
try {
/** @var gacMongoDB $objClass */
if (is_null($objClass = grabWidget($_request[BROKER_META_DATA], '', $errors))) {
foreach ($errors as $error)
$this->logger->error($error);
$_aryRetData = buildReturnPayload([false, STATE_FRAMEWORK_FAIL, ERROR_FACTORY_LOAD_BROKER . BROKER_REQUEST_CREATE, null]);
} else {
$objClass->_deleteRecord($_request[BROKER_DATA]);
if ($objClass->status and $objClass->state != STATE_NOT_FOUND) {
$_msg = SUCCESS_EVENT . BROKER_REQUEST_DELETE;
$rc = true;
$_aryRetData = buildReturnPayload([true, STATE_SUCCESS, $objClass->eventMessages, [STRING_RECS_DELETED => $objClass->rowsAffected]]);
} elseif ($objClass->status and $objClass->state == STATE_NOT_FOUND) {
$_msg = FAIL_EVENT . BROKER_REQUEST_DELETE;
$_aryRetData = buildReturnPayload([true, STATE_NOT_FOUND, $objClass->eventMessages, null]);
} else {
$_msg = FAIL_EVENT . BROKER_REQUEST_DELETE;
$_aryRetData = buildReturnPayload([false, $objClass->state, $objClass->eventMessages, null]);
}
if (is_object($objClass)) $objClass->__destruct();
unset($objClass);
}
} catch (Throwable | TypeError $t) {
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __FILE__);
@handleExceptionMessaging($hdr, $t->getMessage(), $errors, true);
$_aryRetData = buildReturnPayload([false, STATE_FAIL, ERROR_EXCEPTION, null]);
}
return $rc;
}
}