]> git.mxchange.org Git - hub.git/blobdiff - application/hub/main/dht/node/class_NodeDhtFacade.php
DHT data registration/update added to NodeDhtFacade, now every DHT facade must implem...
[hub.git] / application / hub / main / dht / node / class_NodeDhtFacade.php
index 49434e1035f34c43ae2da27dcf7bedd8cdd13199..23e3abfe13596c28d52146fd1e08a15d93c9bd9a 100644 (file)
@@ -51,11 +51,37 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                return $dhtInstance;
        }
 
+       /**
+        * Registers/updates an entry in the DHT with given data from $dhtData
+        * array. Different DHT implemtations may handle this differently as they
+        * may enrich the data with more meta data.
+        *
+        * @param       $dhtData        A valid array with DHT-related data (e.g. node/peer data)
+        * @return      void
+        * @todo        Does the data need to be enriched?
+        */
+       protected function insertDataIntoDht (array $dhtData) {
+               // Check if there is already an entry for given node_id
+               if ($this->getWrapperInstance()->isNodeRegisteredByNodeId($dhtData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_NODE_ID])) {
+                       /*
+                        * Update existing record. Please note that this step is not secure
+                        * (e.g. DHT poisoning) it would be good to implement some checks if
+                        * the both node owner trust each other (see sub-project 'DSHT').
+                        */
+                       $this->getWrapperInstance()->updateNodeEntry($nodeData);
+               } else {
+                       /*
+                        * Inserts given node data into the DHT. As above, this step does
+                        * currently not perform any security checks.
+                        */
+                       $this->getWrapperInstance()->registerNodeByData($nodeData);
+               }
+       }
+
        /**
         * Initializes the distributed hash table (DHT)
         *
         * @return      void
-        * @todo        Please implement this method
         */
        public function initDht () {
                // Is the local node registered?
@@ -66,24 +92,57 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                        // No, so register it
                        $this->getWrapperInstance()->registerLocalNode();
                }
+
+               // Change state
+               $this->getStateInstance()->dhtHasInitialized();
+       }
+
+       /**
+        * Bootstraps the DHT by sending out a message to all available nodes
+        * (including itself). This step helps the node to get to know more nodes
+        * which can be queried later for object distribution.
+        *
+        * @return      void
+        */
+       public function bootstrapDht () {
+               // Get a helper instance
+               $helperInstance = ObjectFactory::createObjectByConfiguredName('dht_bootstrap_helper_class');
+
+               // Load the announcement descriptor
+               $helperInstance->loadDescriptorXml($this);
+
+               // Compile all variables
+               $helperInstance->getTemplateInstance()->compileConfigInVariables();
+
+               // "Publish" the descriptor by sending it to the bootstrap/list nodes
+               $helperInstance->sendPackage($this);
+
+               // Change state
+               $this->getStateInstance()->dhtHasBooted();
        }
 
        /**
         * Finds a node locally by given session id
         *
         * @param       $sessionId      Session id to lookup
-        * @return      $nodeData       Node data array
+        * @return      $nodeData       Node-data array
         */
        public function findNodeLocalBySessionId ($sessionId) {
                // Default is empty data array
                $nodeData = array();
 
-               // Call the wrapper to do the job and get back a result instance
+               /*
+                * Call the wrapper to do the job and get back a result instance. There
+                * will come back zero or one entry from the wrapper.
+                */
                $resultInstance = $this->getWrapperInstance()->findNodeLocalBySessionId($sessionId);
 
                // Is the next entry valid?
                if ($resultInstance->next()) {
-                       // Then load the entry
+                       /*
+                        * Then load the first entry (more entries are being ignored and
+                        * should not happen).
+                        */
                        $nodeData = $resultInstance->current();
                } // END - if
 
@@ -110,16 +169,19 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
 
                // Debug message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE: messageData=' . print_r($messageData, true));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: state=' . $this->getPrintableState() . ',messageData=' . print_r($messageData, true) . ',handlerInstance=' . $handlerInstance->__toString() . ',forceUpdate=' . intval($forceUpdate) . ',count(getSearchData())=' . count($handlerInstance->getSearchData()));
 
                // Search for the node's session id and external IP/hostname + TCP/UDP listen port
                foreach ($handlerInstance->getSearchData() as $key) {
                        // Debug message
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE: messageData[' . $key . ']=' . $messageData[$key]);
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: state=' . $this->getPrintableState() . ',key=' . $key);
 
                        // Is it there?
                        assert(isset($messageData[$key]));
 
+                       // Debug message
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: state=' . $this->getPrintableState() . ',messageData[' . $key . ']=' . $messageData[$key]);
+
                        // Add criteria
                        $searchInstance->addCriteria(str_replace('my-', '', $key), $messageData[$key]);
                } // END - foreach
@@ -166,7 +228,7 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                assert((isset($messageData[$excludeKey])) && (isset($messageData[$andKey])));
 
                // Debug message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADEmessageData=' . print_r($messageData, true));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: state=' . $this->getPrintableState() . ',messageData=' . print_r($messageData, true));
 
                // Get a search criteria class
                $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
@@ -174,7 +236,7 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                // Add all keys
                foreach (explode($separator, $messageData[$andKey]) as $criteria) {
                        // Debug message
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE: andKey=' . $andKey . ',criteria=' . $criteria);
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: andKey=' . $andKey . ',criteria=' . $criteria);
 
                        // Add it and leave any 'my-' prefix out
                        $searchInstance->addChoiceCriteria(str_replace('my-', '', $andKey), $criteria);
@@ -192,8 +254,21 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                // Get node list
                $nodeList = array();
                while ($resultInstance->next()) {
+                       // Get current element (it should be an array, and have at least 1 entry)
+                       $current = $resultInstance->current();
+                       assert(is_array($current));
+                       assert(count($current) > 0);
+
+                       // Debug message
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: current(' . count($current) . ')[' . gettype($current) . ']=' . print_r($current, TRUE));
+
+                       /*
+                        * Remove some keys as they should not be published.
+                        */
+                       unset($current[$this->getWrapperInstance()->getIndexKey()]);
+
                        // Add this entry
-                       array_push($nodeList, $resultInstance->current());
+                       array_push($nodeList, $current);
                } // END - while
 
                // Save last exception
@@ -202,6 +277,31 @@ class NodeDhtFacade extends BaseDht implements Distributable, Registerable {
                // Return node list (array)
                return $nodeList;
        }
+
+       /**
+        * Inserts given node list array (from earlier database result produced by
+        * an other node) into the DHT. This array origins from above method
+        * queryLocalNodeListExceptByMessageData().
+        *
+        * @param       $nodeList       An array from an earlier database result instance
+        * @return      void
+        */
+       public function insertNodeList (array $nodeList) {
+               // If no node is in the list (array), skip the rest of this method
+               if (count($nodeList) == 0) {
+                       // Debug message
+                       self::createDebugInstance(__CLASS__)->debugOutput('DHT-FACADE[' . __LINE__ . ']: No node record has been returned.');
+
+                       // Abort here
+                       return;
+               } // END - if
+
+               // Put them all into a stack
+               foreach ($nodeList as $nodeData) {
+                       // Insert all entries
+                       $this->getStackerInstance()->pushNamed(self::STACKER_NAME_INSERT_NODE, $nodeData);
+               } // END - foreach
+       }
 }
 
 // [EOF]