📄 networkimpl.java
字号:
package planet.generic.commonapi;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import planet.commonapi.Application;
import planet.commonapi.Network;
import planet.commonapi.Node;
import planet.commonapi.NodeHandle;
import planet.commonapi.RouteMessage;
import planet.commonapi.behaviours.BehavioursRoleSelector;
import planet.commonapi.exception.InitializationException;
import planet.commonapi.factory.NodeFactory;
import planet.generic.commonapi.behaviours.BehavioursPropertiesImpl;
import planet.generic.commonapi.factory.GenericFactory;
import planet.simulate.Globals;
import planet.simulate.Logger;
import planet.simulate.Results;
import planet.util.Properties;
import planet.util.Queue;
import planet.util.QueueFull;
/**
* This implementation of Network interface pretends to abstract
* any network, based with the actual commonapi, of course. The
* time is abstracted to discrete simulation steps.
* <br><br>
* Operationals modes for this network implementation:
*
* <ol>
* <li>Accessing directly to an instance of this class, and adding
* nodes, leaving them (or part of them), etc. without time certainty.
* In some cases it is usefull. In this case, events cannot be treated.</li>
* <li>Generating a new instance of NetworkSimulator and invoking ONLY AND
* ONLY IF the NetworkSimulator methods, with time certainty and treatment
* of events.</li>
* </ol>
*
* @author <a href="mailto: jordi.pujol@estudiants.urv.es">Jordi Pujol</a>
* @author <a href="mailto: marc.sanchez@urv.net">Marc Sanchez</a>
* 07-jul-2005
*/
public class NetworkImpl implements Network {
/**
* To contains (NodeHandle,Node) pairs for all nodes in the network.
*/
private TreeMap nodes;
/**
* Containts all nodes to remove from the network.
*/
private Stack toRemove;
/**
* NodeFactory implementation which permits build new nodes.
*/
private NodeFactory nodeFactory;
/**
* Defines the topology of the actual network.
*/
private String topology;
/**
* Random generator to use to generate random indexes.
*/
private Random randomGenerator;
/**
* The actual size of the network. The number of contained nodes.
* It is required for when there are leaving nodes, for showing
* the real size on any time.
*/
private int size;
/**
* Shows the level of stabilization of the network.
*/
private int stabLevel;
/**
* Shows the number of actually simulated steps.
*/
private int totalSteps;
/**
* Initialize the network with no nodes and wihtout simulation steps.
*/
public NetworkImpl() {
nodes = new TreeMap(); //to contain all nodes
toRemove = new Stack();
randomGenerator = new Random(System.currentTimeMillis());
size = 0;
stabLevel = 0;
totalSteps = 0;
}
/**
* Sets the initial values for the new Network instance.
* @param topology Desired network topology.
* @param nodeFactory NodeFactory implementation to be used to build
* the network.
* @return The same instance once it has been updated.
* @throws InitializationException if any error occurs during
* the initialization process.
* @see planet.commonapi.Network#setValues(java.lang.String, planet.commonapi.factory.NodeFactory)
*/
public Network setValues(String topology, NodeFactory nodeFactory) throws InitializationException
{
this.topology = topology;
this.nodeFactory = nodeFactory;
if (nodeFactory == null)
throw new InitializationException("The nodeFactory parameter is null");
return this;
}
/**
* Add the <b>node</b> to the actual network. Its bootstrap can be:
* <ol>
* <li><b>node</b>: If there aren't nodes to the network.</li>
* <li><b>Any node</b>: Any node in the network if just exists nodes
* to the network.</li>
* </ol>
* Runs the stabilization process after joins the node.
* @see planet.commonapi.Network#joinNode(planet.commonapi.Node)
* @param node Node to add to the network.
*/
public void joinNode(Node node) throws InitializationException {
if (nodes.size()==0) {
nodes.put(node.getLocalHandle(),node); //it is its own bootstrap
node.join(node.getLocalHandle());
} else {
Node boot = (Node)nodes.values().iterator().next(); //constant view of Id of nodes
node.join(boot.getLocalHandle());
}
size++;
}
/**
* Adds <b>node</b> to the network, using the node with
* Id <b>bootstrap</b> to enter it. Runs the stabilization process after joins
* this node.
* @see planet.commonapi.Network#joinNode(planet.commonapi.Node, planet.commonapi.NodeHandle)
* @param node Node to add to the network.
* @param bootstrap Id of the node to use as bootstrap for <b>node</b>.
* @throws InitializationException if the <b>bootstrap</b> not exists in the network.
*/
public void joinNode(Node node, NodeHandle bootstrap) throws InitializationException {
//test if bootstrap exists
if ((nodes.size()==0 && !node.getId().equals(bootstrap.getId())) || (nodes.size()>0 && !nodes.containsKey(bootstrap)))
{
throw new InitializationException("The bootstrap Id ["+ bootstrap +"] not exists within the network.");
}
//adds the node to Hash
nodes.put(node.getLocalHandle(),node);
//joins node with this bootstrap
node.join(bootstrap);
size++;
}
/**
* Add <b>size</b> nodes to the actual network. Their class and their Ids
* depends of the actual configuration of different factories. As bootstrap
* for those nodes are used any of the existing nodes or the firt of them
* if exists no nodes. Runs the stabilization process for each node.
* @see planet.commonapi.Network#joinNodes(int)
* @param size Number of nodes to add to the network.
* @throws InitializationException if occur some problem with building nodes.
* @return A number of actual simulated steps after join <b>size</b> nodes.
*/
public int joinNodes(int size) throws InitializationException {
if (Properties.overlayWithBehaviours)
return joinNodesWithBehaviours(size);
else
return joinNodesNormally(size);
}
/**
* Add <b>size</b> nodes to the network.
* @param size Number of nodes to be added.
* @return The number of simulated steps.
* @throws InitializationException if any error has ocurred.
*/
private int joinNodesWithBehaviours(int size) throws InitializationException {
if (size <= 0) return 0;
TreeSet nodeSet = new TreeSet();
Vector network = new Vector();
for (int whichNode = 0; whichNode < size; whichNode++) {
Node toJoin = nodeFactory.buildNode();
nodeSet.add(toJoin.getLocalHandle());
network.add(toJoin);
}
// BehaviourRoleSelector
BehavioursRoleSelector behSelector = GenericFactory.buildBehavioursRoleSelector();
Set badSet = behSelector.select(
nodeSet.iterator(), // Iterator over the whole Network
((BehavioursPropertiesImpl)Properties.behavioursPropertiesInstance).faultyNodes/100, // Percentage of Bad nodes.
((BehavioursPropertiesImpl)Properties.behavioursPropertiesInstance).maliciousDistributionAsInt // Distrbution of Bad nodes.
);
Iterator it = network.iterator();
Node toJoin = (Node) it.next(); // First Node to be inserted
NodeHandle bootstrap = null;
if (this.size==0)
{
bootstrap = toJoin.getLocalHandle(); // itself
} else {
bootstrap = (NodeHandle)nodes.keySet().iterator().next(); //another node already existing
}
toJoin.setGoodRole(badSet==null || !badSet.contains(toJoin.getId()));
toJoin.join(bootstrap);
nodes.put(toJoin.getLocalHandle(),toJoin);
Vector boots = new Vector(); //the set of possible bootstrap nodes
boots.add(bootstrap);
this.size++;
// The Remaining Nodes Ready For Bootstrapping
while (it.hasNext())
{
toJoin = (Node) it.next();
toJoin.setGoodRole(badSet==null || !badSet.contains(toJoin.getId()));
bootstrap = (NodeHandle)boots.get(randomGenerator.nextInt(boots.size()));
toJoin.join(bootstrap);
nodes.put(toJoin.getLocalHandle(),toJoin);
boots.add(toJoin.getLocalHandle());
run(Properties.simulatorSimulationSteps);
this.size++;
}
return totalSteps;
}
/**
* Adds the <b>size</b> nodes to the current network.
* @param size Total number of nodes to add.
* @return The last simulated step number.
* @throws InitializationException if any error occurs during the
* joining process.
*/
private int joinNodesNormally(int size) throws InitializationException {
if (size>0) {
Node toJoin = null;
NodeHandle bootstrap = null;
Vector boots = new Vector();
//if exists no nodes, add one
if (this.size==0) {
//create new node
toJoin = nodeFactory.buildNode();
nodes.put(toJoin.getLocalHandle(),toJoin);
//updates number of nodes to join
size--;
this.size++;
bootstrap = toJoin.getLocalHandle();
toJoin.join(bootstrap);
} else {
bootstrap = (NodeHandle)nodes.keySet().iterator().next();
}
boots.add(bootstrap);
//add the rest of nodes
for (int i = 0; i<size; i++) {
//create new node
toJoin = nodeFactory.buildNode();
//put it into hashmap
nodes.put(toJoin.getLocalHandle(),toJoin);
toJoin.join(bootstrap);
boots.add(bootstrap);
bootstrap = (NodeHandle)boots.get(randomGenerator.nextInt(boots.size()));
run(Properties.simulatorSimulationSteps);
this.size++;
}
}
return totalSteps;
}
/**
* Add <b>size</b> nodes to the actual network. Their class and their Ids
* depends of the actual configuration of different factories. As bootstrap
* for those nodes are used the Ids that appears at <b>bootstrap</b>. If
* <b>size</b> > <b>bootstrap.length</b>, new nodes are distributed
* radomly for them.
* @see planet.commonapi.Network#joinNodes(int, planet.commonapi.NodeHandle[])
* @param size Number of nodes to add to the network.
* @param bootstrap NodeHandles of nodes to use as bootstrap for new nodes.
* @throws InitializationException if occur some problem with building nodes.
* @return A number of actual simulated steps after join <b>size</b> nodes.
*/
public int joinNodes(int size, NodeHandle[] bootstrap) throws InitializationException {
Node toJoin = null;
NodeHandle boot = null;
int index = 0;
for (int i = 0; i<size; i++) {
//create new node
toJoin = nodeFactory.buildNode();
//put it to hashmap
nodes.put(toJoin.getLocalHandle(),toJoin);
//reinitialize the iterator if it has no more elements
if (index==bootstrap.length)
index = 0;
boot = bootstrap[index];
toJoin.join(boot);
run(Properties.simulatorSimulationSteps);
this.size++;
index++;
}
return totalSteps;
}
/**
* Leave theese <b>nodes</b> for the network. If an exception is thrown,
* it method ensures that the existing Ids has been leaved. Runs its
* stabilization process at the end of all leaves.
* @see planet.commonapi.Network#leaveNodes(planet.commonapi.NodeHandle[])
* @param nodes Ids for nodes to leave.
* @throws InitializationException if exists some Id in the array
* as parameter that not exists in the network. The message includes
* which are of them.
*/
public void leaveNodes(NodeHandle[] nodes) throws InitializationException {
Vector unknownNodes = new Vector(0,1);
Set nodesId = this.nodes.keySet(); //constant view of Id of nodes
for (int i=0; i< nodes.length; i++) {
if (nodesId.contains(nodes[i])) {
//update its predecessor and successor
((Node)this.nodes.get(nodes[i])).leave();
} else
unknownNodes.add(nodes[i]);
}
if (unknownNodes.size()>0)
throw new InitializationException ("Not exist some Ids in Id[]. They are followings: "+unknownNodes.toArray());
}
/**
* Runs the stabilization process after each fail node.
* @see planet.commonapi.Network#failNodes(planet.commonapi.NodeHandle[])
*/
public void failNodes(NodeHandle[] nodes) throws InitializationException {
for (int i=0; i < nodes.length; i++) {
((Node)this.nodes.get(nodes[i])).fail();
}
}
/**
* Register the Application <b>app</b> to all nodes existing
* at the underlying network.
* @see planet.commonapi.Network#registerApplicationAll()
*/
public void registerApplicationAll() throws InitializationException {
Iterator it = nodes.values().iterator();
Node node = null;
Application app = null;
while (it.hasNext()) {
node = (Node)it.next();
app = GenericFactory.buildApplication();
node.registerApplication(app,app.getId());
}
}
/**
* Register the Application specified at properties file
* to the specified <b>nodes</b> by theirs Ids.
* @see planet.commonapi.Network#registerApplication(planet.commonapi.NodeHandle[])
* @param nodes NodeHandles of those nodes to register Application <b>app</b>.
* @return The number of Nodes with the Application registered. If all that's ok,
* the value returned would have be the same that nodes.length.
*/
public int registerApplication(NodeHandle[] nodes) throws InitializationException {
Node node = null;
Application app = null;
int registered = 0;
for (int i=0; i<nodes.length; i++) {
node = (Node)this.nodes.get(nodes[i]);
if (node!=null) {
app = GenericFactory.buildApplication();
node.registerApplication(app,app.getId());
registered++;
}
}
return registered;
}
/**
* Register the Application <b>app</b> to radomly at the number of Nodes
* <b>nodes</b>. If <b>nodes</b> is equals or greater than number of nodes
* in the network, his effects are the same of <b>registerApplicationAll(Aplication)</b>.
* @see planet.commonapi.Network#registerApplicationRandom(int)
* @param nodes Number of nodes to radomly select to register the
* Application <b>app</b>.
*/
public void registerApplicationRandom(int nodes) throws InitializationException {
Set nodesId = this.nodes.keySet(); //constant view of Id of nodes
NodeHandle[] ids = (NodeHandle[])nodesId.toArray();
Node node = null;
if (nodes >= this.nodes.size() ) {
registerApplicationAll();
} else {
int[] selectedIds = makeRandomIndexes(nodes);
Application app = null;
for (int i=0; i < nodes; i++) {
node = (Node)this.nodes.get(ids[selectedIds[i]]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -