From 648565252fab14cc7cfd40b536d7ba1d833e19d7 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Tue, 18 Mar 2014 23:46:41 +0100 Subject: [PATCH] Continued with DHT stuff: - added a very generic way to query the local DHT for key/value matches - used this way to look for DHT nodes accepting bootstrap requests. - renamed method DhtObjectFactory::createDhtObjectInstance to createDhtInstance to match with its getter/setter mates. Signed-off-by: Roland Haeder --- .../distributable/class_Distributable.php | 9 +++ .../wrapper/class_NodeDhtWrapper.php | 10 +++ ...odeDistributedHashTableDatabaseWrapper.php | 32 ++++++++++ application/hub/main/dht/class_BaseDht.php | 5 +- .../hub/main/dht/node/class_NodeDhtFacade.php | 61 ++++++++++++++++--- .../dht/class_DhtRecipientDiscovery.php | 2 +- .../factories/dht/class_DhtObjectFactory.php | 2 +- .../main/handler/class_BaseDataHandler.php | 2 +- ...s_NodeMessageDhtBootstrapAnswerHandler.php | 2 +- .../class_NodeMessageDhtBootstrapHandler.php | 20 ++++++ .../node/dht/class_NodeDhtBootstrapTask.php | 2 +- .../dht/class_NodeDhtInitializationTask.php | 2 +- .../dht/class_NodeDhtPublicationCheckTask.php | 2 +- .../node/dht/class_NodeDhtPublicationTask.php | 2 +- .../tasks/node/dht/class_NodeDhtQueryTask.php | 2 +- application/hub/main/tools/class_HubTools.php | 2 +- 16 files changed, 135 insertions(+), 22 deletions(-) diff --git a/application/hub/interfaces/distributable/class_Distributable.php b/application/hub/interfaces/distributable/class_Distributable.php index 8adbc8d64..0743d683e 100644 --- a/application/hub/interfaces/distributable/class_Distributable.php +++ b/application/hub/interfaces/distributable/class_Distributable.php @@ -97,6 +97,15 @@ interface Distributable extends FrameworkInterface { * @return $isBooting Whether this DHT is currently booting */ function ifDhtIsBooting (); + + /** + * Finds DHT recipients by given key/value pair + * + * @param $key Key to search for + * @param $value Value to check on found key + * @return $recipientList Array with DHT recipients from given key/value pair + */ + function findRecipientsByKey ($key, $value); } // [EOF] diff --git a/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php b/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php index 938a3189f..b962cc9de 100644 --- a/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php +++ b/application/hub/interfaces/wrapper/class_NodeDhtWrapper.php @@ -148,6 +148,16 @@ interface NodeDhtWrapper extends DatabaseWrapper { * @return $recipients An indexed array with DHT recipients */ function getResultFromExcludedSender (array $packageData); + + /** + * Find recopients by given key/value pair. First look for the key and if it + * matches, compare the value. + * + * @param $key Key to look for + * @param $value Value to compare if key matches + * @return $recipients An indexed array with DHT recipients + */ + function getResultFromKeyValue ($key, $value); } // [EOF] diff --git a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php index 8c3a8a5e3..08c8a7716 100644 --- a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php +++ b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php @@ -41,6 +41,7 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem const DB_COLUMN_NODE_LIST = 'node_list'; const DB_COLUMN_PUBLICATION_STATUS = 'publication_status'; const DB_COLUMN_ANSWER_STATUS = 'answer_status'; + const DB_COLUMN_ACCEPT_BOOTSTRAP = 'accept_bootstrap'; // Publication status' const PUBLICATION_STATUS_PENDING = 'PENDING'; @@ -519,12 +520,43 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Assert on required array field assert(isset($packageData[NetworkPackage::PACKAGE_DATA_SENDER])); + // Get max recipients + $maxRecipients = $this->getConfigInstance()->getConfigEntry('max_dht_recipients'); + // First creata a search instance $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); // Then exclude 'sender' field as the sender is the current (*this*) node $searchInstance->addExcludeCriteria(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER]); + // Set limit to maximum DHT recipients + $searchInstance->setLimit($maxRecipients); + + // Get a result instance back from DHT database wrapper. + $resultInstance = $this->doSelectByCriteria($searchInstance); + + // Return result instance + return $resultInstance; + } + + /** + * Find recopients by given key/value pair. First look for the key and if it + * matches, compare the value. + * + * @param $key Key to look for + * @param $value Value to compare if key matches + * @return $recipients An indexed array with DHT recipients + */ + public function getResultFromKeyValue ($key, $value) { + // Get max recipients + $maxRecipients = $this->getConfigInstance()->getConfigEntry('max_dht_recipients'); + + // First creata a search instance + $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); + + // Find the key/value pair + $searchInstance->addCriteria($key, $value); + // Get a result instance back from DHT database wrapper. $resultInstance = $this->doSelectByCriteria($searchInstance); diff --git a/application/hub/main/dht/class_BaseDht.php b/application/hub/main/dht/class_BaseDht.php index d81cbcd29..7a667811a 100644 --- a/application/hub/main/dht/class_BaseDht.php +++ b/application/hub/main/dht/class_BaseDht.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -abstract class BaseDht extends BaseHubSystem { +abstract class BaseDht extends BaseHubSystem implements Distributable { /** * "Cached" instance of a publish helper */ @@ -150,7 +150,8 @@ abstract class BaseDht extends BaseHubSystem { // Get result instance $resultInstance = $this->getWrapperInstance()->getUnpublishedEntriesInstance(); - // Must still be valid + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); assert($resultInstance->valid()); // "Walk" through all entries diff --git a/application/hub/main/dht/node/class_NodeDhtFacade.php b/application/hub/main/dht/node/class_NodeDhtFacade.php index a80a36259..a3d1524b8 100644 --- a/application/hub/main/dht/node/class_NodeDhtFacade.php +++ b/application/hub/main/dht/node/class_NodeDhtFacade.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class NodeDhtFacade extends BaseDht implements Distributable, Registerable { +class NodeDhtFacade extends BaseDht implements DistributableNode, Registerable { /** * Protected constructor * @@ -137,6 +137,10 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { */ $resultInstance = $this->getWrapperInstance()->findNodeLocalBySessionId($sessionId); + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); + assert($resultInstance->valid()); + // Is the next entry valid? if (($resultInstance->valid()) && ($resultInstance->next())) { /* @@ -192,6 +196,10 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { // Run the query $resultInstance = $this->getWrapperInstance()->doSelectByCriteria($searchInstance); + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); + assert($resultInstance->valid()); + // Is there already an entry? if ($resultInstance->valid()) { // Entry found, so update it @@ -251,8 +259,14 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { // Run the query $resultInstance = $this->getWrapperInstance()->doSelectByCriteria($searchInstance); - // Get node list + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); + assert($resultInstance->valid()); + + // Init array $nodeList = array(); + + // Get node list while ($resultInstance->next()) { // Get current element (it should be an array, and have at least 1 entry) $current = $resultInstance->current(); @@ -310,12 +324,13 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { * @return $recipients An indexed array with DHT recipients */ public function findRecipientsByPackageData (array $packageData) { - // Get max recipients - $maxRecipients = $this->getConfigInstance()->getConfigEntry('max_dht_recipients'); - // Query get a result instance back from DHT database wrapper. $resultInstance = $this->getWrapperInstance()->getResultFromExcludedSender($packageData); + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); + assert($resultInstance->valid()); + // Init array $recipients = array(); @@ -327,12 +342,38 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable { // Add instance to recipient list array_push($recipients, $current); + } // END - while - // Has the maximum been reached? - if (count($recipients) == $maxRecipients) { - // Stop search here - break; - } // END - if + // Return filled array + return $recipients; + } + + /** + * Finds DHT recipients by given key/value pair + * + * @param $key Key to search for + * @param $value Value to check on found key + * @return $recipiens Array with DHT recipients from given key/value pair + */ + public function findRecipientsByKey ($key, $value) { + // Look for all suitable nodes + $resultInstance = $this->getWrapperInstance()->getResultFromKeyValue($key, $value); + + // Make sure the result instance is valid + assert($resultInstance instanceof SearchableResult); + assert($resultInstance->valid()); + + // Init array + $recipients = array(); + + // "Walk" through all entries + while ($resultInstance->next()) { + // Get current entry + $current = $resultInstance->current(); + } // END - while + + // Add instance to recipient list + array_push($recipients, $current); } // END - while // Return filled array diff --git a/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php b/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php index f9c2a4630..35809b67f 100644 --- a/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php +++ b/application/hub/main/discovery/dht/class_DhtRecipientDiscovery.php @@ -42,7 +42,7 @@ class DhtRecipientDiscovery extends BaseNodeDiscovery implements DiscoverableDht $discoveryInstance = new DhtRecipientDiscovery(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set it here $discoveryInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/factories/dht/class_DhtObjectFactory.php b/application/hub/main/factories/dht/class_DhtObjectFactory.php index 4c7ff621f..11f35a8bb 100644 --- a/application/hub/main/factories/dht/class_DhtObjectFactory.php +++ b/application/hub/main/factories/dht/class_DhtObjectFactory.php @@ -38,7 +38,7 @@ class DhtObjectFactory extends ObjectFactory { * @param $prefix Prefix for DHT class name and registry key * @return $dhtInstance An instance of a DHT object class */ - public static final function createDhtObjectInstance ($prefix) { + public static final function createDhtInstance ($prefix) { // Set instance name $name = $prefix . '_dht'; diff --git a/application/hub/main/handler/class_BaseDataHandler.php b/application/hub/main/handler/class_BaseDataHandler.php index 902c66783..8af671281 100644 --- a/application/hub/main/handler/class_BaseDataHandler.php +++ b/application/hub/main/handler/class_BaseDataHandler.php @@ -59,7 +59,7 @@ abstract class BaseDataHandler extends BaseHandler { parent::__construct($className); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set it here $this->setDhtInstance($dhtInstance); diff --git a/application/hub/main/handler/message-types/answer/class_NodeMessageDhtBootstrapAnswerHandler.php b/application/hub/main/handler/message-types/answer/class_NodeMessageDhtBootstrapAnswerHandler.php index 23fc0f5f7..cf4fa42c9 100644 --- a/application/hub/main/handler/message-types/answer/class_NodeMessageDhtBootstrapAnswerHandler.php +++ b/application/hub/main/handler/message-types/answer/class_NodeMessageDhtBootstrapAnswerHandler.php @@ -94,7 +94,7 @@ class NodeMessageDhtBootstrapAnswerHandler extends BaseMessageHandler implements */ public function handleMessageData (array $messageData, Receivable $packageInstance) { // Get DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Has this DHT attempted to bootstrap? if (!$dhtInstance->ifDhtIsBooting()) { diff --git a/application/hub/main/handler/message-types/dht/class_NodeMessageDhtBootstrapHandler.php b/application/hub/main/handler/message-types/dht/class_NodeMessageDhtBootstrapHandler.php index 5356cb6a4..e6344ca18 100644 --- a/application/hub/main/handler/message-types/dht/class_NodeMessageDhtBootstrapHandler.php +++ b/application/hub/main/handler/message-types/dht/class_NodeMessageDhtBootstrapHandler.php @@ -82,6 +82,12 @@ class NodeMessageDhtBootstrapHandler extends BaseMessageHandler implements Handl // ... and set it here $handlerInstance->setNodeInstance($nodeInstance); + // Get a DHT instance + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); + + // Set the DHT instance here + $handlerInstance->setDhtInstance($dhtInstance); + // Return the prepared instance return $handlerInstance; } @@ -164,6 +170,20 @@ class NodeMessageDhtBootstrapHandler extends BaseMessageHandler implements Handl // Set it in configuration (temporarily) $this->getConfigInstance()->setConfigEntry(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_ANSWER_STATUS, $statusCode); + + /* + * Use the DHT instance to get a list of recipients. This means that all + * DHT nodes that accept bootstrap requests are read from the DHT + * database. + */ + $nodeList = $this->getDhtInstance()->findRecipientsByKey(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_ACCEPT_BOOTSTRAP, 'Y'); + + // Make sure it is an array and has at least one entry + assert(is_array($nodeList)); + assert(count($nodeList) > 0); + + // Set it in configuration + $this->getConfigInstance()->setConfigEntry('dht_nodes', base64_encode(serialize($nodeList))); } /** diff --git a/application/hub/main/tasks/node/dht/class_NodeDhtBootstrapTask.php b/application/hub/main/tasks/node/dht/class_NodeDhtBootstrapTask.php index b4614ab6d..73dedd4d4 100644 --- a/application/hub/main/tasks/node/dht/class_NodeDhtBootstrapTask.php +++ b/application/hub/main/tasks/node/dht/class_NodeDhtBootstrapTask.php @@ -42,7 +42,7 @@ class NodeDhtBootstrapTask extends BaseTask implements Taskable, Visitable { $taskInstance = new NodeDhtBootstrapTask(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set the DHT instance here $taskInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/tasks/node/dht/class_NodeDhtInitializationTask.php b/application/hub/main/tasks/node/dht/class_NodeDhtInitializationTask.php index 25f341491..7daf57841 100644 --- a/application/hub/main/tasks/node/dht/class_NodeDhtInitializationTask.php +++ b/application/hub/main/tasks/node/dht/class_NodeDhtInitializationTask.php @@ -42,7 +42,7 @@ class NodeDhtInitializationTask extends BaseTask implements Taskable, Visitable $taskInstance = new NodeDhtInitializationTask(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set the DHT instance here $taskInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/tasks/node/dht/class_NodeDhtPublicationCheckTask.php b/application/hub/main/tasks/node/dht/class_NodeDhtPublicationCheckTask.php index 7037e08ce..cfa8b4753 100644 --- a/application/hub/main/tasks/node/dht/class_NodeDhtPublicationCheckTask.php +++ b/application/hub/main/tasks/node/dht/class_NodeDhtPublicationCheckTask.php @@ -42,7 +42,7 @@ class NodeDhtPublicationCheckTask extends BaseTask implements Taskable, Visitabl $taskInstance = new NodeDhtPublicationCheckTask(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set the DHT instance here $taskInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/tasks/node/dht/class_NodeDhtPublicationTask.php b/application/hub/main/tasks/node/dht/class_NodeDhtPublicationTask.php index 437b050d8..d44862395 100644 --- a/application/hub/main/tasks/node/dht/class_NodeDhtPublicationTask.php +++ b/application/hub/main/tasks/node/dht/class_NodeDhtPublicationTask.php @@ -42,7 +42,7 @@ class NodeDhtPublicationTask extends BaseTask implements Taskable, Visitable { $taskInstance = new NodeDhtPublicationTask(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set the DHT instance here $taskInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/tasks/node/dht/class_NodeDhtQueryTask.php b/application/hub/main/tasks/node/dht/class_NodeDhtQueryTask.php index f8daa16d3..55576e718 100644 --- a/application/hub/main/tasks/node/dht/class_NodeDhtQueryTask.php +++ b/application/hub/main/tasks/node/dht/class_NodeDhtQueryTask.php @@ -42,7 +42,7 @@ class NodeDhtQueryTask extends BaseTask implements Taskable, Visitable { $taskInstance = new NodeDhtQueryTask(); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set the DHT instance here $taskInstance->setDhtInstance($dhtInstance); diff --git a/application/hub/main/tools/class_HubTools.php b/application/hub/main/tools/class_HubTools.php index 122ce3a18..d59db6654 100644 --- a/application/hub/main/tools/class_HubTools.php +++ b/application/hub/main/tools/class_HubTools.php @@ -51,7 +51,7 @@ class HubTools extends BaseHubSystem { parent::__construct(__CLASS__); // Get a DHT instance - $dhtInstance = DhtObjectFactory::createDhtObjectInstance('node'); + $dhtInstance = DhtObjectFactory::createDhtInstance('node'); // Set it here $this->setDhtInstance($dhtInstance); -- 2.39.5