// CFG: DHT-BOOTSTRAP-HELPER-CLASS
$cfg->setConfigEntry('dht_bootstrap_helper_class', 'DhtBootstrapHelper');
+// CFG: DHT-PUBLISH-ENTRY-HELPER-CLASS
+$cfg->setConfigEntry('dht_publish_entry_helper_class', 'DhtPublishEntryHelper');
+
// CFG: DEFAULT-CONSOLE-COMMAND
$cfg->setConfigEntry('default_console_command', 'main');
// CFG: DHT-BOOTSTRAP-TEMPLATE-CLASS
$cfg->setConfigEntry('dht_bootstrap_template_class', 'XmlDhtBootstrapTemplateEngine');
+// CFG: DHT-PUBLISH-ENTRY-TEMPLATE-CLASS
+$cfg->setConfigEntry('dht_publish_entry_template_class', 'XmlDhtPublishEntryTemplateEngine');
+
// CFG: NODE-MESSAGE-TEMPLATE-EXTENSION
$cfg->setConfigEntry('node_message_template_extension', '.xml');
// CFG: DHT-BOOTSTRAP-TEMPLATE-TYPE
$cfg->setConfigEntry('dht_bootstrap_template_type', 'xml/dht_bootstrap');
+// CFG: DHT-PUBLISH-TEMPLATE-TYPE
+$cfg->setConfigEntry('dht_publish_template_type', 'xml/dht_publish');
+
// CFG: CODE-TEMPLATE-TYPE
$cfg->setConfigEntry('code_template_type', 'xml');
// CFG: DHT-BOOTSTRAP-STACKER-CLASS
$cfg->setConfigEntry('dht_bootstrap_stacker_class', 'FiFoStacker');
+// CFG: DHT-PUBLISH-STACKER-CLASS
+$cfg->setConfigEntry('dht_publish_stacker_class', 'FiFoStacker');
+
// CFG: PRODUCER-OUTGOING-QUEUE
$cfg->setConfigEntry('producer_outgoing_queue', 'FiFoStacker');
// CFG: STACKER-DHT-BOOTSTRAP-MAX-SIZE
$cfg->setConfigEntry('stacker_dht_bootstrap_max_size', 10);
+// CFG: STACKER-DHT-PUBLISH-MAX-SIZE
+$cfg->setConfigEntry('stacker_dht_publish_max_size', 10);
+
// CFG: STACKER-DHT-INSERT-NODE-MAX-SIZE
$cfg->setConfigEntry('stacker_dht_insert_node_max_size', 100);
/**
* Loads the descriptor XML file
*
+ * @param $dhtInstance An instance of a Distributable class
* @return void
*/
- function loadDescriptorXml ();
+ function loadDescriptorXml (Distributable $dhtInstance);
/**
* Send a package out
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
abstract class BaseDht extends BaseHubSystem {
+ /**
+ * "Cached" instance of a publish helper
+ */
+ private $publishHelperInstance = NULL;
+
/**
* Stacker name for "INSERT" node data
*/
$isPending = ($this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_PENDING_PUBLISHING) === FALSE);
// Return status
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] isPending=' . intval($isPending));
return $isPending;
}
* corresponding dabase entry.
*
* @return void
+ * @todo Find out if loadDescriptorXml() can be called only once to avoid a lot methods working.
*/
public function publishEntry () {
- $this->partialStub('Unimplemented method.');
+ // This test must not fail
+ assert($this->hasEntriesPendingPublication());
+
+ // Is there an instance?
+ if (!$this->publishHelperInstance instanceof HelpableDht) {
+ // Get a helper instance
+ $this->publishHelperInstance = ObjectFactory::createObjectByConfiguredName('dht_publish_entry_helper_class');
+ } // END - if
+
+ // Load the announcement descriptor
+ $this->publishHelperInstance->loadDescriptorXml($this);
+
+ // Compile all variables
+ $this->publishHelperInstance->getTemplateInstance()->compileConfigInVariables();
+
+ // "Publish" the descriptor by sending it to the bootstrap/list nodes
+ $this->publishHelperInstance->sendPackage($this);
}
}
/**
* Loads the announcement descriptor for parsing
*
+ * @param $dhtInstance An instance of a Distributable class
* @return void
*/
- public function loadDescriptorXml () {
+ public function loadDescriptorXml (Distributable $dhtInstance) {
// Debug message
self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __LINE__ . ']: Starting with DHT boostrap ...');
--- /dev/null
+<?php
+/**
+ * A PublishingEntry Dht helper class
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.org
+ * @todo Find an interface for hub helper
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class DhtPublishEntryHelper extends BaseHubSystemHelper implements HelpableDht {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set recipient type
+ $this->setRecipientType(NetworkPackage::NETWORK_TARGET_DHT);
+
+ // Set package tags
+ $this->setPackageTags(array('dht_publish_entry'));
+ }
+
+ /**
+ * Creates the helper class
+ *
+ * @return $helperInstance A prepared instance of this helper
+ */
+ public final static function createDhtPublishEntryHelper () {
+ // Get new instance
+ $helperInstance = new DhtPublishEntryHelper();
+
+ // Return the prepared instance
+ return $helperInstance;
+ }
+
+ /**
+ * Loads the announcement descriptor for parsing
+ *
+ * @param $dhtInstance An instance of a Distributable class
+ * @return void
+ */
+ public function loadDescriptorXml (Distributable $dhtInstance) {
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __LINE__ . ']: Starting with publishing an entry ...');
+
+ // Get a XML template instance
+ $templateInstance = XmlTemplateEngineFactory::createXmlTemplateEngineInstance('dht_publish_entry_template_class');
+
+ // Set stacker
+
+ // Set it for later use
+ $this->setTemplateInstance($templateInstance);
+
+ // Read the XML descriptor
+ $templateInstance->loadXmlTemplate();
+
+ // Render the XML content
+ $templateInstance->renderXmlContent();
+ }
+
+ /**
+ * Do the helped attempt by delivering a package to ourselfs
+ *
+ * @param $dhtInstance An instance of a Distributable class
+ * @return void
+ */
+ public function sendPackage (Distributable $dhtInstance) {
+ // Compile the template, this inserts the loaded dht data into the gaps.
+ $this->getTemplateInstance()->compileTemplate();
+ die(print_r($this->getTemplateInstance(), TRUE));
+
+ // Get a singleton network package instance
+ $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+
+ // Next, feed the content in. The network package class is a pipe-through class.
+ $packageInstance->enqueueRawDataFromTemplate($this, NetworkPackage::PROTOCOL_TCP);
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * An PublishEntry template engine class for XML templates
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.org
+ * @todo This template engine does not make use of setTemplateType()
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class XmlDhtPublishEntryTemplateEngine extends BaseXmlTemplateEngine implements CompileableTemplate, Registerable {
+ /**
+ * Some XML nodes must be available for later data extraction
+ */
+ const PUBLISH_DATA_NODE_ID = 'node-id';
+ const PUBLISH_DATA_SESSION_ID = 'session-id';
+ const PUBLISH_DATA_NODE_STATUS = 'node-status';
+ const PUBLISH_DATA_NODE_MODE = 'node-mode';
+ const PUBLISH_DATA_EXTERNAL_IP = 'external-ip';
+ const PUBLISH_DATA_LISTEN_PORT = 'listen-port';
+ const PUBLISH_DATA_PRIVATE_KEY_HASH = 'private-key-hash';
+ const PUBLISH_DATA_ACCEPTED_OBJECT_TYPES = 'accepted-object-types';
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Init array
+ $this->subNodes = array(
+ 'publish-data',
+ 'listener',
+ self::PUBLISH_DATA_NODE_STATUS,
+ self::PUBLISH_DATA_NODE_MODE,
+ self::PUBLISH_DATA_LISTEN_PORT,
+ self::PUBLISH_DATA_PRIVATE_KEY_HASH,
+ self::PUBLISH_DATA_ACCEPTED_OBJECT_TYPES,
+ self::PUBLISH_DATA_NODE_ID,
+ self::PUBLISH_DATA_SESSION_ID,
+ self::PUBLISH_DATA_EXTERNAL_IP,
+ 'object-type-list',
+ );
+ }
+
+ /**
+ * Creates an instance of the class TemplateEngine and prepares it for usage
+ *
+ * @return $templateInstance An instance of TemplateEngine
+ * @throws BasePathIsEmptyException If the provided $templateBasePath is empty
+ * @throws InvalidBasePathStringException If $templateBasePath is no string
+ * @throws BasePathIsNoDirectoryException If $templateBasePath is no
+ * directory or not found
+ * @throws BasePathReadProtectedException If $templateBasePath is
+ * read-protected
+ */
+ public static final function createXmlDhtPublishEntryTemplateEngine () {
+ // Get a new instance
+ $templateInstance = new XmlDhtPublishEntryTemplateEngine();
+
+ // Init template instance
+ $templateInstance->initXmlTemplateEngine('dht', 'publish');
+
+ // Return the prepared instance
+ return $templateInstance;
+ }
+
+ /**
+ * Currently not used
+ *
+ * @param $resource XML parser resource (currently ignored)
+ * @param $characters Characters to handle
+ * @return void
+ */
+ public function characterHandler ($resource, $characters) {
+ // Trim all spaces away
+ $characters = trim($characters);
+
+ // Is this string empty?
+ if (empty($characters)) {
+ // Then skip it silently
+ return;
+ } // END - if
+
+ /*
+ * Assign the found characters to variable and use the last entry from
+ * stack as the name.
+ */
+ parent::assignVariable($this->getStackerInstance()->getNamed('dht_publish'), $characters);
+ }
+
+ /**
+ * Getter for cache file (FQFN)
+ *
+ * @return $fqfn Full-qualified file name of the menu cache
+ */
+ public function getMenuCacheFqfn () {
+ $this->partialStub('Please implement this method.');
+ }
+
+ /**
+ * Starts the publish
+ *
+ * @return void
+ */
+ protected function startPublish () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', 'publish');
+ }
+
+ /**
+ * Starts the publish data
+ *
+ * @return void
+ */
+ protected function startPublishData () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', 'publish-data');
+ }
+
+ /**
+ * Starts the node status
+ *
+ * @return void
+ */
+ protected function startNodeStatus () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_NODE_STATUS);
+ }
+
+ /**
+ * Starts the node-mode
+ *
+ * @return void
+ */
+ protected function startNodeMode () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_NODE_MODE);
+ }
+
+ /**
+ * Starts the listener
+ *
+ * @return void
+ */
+ protected function startListener () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', 'listener');
+ }
+
+ /**
+ * Starts the TCP/UDP listen port
+ *
+ * @return void
+ */
+ protected function startListenPort () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_LISTEN_PORT);
+ }
+
+ /**
+ * Starts accepted object types
+ *
+ * @return void
+ */
+ protected function startAcceptedObjectTypes () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_ACCEPTED_OBJECT_TYPES);
+ }
+
+ /**
+ * Starts hash from private key
+ *
+ * @return void
+ */
+ protected function startPrivateKeyHash () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_PRIVATE_KEY_HASH);
+ }
+
+ /**
+ * Starts the node id
+ *
+ * @return void
+ */
+ protected function startNodeId () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_NODE_ID);
+ }
+
+ /**
+ * Starts the session id
+ *
+ * @return void
+ */
+ protected function startSessionId () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_SESSION_ID);
+ }
+
+ /**
+ * Starts the public ip
+ *
+ * @return void
+ */
+ protected function startExternalIp () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', self::PUBLISH_DATA_EXTERNAL_IP);
+ }
+
+ /**
+ * Starts the object type list
+ *
+ * @return void
+ */
+ protected function startObjectTypeList () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', 'object-type-list');
+ }
+
+ /**
+ * Starts the object type
+ *
+ * @return void
+ */
+ protected function startObjectType () {
+ // Push the node name on the stacker
+ $this->getStackerInstance()->pushNamed('dht_publish', 'object-type');
+ }
+
+ /**
+ * Finishes the object type
+ *
+ * @return void
+ */
+ protected function finishObjectType () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the object type list
+ *
+ * @return void
+ */
+ protected function finishObjectTypeList () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the session id
+ *
+ * @return void
+ */
+ protected function finishSessionId () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the node id
+ *
+ * @return void
+ */
+ protected function finishNodeId () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the public ip
+ *
+ * @return void
+ */
+ protected function finishExternalIp () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the TCP/UDP listen port
+ *
+ * @return void
+ */
+ protected function finishListenPort () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes hash from private key
+ *
+ * @return void
+ */
+ protected function finishPrivateKeyHash () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes accepted object types
+ *
+ * @return void
+ */
+ protected function finishAcceptedObjectTypes () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the listener
+ *
+ * @return void
+ */
+ protected function finishListener () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the node mode
+ *
+ * @return void
+ */
+ protected function finishNodeMode () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the node status
+ *
+ * @return void
+ */
+ protected function finishNodeStatus () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the publish data
+ *
+ * @return void
+ */
+ protected function finishPublishData () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+
+ /**
+ * Finishes the publish
+ *
+ * @return void
+ */
+ protected function finishPublish () {
+ // Pop the last entry
+ $this->getStackerInstance()->popNamed('dht_publish');
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+An XML for DHTs publishing their entries
+
+@author Roland Haeder <webmaster@ship-simu.org>
+@version 0.0.0
+@copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team
+@license GNU GPL 3.0 or any newer version
+@link http://www.ship-simu.org
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>
+//-->
+<publish>
+ <!--
+ The data in this message is similar to that in announcement, except that an
+ announcement is sent to boot, master and list nodes but this to "all" nodes
+ that matches some criteria. If we would send this to *really* all nodes,
+ this would easily flood the network.
+
+ Currently this XML message contains the same data fields as announcement.xml
+ but this might be changed in the future. And please remember that you can
+ type as much as you want here, as all will be removed by the compaction
+ step.
+
+ The following example data will be published (execept __idx):
+Array
+(
+ [node_mode] => regular
+ [external_ip] => 192.168.2.3
+ [listen_port] => 9061
+ [node_id] => 38fc625d3d9aa05654bfc90a7aea7ff72c883f1573
+ [session_id] => 38fc625d3dabe9ff09b54253b298e91985191472a3
+ [private_key_hash] => 38fc625d3dad67db034d7e715fae8b8ea47fefb0dc
+ [accepted_object_types] => announcement,self_connect,announcement_answer,request_node_list,request_node_list_answer,dht_bootstrap
+ [__idx] => 1
+)
+ //-->
+ <publish-data>
+ <!-- Status of this node, see node_status.xml for details. //-->
+ <node-status>{?node_status?}</node-status>
+ <!-- Node mode: regular, master, list, boot again //-->
+ <node-mode>{?node_default_mode?}</node-mode>
+ <!-- The node id. //-->
+ <node-id>{?node_id?}</node-id>
+ <!-- The session id. This should be announced to all other hubs. //-->
+ <session-id>{?session_id?}</session-id>
+ <!-- Hash of private key. //-->
+ <private-key-hash>{?private_key_hash?}</private-key-hash>
+ <!-- Accepted object types //-->
+ <accepted-object-types>{?accepted_object_types?}</accepted-object-types>
+ <!-- Data from our listeners (e.g. which port) //-->
+ <listener>
+ <!-- Public external IP address //-->
+ <external-ip>{?external_ip?}</external-ip>
+ <!-- Listener ports for both connections //-->
+ <listen-port>{?listen_port?}</listen-port>
+ </listener>
+ </publish-data>
+</publish>
<object-protocol>tcp</object-protocol>
<object-recipient-type>all</object-recipient-type>
</object-list-entry>
+ <object-list-entry>
+ <object-name>dht_publish</object-name>
+ <object-recipient-limitation>all</object-recipient-limitation>
+ <object-max-spread>4</object-max-spread>
+ <object-protocol>tcp</object-protocol>
+ <object-recipient-type>all</object-recipient-type>
+ </object-list-entry>
</object-list>
</object-registry>
-Subproject commit 7244bd9800fb371c6c8b51be8844cf089e0921b4
+Subproject commit b287094ddaed86f6d71c2d54f7b18d26a2312fd4