X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=application%2Fhub%2Fmain%2Fdatabase%2Fwrapper%2Fnode%2Fclass_NodeDistributedHashTableDatabaseWrapper.php;h=0beb31c0d3f02e1f81520bb205ab4824279a1b51;hb=7756c313e101f012af9c3ccfc378308f4f03f603;hp=d880df4b8453e8fa0bb53a81af7b381b30b982f9;hpb=add563cf751bbff3bbd4dd00daf04ecf995f921e;p=hub.git diff --git a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php index d880df4b8..0beb31c0d 100644 --- a/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php +++ b/application/hub/main/database/wrapper/node/class_NodeDistributedHashTableDatabaseWrapper.php @@ -28,10 +28,17 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Constants for database column names const DB_COLUMN_NODE_ID = 'node_id'; const DB_COLUMN_SESSION_ID = 'session_id'; - const DB_COLUMN_IP_PORT = 'ip_port'; + const DB_COLUMN_EXTERNAL_IP = 'external_ip'; + const DB_COLUMN_LISTEN_PORT = 'listen_port'; const DB_COLUMN_PRIVATE_KEY = 'private_key'; const DB_COLUMN_PRIVATE_KEY_HASH = 'private_key_hash'; - const DB_COLUMN_NODE_TYPE = 'node_type'; + const DB_COLUMN_NODE_MODE = 'node_mode'; + const DB_COLUMN_ACCEPTED_OBJECTS = 'accepted_object_types'; + const DB_COLUMN_NODE_LIST = 'node_list'; + + // Exception codes + const EXCEPTION_NODE_ALREADY_REGISTERED = 0x800; + const EXCEPTION_NODE_NOT_REGISTERED = 0x801; /** * Protected constructor @@ -77,12 +84,26 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Set the primary key $dataSetInstance->setUniqueKey(self::DB_COLUMN_NODE_ID); + // Get ip:port combination and "explode" it + $ipPort = $nodeInstance->getAddressPortArray(); + + // Make sure both is valid + assert(($ipPort[0] !== 'invalid') && ($ipPort[1] !== 'invalid')); + + // Get an array of all accepted object types + $objectList = $nodeInstance->getListFromAcceptedObjectTypes(); + + // Make sure this is an array + assert(is_array($objectList)); + // Add public node data - $dataSetInstance->addCriteria(self::DB_COLUMN_NODE_TYPE , $requestInstance->getRequestElement('mode')); - $dataSetInstance->addCriteria(self::DB_COLUMN_IP_PORT , $nodeInstance->getAddressPort()); + $dataSetInstance->addCriteria(self::DB_COLUMN_NODE_MODE , $requestInstance->getRequestElement('mode')); + $dataSetInstance->addCriteria(self::DB_COLUMN_EXTERNAL_IP , $ipPort[0]); + $dataSetInstance->addCriteria(self::DB_COLUMN_LISTEN_PORT , $ipPort[1]); $dataSetInstance->addCriteria(self::DB_COLUMN_NODE_ID , $nodeInstance->getNodeId()); $dataSetInstance->addCriteria(self::DB_COLUMN_SESSION_ID , $nodeInstance->getSessionId()); $dataSetInstance->addCriteria(self::DB_COLUMN_PRIVATE_KEY_HASH, $nodeInstance->getPrivateKeyHash()); + $dataSetInstance->addCriteria(self::DB_COLUMN_ACCEPTED_OBJECTS, implode(BaseHubNode::OBJECT_LIST_SEPARATOR, $objectList)); // Return it return $dataSetInstance; @@ -103,15 +124,26 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Get node instance $nodeInstance = Registry::getRegistry()->getInstance('node'); - // Add ip:port as criteria - $searchInstance->addCriteria(self::DB_COLUMN_IP_PORT, $nodeInstance->getAddressPort()); + // Get ip:port combination and "explode" it + $ipPort = $nodeInstance->getAddressPortArray(); + + /* + * Make sure both is not 'invalid' which means that the resolver + * didn't work. + */ + assert(($ipPort[0] !== 'invalid') && ($ipPort[1] !== 'invalid')); + + // Add ip:port/node id as criteria + $searchInstance->addCriteria(self::DB_COLUMN_EXTERNAL_IP, $ipPort[0]); + $searchInstance->addCriteria(self::DB_COLUMN_LISTEN_PORT, $ipPort[1]); + $searchInstance->addCriteria(self::DB_COLUMN_NODE_ID , $nodeInstance->getNodeId()); $searchInstance->setLimit(1); // Query database and get a result instance back $resultInstance = $this->doSelectByCriteria($searchInstance); - // Cache result of if there is an entry, next() will tell us if the next entry is valid - $GLOBALS[__METHOD__] = $resultInstance->next(); + // Cache result of if there is an entry, valid() will tell us if an entry is there + $GLOBALS[__METHOD__] = $resultInstance->valid(); } // END - if // Return result @@ -165,12 +197,12 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem } /** - * Finds a node by given session id + * Finds a node locally by given session id * * @param $sessionId Session id to lookup * @return $nodeData Node data array */ - public function findNodeBySessionId ($sessionId) { + public function findNodeLocalBySessionId ($sessionId) { // Get search criteria $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); @@ -202,6 +234,9 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Add all array elements $handlerInstance->addArrayToDataSet($dataSetInstance, $messageData); + // Remove 'node_list' + $dataSetInstance->unsetCriteria(self::DB_COLUMN_NODE_LIST); + // Run the "INSERT" query $this->queryInsertDataSet($dataSetInstance); } @@ -227,9 +262,75 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem // Add all array elements $handlerInstance->addArrayToDataSet($dataSetInstance, $messageData); + // Remove 'node_list' + $dataSetInstance->unsetCriteria(self::DB_COLUMN_NODE_LIST); + // Run the "UPDATE" query $this->queryUpdateDataSet($dataSetInstance); } + + /** + * Determines whether the given node data is already inserted in the DHT + * + * @param $nodeData An array with valid node data + * @return $isRegistered Whether the given node data is already inserted + */ + public function isNodeRegistered (array $nodeData) { + // Get search criteria + $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); + + // Search for node id and limit it to one entry + $searchInstance->addCriteria(self::DB_COLUMN_NODE_ID, $nodeData[self::DB_COLUMN_NODE_ID]); + $searchInstance->setLimit(1); + + // Query database and get a result instance back + $resultInstance = $this->doSelectByCriteria($searchInstance); + + // Check if there is an entry + $isRegistered = $resultInstance->valid(); + + // Return registration status + return $isRegistered; + } + + /** + * Registers a node with given data in the DHT. If the node is already + * registered this method shall throw an exception. + * + * @param $nodeData An array with valid node data + * @return void + * @throws NodeAlreadyRegisteredException If the node is already registered + */ + public function registerNode (array $nodeData) { + // Is the node registered? + if ($this->isNodeRegistered($nodeData)) { + // Throw an exception + throw new NodeAlreadyRegisteredException(array($this, $nodeData), self::EXCEPTION_NODE_ALREADY_REGISTERED); + } // END - if + + // @TODO Unimplemented part + $this->partialStub('nodeData=' . print_r($nodeData, TRUE)); + } + + /** + * Updates a node's entry in the DHT with given data. This will enrich or + * just update already exsiting data. If the node is not found this method + * shall throw an exception. + * + * @param $nodeData An array with valid node data + * @return void + * @throws NodeDataMissingException If the node's data is missing + */ + public function updateNode (array $nodeData) { + // Is the node registered? + if (!$this->isNodeRegistered($nodeData)) { + // No, then throw an exception + throw new NodeDataMissingException(array($this, $nodeData), self::EXCEPTION_NODE_NOT_REGISTERED); + } // END - if + + // @TODO Unimplemented part + $this->partialStub('nodeData=' . print_r($nodeData, TRUE)); + } } // [EOF]