1 /*------------------------------------------------------------------------------
  2 Name:      NodeInfo.cpp
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Holding information about the current node.
  6 ------------------------------------------------------------------------------*/
  7 
  8 #include <util/cluster/NodeInfo.h>
  9 #include <util/Global.h>
 10 
 11 namespace org { namespace xmlBlaster { namespace util { namespace cluster {
 12 
 13 using namespace std;
 14 using namespace org::xmlBlaster::util;
 15 using namespace org::xmlBlaster::util::qos::address;
 16 using namespace org::xmlBlaster::util::cluster;
 17 
 18 /**
 19  * This class holds the address informations about an
 20  * xmlBlaster server instance (=cluster node). 
 21  */
 22 
 23 //typedef map<string, CallbackAddress> CbAddressMap;
 24 //typedef map<string, Address>         AddressMap;
 25 //typedef map<string, NodeId>          NodeMap;
 26 
 27 NodeInfo::NodeInfo(Global& global, NodeId nodeId)
 28    : ME(string("NodeInfo.") + nodeId.toString()), global_(global), nodeId_(nodeId),
 29      tmpAddress_(global), tmpCbAddress_(global), cbAddressMap_(), addressMap_(),
 30      backupNodeMap_()
 31 {
 32    init();
 33 }
 34 
 35 NodeInfo::NodeInfo(const NodeInfo& info)
 36    : ME(info.ME), global_(info.global_), nodeId_(info.nodeId_),
 37      tmpAddress_(info.tmpAddress_), tmpCbAddress_(info.tmpCbAddress_),
 38      cbAddressMap_(info.cbAddressMap_), addressMap_(info.addressMap_),
 39      backupNodeMap_(info.backupNodeMap_)
 40 {
 41    copy(info);
 42 }
 43 
 44 NodeInfo& NodeInfo::operator=(const NodeInfo& info)
 45 {
 46    copy(info);
 47    return *this;
 48 }
 49 
 50 /**
 51  * @return The unique name of the managed xmlBlaster instance e.g. "bilbo.mycompany.com"
 52  */
 53 string NodeInfo::getId() const
 54 {
 55   return nodeId_.getId();
 56 }
 57 
 58    /**
 59     * @return The unique name of the managed xmlBlaster instance.
 60     */
 61    NodeId NodeInfo::getNodeId() const
 62    {
 63      return nodeId_;
 64    }
 65 
 66    /**
 67     * @param The unique name of the managed xmlBlaster instance
 68     */
 69    void NodeInfo::setNodeId(NodeId nodeId)
 70    {
 71       nodeId_ = nodeId;
 72    }
 73 
 74    /**
 75     * Access the currently used address to access the node
 76     * @return null if not specified
 77     */
 78    AddressBaseRef NodeInfo::getAddress() const
 79    {
 80       if (addressMap_.empty()) return new Address(global_);
 81       return (*(addressMap_.begin())).second;
 82    }
 83 
 84    /**
 85     * Add another address for this cluster node. 
 86     * <p />
 87     * The map is sorted with the same sequence as the given XML sequence
 88     */
 89    void NodeInfo::addAddress(const AddressBaseRef& address)
 90    {
 91       addressMap_.insert(AddressMap::value_type(address->getRawAddress(), address));
 92    }
 93 
 94    /**
 95     * Access all addresses of a node, please handle as readonly. 
 96     */
 97    AddressMap NodeInfo::getAddressMap() const
 98    {
 99       return addressMap_;
100    }
101 
102    /**
103     * Does the given address belong to this node?
104     */
105    bool NodeInfo::contains(const AddressBaseRef& other)
106    {
107       if (addressMap_.empty()) return false;
108       return (addressMap_.find(other->getRawAddress()) != addressMap_.end());
109    }
110 
111    /**
112     * Access the currently used callback address for this node
113     * @return Never null, returns a default if none specified
114     */
115    AddressBaseRef NodeInfo::getCbAddress()
116    {
117       if (cbAddressMap_.empty()) {
118          addCbAddress(new CallbackAddress(global_));
119       }
120       return (*(cbAddressMap_.begin())).second;
121    }
122 
123    /**
124     * Currently not used. 
125     */
126    AddressMap NodeInfo::getCbAddressMap() const
127    {
128       return cbAddressMap_;
129    }
130 
131    /**
132     * Add another callback address for this cluster node. 
133     */
134    void NodeInfo::addCbAddress(const AddressBaseRef& cbAddress)
135    {
136       cbAddressMap_.insert(AddressMap::value_type(cbAddress->getRawAddress(),cbAddress));
137    }
138 
139    /**
140     * Is the node acting as a preferred cluster naming service. 
141     * <p />
142     * NOTE: This mode is currently not supported
143     */
144    bool NodeInfo::isNameService() const
145    {
146       return nameService_;
147    }
148 
149    /**
150     * Tag this node as a cluster naming service. 
151     * <p />
152     * NOTE: This mode is currently not supported
153     */
154    void NodeInfo::setNameService(bool nameService)
155    {
156       nameService_ = nameService;
157    }
158 
159    /**
160     * If this node is not accessible, we can use its backup nodes. 
161     * @return a Map containing NodeId objects
162     */
163    NodeMap NodeInfo::getBackupnodeMap() const
164    {
165       return backupNodeMap_;
166    }
167 
168    /**
169     * Set backup nodes. 
170     */
171    void NodeInfo::addBackupnode(const NodeId& backupId)
172    {
173       backupNodeMap_.insert(NodeMap::value_type(backupId.getId(), backupId));
174    }
175 
176    /**
177     * Called for SAX master start tag
178     * @return true if ok, false on error
179     */
180 /*
181    bool startElement(String uri, String localName, String name, StringBuffer character, Attributes attrs) {
182       // glob.getLog("cluster").info(ME, "startElement: name=" + name + " character='" + character.toString() + "'");
183 
184       if (name.equalsIgnoreCase("info")) {
185          return true;
186       }
187 
188       if (inAddress) { // delegate internal tags
189          if (tmpAddress == null) return false;
190          tmpAddress.startElement(uri, localName, name, character, attrs);
191          return true;
192       }
193       if (name.equalsIgnoreCase("address")) {
194          inAddress = true;
195          tmpAddress = new Address(glob, "", getId());
196          tmpAddress.startElement(uri, localName, name, character, attrs);
197          return true;
198       }
199 
200       if (name.equalsIgnoreCase("callback")) {
201          inCallback = true;
202          tmpCbAddress = new CallbackAddress(glob);
203          tmpCbAddress.startElement(uri, localName, name, character, attrs);
204          return true;
205       }
206 
207       if (name.equalsIgnoreCase("backupnode")) {
208          inBackupnode = true;
209          return true;
210       }
211       if (inBackupnode && name.equalsIgnoreCase("clusternode")) {
212          if (attrs != null) {
213             String tmp = attrs.getValue("id");
214             if (tmp == null) {
215                glob.getLog("org.xmlBlaster.cluster").error(ME, "<backupnode><clusternode> attribute 'id' is missing, ignoring message");
216                throw RuntimeException("NodeParser: <backupnode><clusternode> attribute 'id' is missing, ignoring message");
217             }
218             addBackupnode(new NodeId(tmp.trim()));
219          }
220          return true;
221       }
222 
223       return false;
224    }
225 */
226 
227    /**
228     * Handle SAX parsed end element
229     */
230 /*
231    public final void endElement(String uri, String localName, String name, StringBuffer character) {
232       if (inAddress) { // delegate address internal tags
233          tmpAddress.endElement(uri, localName, name, character);
234          if (name.equalsIgnoreCase("address")) {
235             inAddress = false;
236             addAddress(tmpAddress);
237          }
238          return;
239       }
240 
241       if (inCallback) { // delegate address internal tags
242          tmpCbAddress.endElement(uri, localName, name, character);
243          if (name.equalsIgnoreCase("callback")) {
244             inCallback = false;
245             addCbAddress(tmpCbAddress);
246          }
247          return;
248       }
249 
250       if (name.equalsIgnoreCase("backupnode")) {
251          inBackupnode = false;
252          character.setLength(0);
253          return;
254       }
255 
256       character.setLength(0);
257       return;
258    }
259 */
260 
261    /**
262     * Dump state of this object into a XML ASCII string.
263     * @param extraOffset indenting of tags for nice output
264     */
265    string NodeInfo::toXml(const string& extraOffset)
266    {
267       string ret;
268       string offset = "\n   ";
269       offset += extraOffset;
270 
271       ret += offset + "<info>";
272       if (!addressMap_.empty()) {
273          AddressMap::iterator iter = addressMap_.begin();
274          while (iter != addressMap_.end()) {
275             const AddressBaseRef& info = (*iter).second;
276             ret += info->toXml(extraOffset + "   ");
277             iter++;
278          }
279       }
280  
281       if (!cbAddressMap_.empty()) {
282          AddressMap::iterator iter = cbAddressMap_.begin();
283          while (iter != cbAddressMap_.end()) {
284             const AddressBaseRef &info = (*iter).second;
285             ret +=  info->toXml(extraOffset + "   ");
286             iter++;
287          }
288       }
289 
290       if (!backupNodeMap_.empty()) {
291          NodeMap::iterator iter = backupNodeMap_.begin();
292          ret += offset + "   <backupnode>";
293          while (iter != backupNodeMap_.end()) {
294             NodeId info = (*iter).second;
295             ret += offset + "      <clusternode id='" + info.getId() + "'/>";
296          }
297          ret += offset + "   </backupnode>";
298       }
299       ret += offset + "</info>";
300       return ret;
301    }
302 
303 }}}}


syntax highlighted by Code2HTML, v. 0.9.1