| 54 | | /** |
| 55 | | * To contains (NodeHandle,Node) pairs for all nodes in the network. |
| 56 | | */ |
| 57 | | private TreeMap nodes; |
| 58 | | /** |
| 59 | | * Containts all nodes to remove from the network. |
| 60 | | */ |
| 61 | | private Stack toRemove; |
| 62 | | /** |
| 63 | | * NodeFactory implementation which permits build new nodes. |
| 64 | | */ |
| 65 | | private NodeFactory nodeFactory; |
| 66 | | /** |
| 67 | | * Defines the topology of the actual network. |
| 68 | | */ |
| 69 | | private String topology; |
| 70 | | /** |
| 71 | | * Random generator to use to generate random indexes. |
| 72 | | */ |
| 73 | | private Random randomGenerator; |
| 74 | | /** |
| 75 | | * The actual size of the network. The number of contained nodes. |
| 76 | | * It is required for when there are leaving nodes, for showing |
| 77 | | * the real size on any time. |
| 78 | | */ |
| 79 | | private int size; |
| 80 | | /** |
| 81 | | * Shows the level of stabilization of the network. |
| 82 | | */ |
| 83 | | private int stabLevel; |
| 84 | | /** |
| 85 | | * Shows the number of actually simulated steps. |
| 86 | | */ |
| 87 | | private int totalSteps; |
| 88 | | |
| 89 | | /** |
| 90 | | * Initialize the network with no nodes and wihtout simulation steps. |
| 91 | | */ |
| 92 | | public NetworkImpl() { |
| 93 | | nodes = new TreeMap(); //to contain all nodes |
| 94 | | toRemove = new Stack(); |
| 95 | | randomGenerator = new Random(System.currentTimeMillis()); |
| 96 | | size = 0; |
| 97 | | stabLevel = 0; |
| 98 | | totalSteps = 0; |
| 99 | | } |
| | 54 | /** |
| | 55 | * To contains (NodeHandle,Node) pairs for all nodes in the network. |
| | 56 | */ |
| | 57 | private TreeMap nodes; |
| | 58 | /** |
| | 59 | * Containts all nodes to remove from the network. |
| | 60 | */ |
| | 61 | private Stack toRemove; |
| | 62 | /** |
| | 63 | * NodeFactory implementation which permits build new nodes. |
| | 64 | */ |
| | 65 | private NodeFactory nodeFactory; |
| | 66 | /** |
| | 67 | * Defines the topology of the actual network. |
| | 68 | */ |
| | 69 | private String topology; |
| | 70 | /** |
| | 71 | * Random generator to use to generate random indexes. |
| | 72 | */ |
| | 73 | private Random randomGenerator; |
| | 74 | /** |
| | 75 | * The actual size of the network. The number of contained nodes. |
| | 76 | * It is required for when there are leaving nodes, for showing |
| | 77 | * the real size on any time. |
| | 78 | */ |
| | 79 | private int size; |
| | 80 | /** |
| | 81 | * Shows the level of stabilization of the network. |
| | 82 | */ |
| | 83 | private int stabLevel; |
| | 84 | /** |
| | 85 | * Shows the number of actually simulated steps. |
| | 86 | */ |
| | 87 | private int totalSteps; |
| | 88 | |
| | 89 | /** |
| | 90 | * Initialize the network with no nodes and wihtout simulation steps. |
| | 91 | */ |
| | 92 | public NetworkImpl() { |
| | 93 | nodes = new TreeMap(); //to contain all nodes |
| | 94 | toRemove = new Stack(); |
| | 95 | randomGenerator = new Random(System.currentTimeMillis()); |
| | 96 | size = 0; |
| | 97 | stabLevel = 0; |
| | 98 | totalSteps = 0; |
| | 99 | } |
| 120 | | |
| 121 | | /** |
| 122 | | * Add the <b>node</b> to the actual network. Its bootstrap can be: |
| 123 | | * <ol> |
| 124 | | * <li><b>node</b>: If there aren't nodes to the network.</li> |
| 125 | | * <li><b>Any node</b>: Any node in the network if just exists nodes |
| 126 | | * to the network.</li> |
| 127 | | * </ol> |
| 128 | | * Runs the stabilization process after joins the node. |
| 129 | | * @see planet.commonapi.Network#joinNode(planet.commonapi.Node) |
| 130 | | * @param node Node to add to the network. |
| 131 | | */ |
| 132 | | public void joinNode(Node node) throws InitializationException { |
| 133 | | if (nodes.size()==0) { |
| 134 | | nodes.put(node.getLocalHandle(),node); //it is its own bootstrap |
| 135 | | node.join(node.getLocalHandle()); |
| 136 | | } else { |
| 137 | | Node boot = (Node)nodes.values().iterator().next(); //constant view of Id of nodes |
| 138 | | node.join(boot.getLocalHandle()); |
| 139 | | } |
| 140 | | size++; |
| 141 | | } |
| 142 | | |
| 143 | | /** |
| 144 | | * Adds <b>node</b> to the network, using the node with |
| 145 | | * Id <b>bootstrap</b> to enter it. Runs the stabilization process after joins |
| 146 | | * this node. |
| 147 | | * @see planet.commonapi.Network#joinNode(planet.commonapi.Node, planet.commonapi.NodeHandle) |
| 148 | | * @param node Node to add to the network. |
| 149 | | * @param bootstrap Id of the node to use as bootstrap for <b>node</b>. |
| 150 | | * @throws InitializationException if the <b>bootstrap</b> not exists in the network. |
| 151 | | */ |
| 152 | | public void joinNode(Node node, NodeHandle bootstrap) throws InitializationException { |
| 153 | | //test if bootstrap exists |
| 154 | | if ((nodes.size()==0 && !node.getId().equals(bootstrap.getId())) || (nodes.size()>0 && !nodes.containsKey(bootstrap))) |
| | 120 | |
| | 121 | /** |
| | 122 | * Add the <b>node</b> to the actual network. Its bootstrap can be: |
| | 123 | * <ol> |
| | 124 | * <li><b>node</b>: If there aren't nodes to the network.</li> |
| | 125 | * <li><b>Any node</b>: Any node in the network if just exists nodes |
| | 126 | * to the network.</li> |
| | 127 | * </ol> |
| | 128 | * Runs the stabilization process after joins the node. |
| | 129 | * @see planet.commonapi.Network#joinNode(planet.commonapi.Node) |
| | 130 | * @param node Node to add to the network. |
| | 131 | */ |
| | 132 | public void joinNode(Node node) throws InitializationException { |
| | 133 | if (nodes.size()==0) { |
| | 134 | nodes.put(node.getLocalHandle(),node); //it is its own bootstrap |
| | 135 | node.join(node.getLocalHandle()); |
| | 136 | } else { |
| | 137 | Node boot = (Node)nodes.values().iterator().next(); //constant view of Id of nodes |
| | 138 | node.join(boot.getLocalHandle()); |
| | 139 | } |
| | 140 | size++; |
| | 141 | } |
| | 142 | |
| | 143 | /** |
| | 144 | * Adds <b>node</b> to the network, using the node with |
| | 145 | * Id <b>bootstrap</b> to enter it. Runs the stabilization process after joins |
| | 146 | * this node. |
| | 147 | * @see planet.commonapi.Network#joinNode(planet.commonapi.Node, planet.commonapi.NodeHandle) |
| | 148 | * @param node Node to add to the network. |
| | 149 | * @param bootstrap Id of the node to use as bootstrap for <b>node</b>. |
| | 150 | * @throws InitializationException if the <b>bootstrap</b> not exists in the network. |
| | 151 | */ |
| | 152 | public void joinNode(Node node, NodeHandle bootstrap) throws InitializationException { |
| | 153 | //test if bootstrap exists |
| | 154 | if ((nodes.size()==0 && !node.getId().equals(bootstrap.getId())) || (nodes.size()>0 && !nodes.containsKey(bootstrap))) |
| 245 | | private int joinNodesNormally(int size) throws InitializationException { |
| 246 | | if (size>0) { |
| 247 | | Node toJoin = null; |
| 248 | | NodeHandle bootstrap = null; |
| 249 | | Vector boots = new Vector(); |
| 250 | | //if exists no nodes, add one |
| 251 | | if (this.size==0) { |
| 252 | | //create new node |
| 253 | | toJoin = nodeFactory.buildNode(); |
| 254 | | nodes.put(toJoin.getLocalHandle(),toJoin); |
| 255 | | //updates number of nodes to join |
| 256 | | size--; |
| 257 | | this.size++; |
| 258 | | bootstrap = toJoin.getLocalHandle(); |
| 259 | | toJoin.join(bootstrap); |
| 260 | | } else { |
| 261 | | bootstrap = (NodeHandle)nodes.keySet().iterator().next(); |
| 262 | | } |
| 263 | | |
| 264 | | boots.add(bootstrap); |
| 265 | | //add the rest of nodes |
| 266 | | for (int i = 0; i<size; i++) { |
| 267 | | //create new node |
| 268 | | toJoin = nodeFactory.buildNode(); |
| 269 | | //put it into hashmap |
| 270 | | nodes.put(toJoin.getLocalHandle(),toJoin); |
| 271 | | toJoin.join(bootstrap); |
| 272 | | boots.add(toJoin); |
| 273 | | bootstrap = (NodeHandle)boots.get(randomGenerator.nextInt(boots.size())); |
| 274 | | run(Properties.simulatorSimulationSteps); |
| 275 | | this.size++; |
| 276 | | } |
| 277 | | } |
| 278 | | return totalSteps; |
| 279 | | } |
| 280 | | |
| 281 | | /** |
| 282 | | * Add <b>size</b> nodes to the actual network. Their class and their Ids |
| 283 | | * depends of the actual configuration of different factories. As bootstrap |
| 284 | | * for those nodes are used the Ids that appears at <b>bootstrap</b>. If |
| 285 | | * <b>size</b> > <b>bootstrap.length</b>, new nodes are distributed |
| 286 | | * radomly for them. |
| 287 | | * @see planet.commonapi.Network#joinNodes(int, planet.commonapi.NodeHandle[]) |
| 288 | | * @param size Number of nodes to add to the network. |
| 289 | | * @param bootstrap NodeHandles of nodes to use as bootstrap for new nodes. |
| 290 | | * @throws InitializationException if occur some problem with building nodes. |
| 291 | | * @return A number of actual simulated steps after join <b>size</b> nodes. |
| 292 | | */ |
| 293 | | public int joinNodes(int size, NodeHandle[] bootstrap) throws InitializationException { |
| 294 | | Node toJoin = null; |
| 295 | | NodeHandle boot = null; |
| 296 | | int index = 0; |
| 297 | | for (int i = 0; i<size; i++) { |
| 298 | | //create new node |
| 299 | | toJoin = nodeFactory.buildNode(); |
| 300 | | //put it to hashmap |
| 301 | | nodes.put(toJoin.getLocalHandle(),toJoin); |
| 302 | | //reinitialize the iterator if it has no more elements |
| 303 | | if (index==bootstrap.length) |
| 304 | | index = 0; |
| 305 | | boot = bootstrap[index]; |
| 306 | | toJoin.join(boot); |
| 307 | | run(Properties.simulatorSimulationSteps); |
| 308 | | this.size++; |
| 309 | | index++; |
| 310 | | } |
| 311 | | return totalSteps; |
| 312 | | } |
| 313 | | |
| 314 | | /** |
| 315 | | * Leave theese <b>nodes</b> for the network. If an exception is thrown, |
| 316 | | * it method ensures that the existing Ids has been leaved. Runs its |
| 317 | | * stabilization process at the end of all leaves. |
| 318 | | * @see planet.commonapi.Network#leaveNodes(planet.commonapi.NodeHandle[]) |
| 319 | | * @param nodes Ids for nodes to leave. |
| 320 | | * @throws InitializationException if exists some Id in the array |
| 321 | | * as parameter that not exists in the network. The message includes |
| 322 | | * which are of them. |
| 323 | | */ |
| 324 | | public void leaveNodes(NodeHandle[] nodes) throws InitializationException { |
| 325 | | Vector unknownNodes = new Vector(0,1); |
| 326 | | Set nodesId = this.nodes.keySet(); //constant view of Id of nodes |
| 327 | | for (int i=0; i< nodes.length; i++) { |
| 328 | | if (nodesId.contains(nodes[i])) { |
| 329 | | //update its predecessor and successor |
| 330 | | ((Node)this.nodes.get(nodes[i])).leave(); |
| 331 | | } else |
| 332 | | unknownNodes.add(nodes[i]); |
| 333 | | } |
| 334 | | if (unknownNodes.size()>0) |
| 335 | | throw new InitializationException ("Not exist some Ids in Id[]. They are followings: "+unknownNodes.toArray()); |
| 336 | | } |
| 337 | | |
| 338 | | /** |
| 339 | | * Runs the stabilization process after each fail node. |
| 340 | | * @see planet.commonapi.Network#failNodes(planet.commonapi.NodeHandle[]) |
| 341 | | */ |
| 342 | | public void failNodes(NodeHandle[] nodes) throws InitializationException { |
| 343 | | for (int i=0; i < nodes.length; i++) { |
| 344 | | ((Node)this.nodes.get(nodes[i])).fail(); |
| 345 | | } |
| 346 | | } |
| 347 | | |
| 348 | | /** |
| 349 | | * Register the Application <b>app</b> to all nodes existing |
| 350 | | * at the underlying network. |
| 351 | | * @see planet.commonapi.Network#registerApplicationAll() |
| 352 | | */ |
| 353 | | public void registerApplicationAll() throws InitializationException { |
| 354 | | Iterator it = nodes.values().iterator(); |
| 355 | | Node node = null; |
| 356 | | Application app = null; |
| 357 | | while (it.hasNext()) { |
| 358 | | node = (Node)it.next(); |
| 359 | | app = GenericFactory.buildApplication(); |
| 360 | | node.registerApplication(app,app.getId()); |
| 361 | | } |
| 362 | | } |
| 363 | | |
| 364 | | /** |
| 365 | | * Register the Application specified at properties file |
| 366 | | * to the specified <b>nodes</b> by theirs Ids. |
| 367 | | * @see planet.commonapi.Network#registerApplication(planet.commonapi.NodeHandle[]) |
| 368 | | * @param nodes NodeHandles of those nodes to register Application <b>app</b>. |
| 369 | | * @return The number of Nodes with the Application registered. If all that's ok, |
| 370 | | * the value returned would have be the same that nodes.length. |
| 371 | | */ |
| 372 | | public int registerApplication(NodeHandle[] nodes) throws InitializationException { |
| 373 | | Node node = null; |
| 374 | | Application app = null; |
| 375 | | int registered = 0; |
| 376 | | for (int i=0; i<nodes.length; i++) { |
| 377 | | node = (Node)this.nodes.get(nodes[i]); |
| 378 | | if (node!=null) { |
| 379 | | app = GenericFactory.buildApplication(); |
| 380 | | node.registerApplication(app,app.getId()); |
| 381 | | registered++; |
| 382 | | } |
| 383 | | } |
| 384 | | return registered; |
| 385 | | } |
| 386 | | |
| 387 | | /** |
| 388 | | * Register the Application <b>app</b> to radomly at the number of Nodes |
| 389 | | * <b>nodes</b>. If <b>nodes</b> is equals or greater than number of nodes |
| 390 | | * in the network, his effects are the same of <b>registerApplicationAll(Aplication)</b>. |
| 391 | | * @see planet.commonapi.Network#registerApplicationRandom(int) |
| 392 | | * @param nodes Number of nodes to radomly select to register the |
| 393 | | * Application <b>app</b>. |
| 394 | | */ |
| 395 | | public void registerApplicationRandom(int nodes) throws InitializationException { |
| 396 | | Set nodesId = this.nodes.keySet(); //constant view of Id of nodes |
| 397 | | NodeHandle[] ids = (NodeHandle[])nodesId.toArray(); |
| 398 | | Node node = null; |
| 399 | | if (nodes >= this.nodes.size() ) { |
| 400 | | registerApplicationAll(); |
| 401 | | } else { |
| 402 | | int[] selectedIds = makeRandomIndexes(nodes); |
| 403 | | Application app = null; |
| 404 | | for (int i=0; i < nodes; i++) { |
| 405 | | node = (Node)this.nodes.get(ids[selectedIds[i]]); |
| 406 | | app = GenericFactory.buildApplication(); |
| 407 | | node.registerApplication(app,app.getId()); |
| 408 | | } |
| 409 | | } |
| 410 | | } |
| 411 | | |
| 412 | | /** |
| 413 | | * Returns an array of indexes in range (0..number of nodes) to use |
| 414 | | * to identify which nodes to select. |
| 415 | | * @param max Number of indexes generate. |
| 416 | | * @return An array of indexes with values at range (0..number of nodes) with |
| 417 | | * a size of <b>max</b> elements. |
| 418 | | */ |
| 419 | | protected int[] makeRandomIndexes (int max) { |
| 420 | | HashSet indexes = new HashSet(max); |
| 421 | | int maxValue = nodes.size(); |
| 422 | | while (indexes.size() < max) { |
| 423 | | indexes.add(new Integer(randomGenerator.nextInt(maxValue))); |
| 424 | | } |
| 425 | | Integer[] integerIndexes = (Integer[])indexes.toArray(); |
| 426 | | int[] intIndexes = new int[max]; |
| 427 | | for (int i=0; i<max; i++) { |
| 428 | | intIndexes[i] = integerIndexes[i].intValue(); |
| 429 | | } |
| 430 | | return intIndexes; |
| 431 | | } |
| 432 | | |
| 433 | | /** |
| 434 | | * Gets the actual topology of the underlying network. |
| 435 | | * @see planet.commonapi.Network#getTopology() |
| 436 | | * @return A String defining the actual topology of the network. |
| 437 | | * @see planet.generic.commonapi.factory.Topology |
| 438 | | */ |
| 439 | | public String getTopology() { |
| 440 | | return topology; |
| 441 | | } |
| 442 | | |
| 443 | | /* ***************** DE/SERIALIZE NETWORKIMPL ****************/ |
| 444 | | /** |
| 445 | | * Serialize this instance through the <b>stream</b>. It is |
| 446 | | * responsible to generate a correct serialized state. |
| 447 | | * @param stream ObjectOutputStream to save the actual state. |
| 448 | | * @throws IOException if occurs any problem during serialization. |
| 449 | | */ |
| 450 | | private void writeObject(java.io.ObjectOutputStream stream) |
| | 245 | private int joinNodesNormally(int size) throws InitializationException { |
| | 246 | if (size>0) { |
| | 247 | Node toJoin = null; |
| | 248 | NodeHandle bootstrap = null; |
| | 249 | Vector boots = new Vector(); |
| | 250 | //if exists no nodes, add one |
| | 251 | if (this.size==0) { |
| | 252 | //create new node |
| | 253 | toJoin = nodeFactory.buildNode(); |
| | 254 | nodes.put(toJoin.getLocalHandle(),toJoin); |
| | 255 | //updates number of nodes to join |
| | 256 | size--; |
| | 257 | this.size++; |
| | 258 | bootstrap = toJoin.getLocalHandle(); |
| | 259 | toJoin.join(bootstrap); |
| | 260 | } else { |
| | 261 | bootstrap = (NodeHandle)nodes.keySet().iterator().next(); |
| | 262 | } |
| | 263 | |
| | 264 | boots.add(bootstrap); |
| | 265 | //add the rest of nodes |
| | 266 | for (int i = 0; i<size; i++) { |
| | 267 | //create new node |
| | 268 | toJoin = nodeFactory.buildNode(); |
| | 269 | //put it into hashmap |
| | 270 | nodes.put(toJoin.getLocalHandle(),toJoin); |
| | 271 | toJoin.join(bootstrap); |
| | 272 | boots.add(toJoin.getLocalHandle()); |
| | 273 | bootstrap = (NodeHandle)boots.get(randomGenerator.nextInt(boots.size())); |
| | 274 | run(Properties.simulatorSimulationSteps); |
| | 275 | this.size++; |
| | 276 | } |
| | 277 | } |
| | 278 | return totalSteps; |
| | 279 | } |
| | 280 | |
| | 281 | /** |
| | 282 | * Add <b>size</b> nodes to the actual network. Their class and their Ids |
| | 283 | * depends of the actual configuration of different factories. As bootstrap |
| | 284 | * for those nodes are used the Ids that appears at <b>bootstrap</b>. If |
| | 285 | * <b>size</b> > <b>bootstrap.length</b>, new nodes are distributed |
| | 286 | * radomly for them. |
| | 287 | * @see planet.commonapi.Network#joinNodes(int, planet.commonapi.NodeHandle[]) |
| | 288 | * @param size Number of nodes to add to the network. |
| | 289 | * @param bootstrap NodeHandles of nodes to use as bootstrap for new nodes. |
| | 290 | * @throws InitializationException if occur some problem with building nodes. |
| | 291 | * @return A number of actual simulated steps after join <b>size</b> nodes. |
| | 292 | */ |
| | 293 | public int joinNodes(int size, NodeHandle[] bootstrap) throws InitializationException { |
| | 294 | Node toJoin = null; |
| | 295 | NodeHandle boot = null; |
| | 296 | int index = 0; |
| | 297 | for (int i = 0; i<size; i++) { |
| | 298 | //create new node |
| | 299 | toJoin = nodeFactory.buildNode(); |
| | 300 | //put it to hashmap |
| | 301 | nodes.put(toJoin.getLocalHandle(),toJoin); |
| | 302 | //reinitialize the iterator if it has no more elements |
| | 303 | if (index==bootstrap.length) |