X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=application%2Fhub%2Fmain%2Fnodes%2Fclass_BaseHubNode.php;h=1b052c5b909073397a5c4135d050f209078b1522;hb=02d2e489ecf43bd4386c2632fead7eea5dba0ad2;hp=9bea518358e7e77e2167153b4abbe12b02c3707b;hpb=65082b3aeb63f25506f90e021aa3fe75ba5f29ae;p=hub.git diff --git a/application/hub/main/nodes/class_BaseHubNode.php b/application/hub/main/nodes/class_BaseHubNode.php index 9bea51835..1b052c5b9 100644 --- a/application/hub/main/nodes/class_BaseHubNode.php +++ b/application/hub/main/nodes/class_BaseHubNode.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 BaseHubNode extends BaseHubSystem implements Updateable { +class BaseHubNode extends BaseHubSystem implements Updateable, AddableCriteria { /** * Node types */ @@ -55,17 +55,17 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * Whether this node is anncounced (KEEP ON false!) * @deprecated */ - private $hubIsAnnounced = false; + private $hubIsAnnounced = FALSE; /** * Whether this hub is active (default: false) */ - private $isActive = false; + private $isActive = FALSE; /** * Whether this node accepts announcements (default: false) */ - private $acceptAnnouncements = false; + private $acceptAnnouncements = FALSE; /** * Protected constructor @@ -77,6 +77,12 @@ class BaseHubNode extends BaseHubSystem implements Updateable { // Call parent constructor parent::__construct($className); + // Get a wrapper instance + $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName('node_info_db_wrapper_class'); + + // Set it here + $this->setWrapperInstance($wrapperInstance); + // Get a crypto instance $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class'); @@ -129,18 +135,18 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @return void */ private function generatePrivateKeyAndHash (LocalSearchCriteria $searchInstance) { + // Get an RNG instance + $rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class'); + // Generate a pseudo-random string - $randomString = $this->generateRandomString(255); + $randomString = $rngInstance->randomString(255); // Hash and encrypt the string so we become a node id (also documented as "hub id") $this->setPrivateKey($this->getCryptoInstance()->encryptString($randomString)); $this->setPrivateKeyHash($this->getCryptoInstance()->hashString($this->getPrivateKey())); - // Get a wrapper instance - $wrapperInstance = ObjectFactory::createObjectByConfiguredName('node_info_db_wrapper_class'); - // Register the node id with our wrapper - $wrapperInstance->registerPrivateKey($this, $this->getRequestInstance(), $searchInstance); + $this->getWrapperInstance()->registerPrivateKey($this, $this->getRequestInstance(), $searchInstance); // Output message self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Created new private key with hash: ' . $this->getPrivateKeyHash() . ''); @@ -201,7 +207,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { */ protected function ifAddressMatchesBootstrappingNodes ($remoteAddr) { // By default nothing is found - $isFound = false; + $isFound = FALSE; // Run through all configured IPs foreach (explode(BaseHubSystem::BOOTSTRAP_NODES_SEPARATOR, $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $ipPort) { @@ -211,7 +217,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { // Does it match? if ($ipPortArray[0] == $remoteAddr) { // Found it! - $isFound = true; + $isFound = TRUE; // Remember the port number $this->bootIpPort = $ipPort; @@ -226,7 +232,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * IP matches listen address. At this point we really don't care * if we can really listen on that address */ - $isFound = true; + $isFound = TRUE; // Remember the port number $this->bootIpPort = $ipPort; @@ -274,39 +280,25 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @return void */ public function bootstrapAcquireNodeId (Requestable $requestInstance, Responseable $responseInstance) { - // Get a wrapper instance - $wrapperInstance = ObjectFactory::createObjectByConfiguredName('node_info_db_wrapper_class'); - - // Now get a search criteria instance - $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); - - // Search for the node number one which is hard-coded the default - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1); - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $this->getRequestInstance()->getRequestElement('mode')); - $searchInstance->setLimit(1); - - // Get a result back - $resultInstance = $wrapperInstance->doSelectByCriteria($searchInstance); - - // Is it valid? - if ($resultInstance->next()) { - // Save the result instance in this class - $this->setResultInstance($resultInstance); - + // Is there a node id? + if ($this->getWrapperInstance()->ifNodeDataIsFound($this)) { // Get the node id from result and set it $this->setNodeId($this->getField(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID)); // Output message self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Re-using found node-id: ' . $this->getNodeId() . ''); } else { + // Get an RNG instance + $rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class'); + // Generate a pseudo-random string - $randomString = $this->generateRandomString(255); + $randomString = $rngInstance->randomString(255); // Hash and encrypt the string so we become a node id (also documented as "hub id") $this->setNodeId($this->getCryptoInstance()->hashString($this->getCryptoInstance()->encryptString($randomString))); // Register the node id with our wrapper - $wrapperInstance->registerNodeId($this, $this->getRequestInstance()); + $this->getWrapperInstance()->registerNodeId($this, $this->getRequestInstance()); // Output message self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Created new node-id: ' . $this->getNodeId() . ''); @@ -323,21 +315,22 @@ class BaseHubNode extends BaseHubSystem implements Updateable { $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); // Search for the node number one which is hard-coded the default - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1); - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $this->getRequestInstance()->getRequestElement('mode')); + $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR , 1); + $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE, $this->getRequestInstance()->getRequestElement('mode')); + $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID , $this->getNodeId()); $searchInstance->setLimit(1); + // Remember it for later usage + $this->setSearchInstance($searchInstance); + // Get a random string $randomString = $this->generateRamdomString(255); // Hash and encrypt the string so we become a "node id" aka Hub-Id $this->setSessionId($this->getCryptoInstance()->hashString($this->getCryptoInstance()->encryptString($randomString))); - // Get a wrapper instance - $wrapperInstance = ObjectFactory::createObjectByConfiguredName('node_info_db_wrapper_class'); - // Register the node id with our wrapper - $wrapperInstance->registerSessionId($this, $this->getRequestInstance(), $searchInstance); + $this->getWrapperInstance()->registerSessionId($this, $this->getRequestInstance(), $searchInstance); // Output message self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Created new session-id: ' . $this->getSessionId() . ''); @@ -352,25 +345,8 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @return void */ public function bootstrapGeneratePrivateKey () { - // Get a wrapper instance - $wrapperInstance = ObjectFactory::createObjectByConfiguredName('node_info_db_wrapper_class'); - - // Now get a search criteria instance - $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); - - // Search for the node number one which is hard-coded the default - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1); - $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $this->getRequestInstance()->getRequestElement('mode')); - $searchInstance->setLimit(1); - - // Get a result back - $resultInstance = $wrapperInstance->doSelectByCriteria($searchInstance); - // Is it valid? - if ($resultInstance->next()) { - // Save the result instance in this class - $this->setResultInstance($resultInstance); - + if ($this->getWrapperInstance()->ifNodeDataIsFound($this)) { // Is the element set? if (is_null($this->getField(NodeInformationDatabaseWrapper::DB_COLUMN_PRIVATE_KEY))) { /* @@ -378,7 +354,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * "tables". This allows a smooth update for the underlaying * database table. */ - $this->generatePrivateKeyAndHash($searchInstance); + $this->generatePrivateKeyAndHash($this->getSearchInstance()); } else { // Get the node id from result and set it $this->setPrivateKey(base64_decode($this->getField(NodeInformationDatabaseWrapper::DB_COLUMN_PRIVATE_KEY))); @@ -392,35 +368,10 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * Generate it in a private method (no confusion with 'private * method access' and 'private key' here! ;-)). */ - $this->generatePrivateKeyAndHash($searchInstance); + $this->generatePrivateKeyAndHash($this->getSearchInstance()); } } - /** - * Initializes queues which every node needs - * - * @return void - */ - protected function initGenericQueues () { - // Debug message - self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Initialize queues: START'); - - // Set the query connector instance - $this->setQueryConnectorInstance(ObjectFactory::createObjectByConfiguredName('query_connector_class', array($this))); - - // Run a test query - $this->getQueryConnectorInstance()->doTestQuery(); - - // Set the queue connector instance - $this->setQueueConnectorInstance(ObjectFactory::createObjectByConfiguredName('queue_connector_class', array($this))); - - // Run a test queue - $this->getQueueConnectorInstance()->doTestQueue(); - - // Debug message - self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Initialize queues: FINISHED'); - } - /** * Adds hub data elements to a given dataset instance * @@ -428,10 +379,13 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @param $requestInstance An instance of a Requestable class * @return void */ - public function addElementsToDataSet (StoreableCriteria $criteriaInstance, Requestable $requestInstance) { + public function addElementsToDataSet (StoreableCriteria $criteriaInstance, Requestable $requestInstance = NULL) { + // Make sure request instance is set as it is not optional + assert($requestInstance instanceof Requestable); + // Add node number and type - $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1); - $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $requestInstance->getRequestElement('mode')); + $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR , 1); + $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE, $requestInstance->getRequestElement('mode')); // Add the node id $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID, $this->getNodeId()); @@ -497,9 +451,9 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @throws NodeAlreadyAnnouncedException If this hub is already announced * @todo Change the first if() block to check for a specific state */ - public function announceSelfToUpperNodes (Taskable $taskInstance) { + public function announceToUpperNodes (Taskable $taskInstance) { // Is this hub node announced? - if ($this->hubIsAnnounced === true) { + if ($this->hubIsAnnounced === TRUE) { // Already announced! throw new NodeAlreadyAnnouncedException($this, self::EXCEPTION_HUB_ALREADY_ANNOUNCED); } // END - if @@ -508,7 +462,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { self::createDebugInstance(__CLASS__)->debugOutput('HUB-Announcement: START (taskInstance=' . $taskInstance->__toString(). ')'); // Get a helper instance - $helperInstance = ObjectFactory::createObjectByConfiguredName('hub_announcement_helper_class'); + $helperInstance = ObjectFactory::createObjectByConfiguredName('node_announcement_helper_class'); // Load the announcement descriptor $helperInstance->loadDescriptorXml($this); @@ -536,10 +490,10 @@ class BaseHubNode extends BaseHubSystem implements Updateable { */ public function doSelfConnection (Taskable $taskInstance) { // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')'); + self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')'); // Get a helper instance - $helperInstance = ObjectFactory::createObjectByConfiguredName('hub_self_connect_helper_class', array($this)); + $helperInstance = ObjectFactory::createObjectByConfiguredName('node_self_connect_helper_class', array($this)); // Load the descriptor (XML) file $helperInstance->loadDescriptorXml($this); @@ -551,7 +505,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { $helperInstance->sendPackage($this); // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Self Connection: FINISHED'); + self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: Self Connection: FINISHED'); } /** @@ -589,7 +543,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { */ public function initializeListenerPool () { // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Initialize listener: START'); + self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: Initialize listener: START'); // Get a new pool instance $this->setListenerPoolInstance(ObjectFactory::createObjectByConfiguredName('listener_pool_class', array($this))); @@ -604,13 +558,13 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * All nodes can now use the same configuration entry because it can be * customized in config-local.php. */ - $listenerInstance->setListenPortByConfiguration('node_tcp_listen_port'); + $listenerInstance->setListenPortByConfiguration('node_listen_port'); // Initialize the listener $listenerInstance->initListener(); // Get a decorator class - $decoratorInstance = ObjectFactory::createObjectByConfiguredName('hub_tcp_listener_class', array($listenerInstance)); + $decoratorInstance = ObjectFactory::createObjectByConfiguredName('node_tcp_listener_class', array($listenerInstance)); // Add this listener to the pool $this->getListenerPoolInstance()->addListener($decoratorInstance); @@ -631,13 +585,13 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * All nodes can now use the same configuration entry because it can be * customized in config-local.php. */ - $listenerInstance->setListenPortByConfiguration('node_udp_listen_port'); + $listenerInstance->setListenPortByConfiguration('node_listen_port'); // Initialize the listener $listenerInstance->initListener(); // Get a decorator class - $decoratorInstance = ObjectFactory::createObjectByConfiguredName('hub_udp_listener_class', array($listenerInstance)); + $decoratorInstance = ObjectFactory::createObjectByConfiguredName('node_udp_listener_class', array($listenerInstance)); // Add this listener to the pool $this->getListenerPoolInstance()->addListener($decoratorInstance); @@ -649,45 +603,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { $this->getListenerPoolInstance()->addListener($decoratorInstance); // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Initialize listener: FINISHED.'); - } - - /** - * Restores a previously stored node list from database - * - * @return void - */ - public function bootstrapRestoreNodeList () { - // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Restore node list: START'); - - // Get a wrapper instance - $wrapperInstance = ObjectFactory::createObjectByConfiguredName('node_list_db_wrapper_class'); - - // Now get a search criteria instance - $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); - - // Search for the node number zero which is hard-coded the default - // @TODO Add some criteria, e.g. if the node is active or so - //$searchInstance->addCriteria(NodeListDatabaseWrapper::DB_COLUMN_NODE_NR, 1); - //$searchInstance->addCriteria(NodeListDatabaseWrapper::DB_COLUMN_NODE_TYPE, $this->getRequestInstance()->getRequestElement('mode')); - //$searchInstance->setLimit(1); - - // Get a result back - $resultInstance = $wrapperInstance->doSelectByCriteria($searchInstance); - - // Is it valid? - if ($resultInstance->next()) { - $this->partialStub('Do something for restoring the list.'); - // Output message - //self::createDebugInstance(__CLASS__)->debugOutput('HUB: '); - } else { - // No previously saved node list found! - self::createDebugInstance(__CLASS__)->debugOutput('HUB: No previously saved node list found. This is fine.'); - } - - // Debug output - self::createDebugInstance(__CLASS__)->debugOutput('HUB: Restore node list: FINISHED.'); + self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: Initialize listener: FINISHED.'); } /** @@ -705,7 +621,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @param $isActive Whether the hub is active * @return void */ - public final function enableIsActive ($isActive = true) { + public final function enableIsActive ($isActive = TRUE) { $this->isActive = (bool) $isActive; } @@ -716,30 +632,50 @@ class BaseHubNode extends BaseHubSystem implements Updateable { */ public final function isAcceptingAnnouncements () { // Check it (this node must be active and not shutdown!) - $acceptAnnouncements = (($this->acceptAnnouncements === true) && ($this->isNodeActive())); + $acceptAnnouncements = (($this->acceptAnnouncements === TRUE) && ($this->isNodeActive())); // Return it return $acceptAnnouncements; } + /** + * Checks whether this node has attempted to announce itself + * + * @return $hasAnnounced Whether this node has attempted to announce itself + * @todo Add checking if this node has been announced to the sender node + */ + public function ifNodeHasAnnounced () { + // Debug message + /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: ifNodeHasAnnounced(): state=' . $this->getStateInstance()->getStateName()); + + // Simply check the state of this node + $hasAnnounced = ($this->getStateInstance() instanceof NodeAnnouncedState); + + // Debug message + /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: ifNodeHasAnnounced(): hasAnnounced=' . intval($hasAnnounced)); + + // Return it + return $hasAnnounced; + } + /** * Checks whether this node has attempted to announce itself and completed it * - * @return $hasAnnounced Whether this node has attempted to announce itself and completed it + * @return $hasAnnouncementCompleted Whether this node has attempted to announce itself and completed it * @todo Add checking if this node has been announced to the sender node */ public function ifNodeHasAnnouncementCompleted () { // Debug message - /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnouncementCompleted(): state=' . $this->getStateInstance()->getStateName()); + /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: ifNodeHasAnnouncementCompleted(): state=' . $this->getStateInstance()->getStateName()); // Simply check the state of this node - $hasAnnounced = ($this->getStateInstance() instanceof NodeAnnouncementCompletedState); + $hasAnnouncementCompleted = ($this->getStateInstance() instanceof NodeAnnouncementCompletedState); // Debug message - /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnouncementCompleted(): hasAnnounced=' . intval($hasAnnounced)); + /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __LINE__ . ']: ifNodeHasAnnouncementCompleted(): hasAnnouncementCompleted=' . intval($hasAnnouncementCompleted)); // Return it - return $hasAnnounced; + return $hasAnnouncementCompleted; } /** @@ -748,7 +684,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @param $acceptAnnouncements Whether this node accepts announcements (default: true) * @return void */ - protected final function enableAcceptingAnnouncements ($acceptAnnouncements = true) { + protected final function enableAcceptingAnnouncements ($acceptAnnouncements = TRUE) { $this->acceptAnnouncements = $acceptAnnouncements; } @@ -772,20 +708,29 @@ class BaseHubNode extends BaseHubSystem implements Updateable { /** * "Getter" for address:port combination * - * @param $handlerInstance An instance of a Networkable class - * @return $addressPort A address:port combination for this node + * @return $addressPort A address:port combination for this node */ - public final function getAddressPort (Networkable $handlerInstance) { - // Construct config entry - $configEntry = 'node_' . $handlerInstance->getHandlerName() . '_listen_port'; - + public final function getAddressPort () { // Get IP and port - $addressPort = $this->getConfigInstance()->detectServerAddress() . ':' . $this->getConfigInstance()->getConfigEntry($configEntry); + $addressPort = $this->getConfigInstance()->detectServerAddress() . ':' . $this->getConfigInstance()->getConfigEntry('node_listen_port'); // Return it return $addressPort; } + /** + * "Getter" for address:port array + * + * @return $addressPortArray An array of a address:port combination for this node + */ + public final function getAddressPortArray () { + // Get IP and port + $addressPortArray = explode(':', $this->getAddressPort()); + + // Return it + return $addressPortArray; + } + /** * Updates/refreshes node data (e.g. status). * @@ -806,8 +751,11 @@ class BaseHubNode extends BaseHubSystem implements Updateable { * @todo Handle thrown exception */ public function handleAnswerStatusByMessageData (array $messageData, Receivable $packageInstance) { + // Is it not empty? + assert(!empty($messageData[BaseXmlAnswerTemplateEngine::ANSWER_STATUS])); + // Construct configuration entry for handling class' name - $classConfigEntry = strtolower($messageData[NetworkPackage::MESSAGE_ARRAY_TYPE] . '_status_' . $messageData[XmlAnnouncementAnswerTemplateEngine::ANNOUNCEMENT_DATA_ANSWER_STATUS]) . '_handler_class'; + $classConfigEntry = strtolower($messageData[NetworkPackage::MESSAGE_ARRAY_TYPE] . '_status_' . $messageData[BaseXmlAnswerTemplateEngine::ANSWER_STATUS]) . '_handler_class'; // Try to get a class $handlerInstance = ObjectFactory::createObjectByConfiguredName($classConfigEntry);