HADOOP-7772
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1189847 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1b8511ef89
commit
a3c0a0e799
@ -1008,6 +1008,8 @@ Release 0.22.0 - Unreleased
|
|||||||
HADOOP-7325. The hadoop command should not accept class names starting with
|
HADOOP-7325. The hadoop command should not accept class names starting with
|
||||||
a hyphen. (Brock Noland via todd)
|
a hyphen. (Brock Noland via todd)
|
||||||
|
|
||||||
|
HADOOP-7772. javadoc the topology classes (stevel)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
HADOOP-6884. Add LOG.isDebugEnabled() guard for each LOG.debug(..).
|
HADOOP-6884. Add LOG.isDebugEnabled() guard for each LOG.debug(..).
|
||||||
|
@ -37,14 +37,18 @@
|
|||||||
public class CachedDNSToSwitchMapping implements DNSToSwitchMapping {
|
public class CachedDNSToSwitchMapping implements DNSToSwitchMapping {
|
||||||
private Map<String, String> cache = new ConcurrentHashMap<String, String>();
|
private Map<String, String> cache = new ConcurrentHashMap<String, String>();
|
||||||
protected DNSToSwitchMapping rawMapping;
|
protected DNSToSwitchMapping rawMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cache a raw DNS mapping
|
||||||
|
* @param rawMapping the raw mapping to cache
|
||||||
|
*/
|
||||||
public CachedDNSToSwitchMapping(DNSToSwitchMapping rawMapping) {
|
public CachedDNSToSwitchMapping(DNSToSwitchMapping rawMapping) {
|
||||||
this.rawMapping = rawMapping;
|
this.rawMapping = rawMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the hosts from 'names' that have not been cached previously
|
* @param names a list of hostnames to probe for being cached
|
||||||
|
* @return the hosts from 'names' that have not been cached previously
|
||||||
*/
|
*/
|
||||||
private List<String> getUncachedHosts(List<String> names) {
|
private List<String> getUncachedHosts(List<String> names) {
|
||||||
// find out all names without cached resolved location
|
// find out all names without cached resolved location
|
||||||
@ -58,7 +62,12 @@ private List<String> getUncachedHosts(List<String> names) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches the resolved hosts
|
* Caches the resolved host:rack mappings. The two list
|
||||||
|
* parameters must be of equal size.
|
||||||
|
*
|
||||||
|
* @param uncachedHosts a list of hosts that were uncached
|
||||||
|
* @param resolvedHosts a list of resolved host entries where the element
|
||||||
|
* at index(i) is the resolved value for the entry in uncachedHosts[i]
|
||||||
*/
|
*/
|
||||||
private void cacheResolvedHosts(List<String> uncachedHosts,
|
private void cacheResolvedHosts(List<String> uncachedHosts,
|
||||||
List<String> resolvedHosts) {
|
List<String> resolvedHosts) {
|
||||||
@ -71,8 +80,9 @@ private void cacheResolvedHosts(List<String> uncachedHosts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cached resolution of the list of hostnames/addresses.
|
* @param names a list of hostnames to look up (can be be empty)
|
||||||
* Returns null if any of the names are not currently in the cache
|
* @return the cached resolution of the list of hostnames/addresses.
|
||||||
|
* or null if any of the names are not currently in the cache
|
||||||
*/
|
*/
|
||||||
private List<String> getCachedHosts(List<String> names) {
|
private List<String> getCachedHosts(List<String> names) {
|
||||||
List<String> result = new ArrayList<String>(names.size());
|
List<String> result = new ArrayList<String>(names.size());
|
||||||
@ -88,6 +98,7 @@ private List<String> getCachedHosts(List<String> names) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<String> resolve(List<String> names) {
|
public List<String> resolve(List<String> names) {
|
||||||
// normalize all input names to be in the form of IP addresses
|
// normalize all input names to be in the form of IP addresses
|
||||||
names = NetUtils.normalizeHostNames(names);
|
names = NetUtils.normalizeHostNames(names);
|
||||||
@ -97,12 +108,14 @@ public List<String> resolve(List<String> names) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> uncachedHosts = this.getUncachedHosts(names);
|
List<String> uncachedHosts = getUncachedHosts(names);
|
||||||
|
|
||||||
// Resolve the uncached hosts
|
// Resolve the uncached hosts
|
||||||
List<String> resolvedHosts = rawMapping.resolve(uncachedHosts);
|
List<String> resolvedHosts = rawMapping.resolve(uncachedHosts);
|
||||||
this.cacheResolvedHosts(uncachedHosts, resolvedHosts);
|
//cache them
|
||||||
return this.getCachedHosts(names);
|
cacheResolvedHosts(uncachedHosts, resolvedHosts);
|
||||||
|
//now look up the entire list in the cache
|
||||||
|
return getCachedHosts(names);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface that should be implemented to allow pluggable
|
* An interface that must be implemented to allow pluggable
|
||||||
* DNS-name/IP-address to RackID resolvers.
|
* DNS-name/IP-address to RackID resolvers.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -40,8 +40,9 @@ public interface DNSToSwitchMapping {
|
|||||||
* Note the hostname/ip-address is not part of the returned path.
|
* Note the hostname/ip-address is not part of the returned path.
|
||||||
* The network topology of the cluster would determine the number of
|
* The network topology of the cluster would determine the number of
|
||||||
* components in the network path.
|
* components in the network path.
|
||||||
* @param names
|
* @param names the list of hosts to resolve (can be empty)
|
||||||
* @return list of resolved network paths
|
* @return list of resolved network paths.
|
||||||
|
* If <i>names</i> is empty, the returned list is also empty
|
||||||
*/
|
*/
|
||||||
public List<String> resolve(List<String> names);
|
public List<String> resolve(List<String> names);
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ public class NetworkTopology {
|
|||||||
public static final Log LOG =
|
public static final Log LOG =
|
||||||
LogFactory.getLog(NetworkTopology.class);
|
LogFactory.getLog(NetworkTopology.class);
|
||||||
|
|
||||||
/* Inner Node represent a switch/router of a data center or rack.
|
/** InnerNode represents a switch/router of a data center or rack.
|
||||||
* Different from a leave node, it has non-null children.
|
* Different from a leaf node, it has non-null children.
|
||||||
*/
|
*/
|
||||||
private class InnerNode extends NodeBase {
|
private class InnerNode extends NodeBase {
|
||||||
private ArrayList<Node> children=new ArrayList<Node>();
|
private ArrayList<Node> children=new ArrayList<Node>();
|
||||||
@ -68,16 +68,16 @@ private class InnerNode extends NodeBase {
|
|||||||
super(name, location, parent, level);
|
super(name, location, parent, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get its children */
|
/** @return its children */
|
||||||
Collection<Node> getChildren() {return children;}
|
Collection<Node> getChildren() {return children;}
|
||||||
|
|
||||||
/** Return the number of children this node has */
|
/** @return the number of children this node has */
|
||||||
int getNumOfChildren() {
|
int getNumOfChildren() {
|
||||||
return children.size();
|
return children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Judge if this node represents a rack
|
/** Judge if this node represents a rack
|
||||||
* Return true if it has no child or its children are not InnerNodes
|
* @return true if it has no child or its children are not InnerNodes
|
||||||
*/
|
*/
|
||||||
boolean isRack() {
|
boolean isRack() {
|
||||||
if (children.isEmpty()) {
|
if (children.isEmpty()) {
|
||||||
@ -225,7 +225,11 @@ boolean remove(Node n) {
|
|||||||
}
|
}
|
||||||
} // end of remove
|
} // end of remove
|
||||||
|
|
||||||
/** Given a node's string representation, return a reference to the node */
|
/** Given a node's string representation, return a reference to the node
|
||||||
|
* @param loc string location of the form /rack/node
|
||||||
|
* @return null if the node is not found or the childnode is there but
|
||||||
|
* not an instance of {@link InnerNode}
|
||||||
|
*/
|
||||||
private Node getLoc(String loc) {
|
private Node getLoc(String loc) {
|
||||||
if (loc == null || loc.length() == 0) return this;
|
if (loc == null || loc.length() == 0) return this;
|
||||||
|
|
||||||
@ -246,7 +250,12 @@ private Node getLoc(String loc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get <i>leafIndex</i> leaf of this subtree
|
/** get <i>leafIndex</i> leaf of this subtree
|
||||||
* if it is not in the <i>excludedNode</i>*/
|
* if it is not in the <i>excludedNode</i>
|
||||||
|
*
|
||||||
|
* @param leafIndex an indexed leaf of the node
|
||||||
|
* @param excludedNode an excluded node (can be null)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private Node getLeaf(int leafIndex, Node excludedNode) {
|
private Node getLeaf(int leafIndex, Node excludedNode) {
|
||||||
int count=0;
|
int count=0;
|
||||||
// check if the excluded node a leaf
|
// check if the excluded node a leaf
|
||||||
@ -297,9 +306,14 @@ int getNumOfLeaves() {
|
|||||||
return numOfLeaves;
|
return numOfLeaves;
|
||||||
}
|
}
|
||||||
} // end of InnerNode
|
} // end of InnerNode
|
||||||
|
|
||||||
InnerNode clusterMap = new InnerNode(InnerNode.ROOT); // the root
|
/**
|
||||||
private int numOfRacks = 0; // rack counter
|
* the root cluster map
|
||||||
|
*/
|
||||||
|
InnerNode clusterMap = new InnerNode(InnerNode.ROOT);
|
||||||
|
/** rack counter */
|
||||||
|
private int numOfRacks = 0;
|
||||||
|
/** the lock used to manage access */
|
||||||
private ReadWriteLock netlock;
|
private ReadWriteLock netlock;
|
||||||
|
|
||||||
public NetworkTopology() {
|
public NetworkTopology() {
|
||||||
@ -308,8 +322,7 @@ public NetworkTopology() {
|
|||||||
|
|
||||||
/** Add a leaf node
|
/** Add a leaf node
|
||||||
* Update node counter & rack counter if necessary
|
* Update node counter & rack counter if necessary
|
||||||
* @param node
|
* @param node node to be added; can be null
|
||||||
* node to be added
|
|
||||||
* @exception IllegalArgumentException if add a node to a leave
|
* @exception IllegalArgumentException if add a node to a leave
|
||||||
or node to be added is not a leaf
|
or node to be added is not a leaf
|
||||||
*/
|
*/
|
||||||
@ -342,9 +355,8 @@ public void add(Node node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Remove a node
|
/** Remove a node
|
||||||
* Update node counter & rack counter if necessary
|
* Update node counter and rack counter if necessary
|
||||||
* @param node
|
* @param node node to be removed; can be null
|
||||||
* node to be removed
|
|
||||||
*/
|
*/
|
||||||
public void remove(Node node) {
|
public void remove(Node node) {
|
||||||
if (node==null) return;
|
if (node==null) return;
|
||||||
@ -371,8 +383,7 @@ public void remove(Node node) {
|
|||||||
|
|
||||||
/** Check if the tree contains node <i>node</i>
|
/** Check if the tree contains node <i>node</i>
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node a node
|
||||||
* a node
|
|
||||||
* @return true if <i>node</i> is already in the tree; false otherwise
|
* @return true if <i>node</i> is already in the tree; false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean contains(Node node) {
|
public boolean contains(Node node) {
|
||||||
@ -380,10 +391,11 @@ public boolean contains(Node node) {
|
|||||||
netlock.readLock().lock();
|
netlock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
Node parent = node.getParent();
|
Node parent = node.getParent();
|
||||||
for(int level=node.getLevel(); parent!=null&&level>0;
|
for (int level = node.getLevel(); parent != null && level > 0;
|
||||||
parent=parent.getParent(), level--) {
|
parent = parent.getParent(), level--) {
|
||||||
if (parent == clusterMap)
|
if (parent == clusterMap) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
netlock.readLock().unlock();
|
netlock.readLock().unlock();
|
||||||
@ -409,7 +421,7 @@ public Node getNode(String loc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the total number of racks */
|
/** @return the total number of racks */
|
||||||
public int getNumOfRacks() {
|
public int getNumOfRacks() {
|
||||||
netlock.readLock().lock();
|
netlock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@ -419,7 +431,7 @@ public int getNumOfRacks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the total number of nodes */
|
/** @return the total number of leaf nodes */
|
||||||
public int getNumOfLeaves() {
|
public int getNumOfLeaves() {
|
||||||
netlock.readLock().lock();
|
netlock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@ -432,11 +444,11 @@ public int getNumOfLeaves() {
|
|||||||
/** Return the distance between two nodes
|
/** Return the distance between two nodes
|
||||||
* It is assumed that the distance from one node to its parent is 1
|
* It is assumed that the distance from one node to its parent is 1
|
||||||
* The distance between two nodes is calculated by summing up their distances
|
* The distance between two nodes is calculated by summing up their distances
|
||||||
* to their closest common ancestor.
|
* to their closest common ancestor.
|
||||||
* @param node1 one node
|
* @param node1 one node
|
||||||
* @param node2 another node
|
* @param node2 another node
|
||||||
* @return the distance between node1 and node2
|
* @return the distance between node1 and node2 which is zero if they are the same
|
||||||
* node1 or node2 do not belong to the cluster
|
* or {@link Integer#MAX_VALUE} if node1 or node2 do not belong to the cluster
|
||||||
*/
|
*/
|
||||||
public int getDistance(Node node1, Node node2) {
|
public int getDistance(Node node1, Node node2) {
|
||||||
if (node1 == node2) {
|
if (node1 == node2) {
|
||||||
@ -477,8 +489,8 @@ public int getDistance(Node node1, Node node2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Check if two nodes are on the same rack
|
/** Check if two nodes are on the same rack
|
||||||
* @param node1 one node
|
* @param node1 one node (can be null)
|
||||||
* @param node2 another node
|
* @param node2 another node (can be null)
|
||||||
* @return true if node1 and node2 are on the same rack; false otherwise
|
* @return true if node1 and node2 are on the same rack; false otherwise
|
||||||
* @exception IllegalArgumentException when either node1 or node2 is null, or
|
* @exception IllegalArgumentException when either node1 or node2 is null, or
|
||||||
* node1 or node2 do not belong to the cluster
|
* node1 or node2 do not belong to the cluster
|
||||||
@ -622,6 +634,8 @@ static private void swap(Node[] nodes, int i, int j) {
|
|||||||
* If neither local node or local rack node is found, put a random replica
|
* If neither local node or local rack node is found, put a random replica
|
||||||
* location at position 0.
|
* location at position 0.
|
||||||
* It leaves the rest nodes untouched.
|
* It leaves the rest nodes untouched.
|
||||||
|
* @param reader the node that wishes to read a block from one of the nodes
|
||||||
|
* @param nodes the list of nodes containing data for the reader
|
||||||
*/
|
*/
|
||||||
public void pseudoSortByDistance( Node reader, Node[] nodes ) {
|
public void pseudoSortByDistance( Node reader, Node[] nodes ) {
|
||||||
int tempIndex = 0;
|
int tempIndex = 0;
|
||||||
|
@ -33,20 +33,31 @@
|
|||||||
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
|
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
|
||||||
@InterfaceStability.Unstable
|
@InterfaceStability.Unstable
|
||||||
public interface Node {
|
public interface Node {
|
||||||
/** Return the string representation of this node's network location */
|
/** @return the string representation of this node's network location */
|
||||||
public String getNetworkLocation();
|
public String getNetworkLocation();
|
||||||
/** Set the node's network location */
|
|
||||||
|
/** Set this node's network location
|
||||||
|
* @param location the location
|
||||||
|
*/
|
||||||
public void setNetworkLocation(String location);
|
public void setNetworkLocation(String location);
|
||||||
/** Return this node's name */
|
/** @return this node's name */
|
||||||
public String getName();
|
public String getName();
|
||||||
/** Return this node's parent */
|
|
||||||
|
/** @return this node's parent */
|
||||||
public Node getParent();
|
public Node getParent();
|
||||||
/** Set this node's parent */
|
|
||||||
|
/** Set this node's parent
|
||||||
|
* @param parent the parent
|
||||||
|
*/
|
||||||
public void setParent(Node parent);
|
public void setParent(Node parent);
|
||||||
/** Return this node's level in the tree.
|
|
||||||
|
/** @return this node's level in the tree.
|
||||||
* E.g. the root of a tree returns 0 and its children return 1
|
* E.g. the root of a tree returns 0 and its children return 1
|
||||||
*/
|
*/
|
||||||
public int getLevel();
|
public int getLevel();
|
||||||
/** Set this node's level in the tree.*/
|
|
||||||
|
/** Set this node's level in the tree
|
||||||
|
* @param i the level
|
||||||
|
*/
|
||||||
public void setLevel(int i);
|
public void setLevel(int i);
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,12 @@
|
|||||||
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
|
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
|
||||||
@InterfaceStability.Unstable
|
@InterfaceStability.Unstable
|
||||||
public class NodeBase implements Node {
|
public class NodeBase implements Node {
|
||||||
|
/** Path separator {@value} */
|
||||||
public final static char PATH_SEPARATOR = '/';
|
public final static char PATH_SEPARATOR = '/';
|
||||||
|
/** Path separator as a string {@value} */
|
||||||
public final static String PATH_SEPARATOR_STR = "/";
|
public final static String PATH_SEPARATOR_STR = "/";
|
||||||
public final static String ROOT = ""; // string representation of root
|
/** string representation of root {@value} */
|
||||||
|
public final static String ROOT = "";
|
||||||
|
|
||||||
protected String name; //host:port#
|
protected String name; //host:port#
|
||||||
protected String location; //string representation of this node's location
|
protected String location; //string representation of this node's location
|
||||||
@ -55,7 +58,7 @@ public NodeBase(String path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Construct a node from its name and its location
|
/** Construct a node from its name and its location
|
||||||
* @param name this node's name
|
* @param name this node's name (can be null, must not contain {@link #PATH_SEPARATOR})
|
||||||
* @param location this node's location
|
* @param location this node's location
|
||||||
*/
|
*/
|
||||||
public NodeBase(String name, String location) {
|
public NodeBase(String name, String location) {
|
||||||
@ -63,7 +66,7 @@ public NodeBase(String name, String location) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Construct a node from its name and its location
|
/** Construct a node from its name and its location
|
||||||
* @param name this node's name
|
* @param name this node's name (can be null, must not contain {@link #PATH_SEPARATOR})
|
||||||
* @param location this node's location
|
* @param location this node's location
|
||||||
* @param parent this node's parent node
|
* @param parent this node's parent node
|
||||||
* @param level this node's level in the tree
|
* @param level this node's level in the tree
|
||||||
@ -74,7 +77,11 @@ public NodeBase(String name, String location, Node parent, int level) {
|
|||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set this node's name and location */
|
/**
|
||||||
|
* set this node's name and location
|
||||||
|
* @param name the (nullable) name -which cannot contain the {@link #PATH_SEPARATOR}
|
||||||
|
* @param location the location
|
||||||
|
*/
|
||||||
private void set(String name, String location) {
|
private void set(String name, String location) {
|
||||||
if (name != null && name.contains(PATH_SEPARATOR_STR))
|
if (name != null && name.contains(PATH_SEPARATOR_STR))
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@ -83,27 +90,43 @@ private void set(String name, String location) {
|
|||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return this node's name */
|
/** @return this node's name */
|
||||||
|
@Override
|
||||||
public String getName() { return name; }
|
public String getName() { return name; }
|
||||||
|
|
||||||
/** Return this node's network location */
|
/** @return this node's network location */
|
||||||
|
@Override
|
||||||
public String getNetworkLocation() { return location; }
|
public String getNetworkLocation() { return location; }
|
||||||
|
|
||||||
/** Set this node's network location */
|
/** Set this node's network location
|
||||||
|
* @param location the location
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void setNetworkLocation(String location) { this.location = location; }
|
public void setNetworkLocation(String location) { this.location = location; }
|
||||||
|
|
||||||
/** Return this node's path */
|
/**
|
||||||
|
* Get the path of a node
|
||||||
|
* @param node a non-null node
|
||||||
|
* @return the path of a node
|
||||||
|
*/
|
||||||
public static String getPath(Node node) {
|
public static String getPath(Node node) {
|
||||||
return node.getNetworkLocation()+PATH_SEPARATOR_STR+node.getName();
|
return node.getNetworkLocation()+PATH_SEPARATOR_STR+node.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return this node's string representation */
|
/** @return this node's path as its string representation */
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getPath(this);
|
return getPath(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Normalize a path */
|
/** Normalize a path by stripping off any trailing {@link #PATH_SEPARATOR}
|
||||||
static public String normalize(String path) {
|
* @param path path to normalize.
|
||||||
|
* @return the normalised path
|
||||||
|
* If <i>path</i>is null or empty {@link #ROOT} is returned
|
||||||
|
* @throws IllegalArgumentException if the first character of a non empty path
|
||||||
|
* is not {@link #PATH_SEPARATOR}
|
||||||
|
*/
|
||||||
|
public static String normalize(String path) {
|
||||||
if (path == null || path.length() == 0) return ROOT;
|
if (path == null || path.length() == 0) return ROOT;
|
||||||
|
|
||||||
if (path.charAt(0) != PATH_SEPARATOR) {
|
if (path.charAt(0) != PATH_SEPARATOR) {
|
||||||
@ -119,20 +142,28 @@ static public String normalize(String path) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return this node's parent */
|
/** @return this node's parent */
|
||||||
|
@Override
|
||||||
public Node getParent() { return parent; }
|
public Node getParent() { return parent; }
|
||||||
|
|
||||||
/** Set this node's parent */
|
/** Set this node's parent
|
||||||
|
* @param parent the parent
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void setParent(Node parent) {
|
public void setParent(Node parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return this node's level in the tree.
|
/** @return this node's level in the tree.
|
||||||
* E.g. the root of a tree returns 0 and its children return 1
|
* E.g. the root of a tree returns 0 and its children return 1
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public int getLevel() { return level; }
|
public int getLevel() { return level; }
|
||||||
|
|
||||||
/** Set this node's level in the tree */
|
/** Set this node's level in the tree
|
||||||
|
* @param level the level
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void setLevel(int level) {
|
public void setLevel(int level) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements the {@link DNSToSwitchMapping} interface using a
|
* This class implements the {@link DNSToSwitchMapping} interface using a
|
||||||
* script configured via net.topology.script.file.name .
|
* script configured via the {@link CommonConfigurationKeys#NET_TOPOLOGY_SCRIPT_FILE_NAME_KEY}
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Public
|
@InterfaceAudience.Public
|
||||||
@InterfaceStability.Evolving
|
@InterfaceStability.Evolving
|
||||||
@ -42,50 +42,86 @@ public final class ScriptBasedMapping extends CachedDNSToSwitchMapping
|
|||||||
public ScriptBasedMapping() {
|
public ScriptBasedMapping() {
|
||||||
super(new RawScriptBasedMapping());
|
super(new RawScriptBasedMapping());
|
||||||
}
|
}
|
||||||
|
|
||||||
// script must accept at least this many args
|
/**
|
||||||
|
* Minimum number of arguments: {@value}
|
||||||
|
*/
|
||||||
static final int MIN_ALLOWABLE_ARGS = 1;
|
static final int MIN_ALLOWABLE_ARGS = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default number of arguments: {@value}
|
||||||
|
*/
|
||||||
static final int DEFAULT_ARG_COUNT =
|
static final int DEFAULT_ARG_COUNT =
|
||||||
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_NUMBER_ARGS_DEFAULT;
|
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_NUMBER_ARGS_DEFAULT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key to the script filename {@value}
|
||||||
|
*/
|
||||||
static final String SCRIPT_FILENAME_KEY =
|
static final String SCRIPT_FILENAME_KEY =
|
||||||
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_FILE_NAME_KEY ;
|
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_FILE_NAME_KEY ;
|
||||||
static final String SCRIPT_ARG_COUNT_KEY =
|
/**
|
||||||
|
* key to the argument count that the script supports
|
||||||
|
*/
|
||||||
|
static final String SCRIPT_ARG_COUNT_KEY =
|
||||||
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_NUMBER_ARGS_KEY ;
|
CommonConfigurationKeys.NET_TOPOLOGY_SCRIPT_NUMBER_ARGS_KEY ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance from the given configuration
|
||||||
|
* @param conf configuration
|
||||||
|
*/
|
||||||
public ScriptBasedMapping(Configuration conf) {
|
public ScriptBasedMapping(Configuration conf) {
|
||||||
this();
|
this();
|
||||||
setConf(conf);
|
setConf(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Configuration getConf() {
|
public Configuration getConf() {
|
||||||
return ((RawScriptBasedMapping)rawMapping).getConf();
|
return ((RawScriptBasedMapping)rawMapping).getConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setConf(Configuration conf) {
|
public void setConf(Configuration conf) {
|
||||||
((RawScriptBasedMapping)rawMapping).setConf(conf);
|
((RawScriptBasedMapping)rawMapping).setConf(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the uncached script mapping that is fed into the cache managed
|
||||||
|
* by the superclass {@link CachedDNSToSwitchMapping}
|
||||||
|
*/
|
||||||
private static final class RawScriptBasedMapping
|
private static final class RawScriptBasedMapping
|
||||||
implements DNSToSwitchMapping {
|
implements DNSToSwitchMapping {
|
||||||
private String scriptName;
|
private String scriptName;
|
||||||
private Configuration conf;
|
private Configuration conf;
|
||||||
private int maxArgs; //max hostnames per call of the script
|
private int maxArgs; //max hostnames per call of the script
|
||||||
private static Log LOG =
|
private static Log LOG =
|
||||||
LogFactory.getLog(ScriptBasedMapping.class);
|
LogFactory.getLog(ScriptBasedMapping.class);
|
||||||
public void setConf (Configuration conf) {
|
|
||||||
this.scriptName = conf.get(SCRIPT_FILENAME_KEY);
|
/**
|
||||||
this.maxArgs = conf.getInt(SCRIPT_ARG_COUNT_KEY, DEFAULT_ARG_COUNT);
|
* Set the configuration and
|
||||||
this.conf = conf;
|
* @param conf extract the configuration parameters of interest
|
||||||
}
|
*/
|
||||||
public Configuration getConf () {
|
public void setConf (Configuration conf) {
|
||||||
return conf;
|
this.scriptName = conf.get(SCRIPT_FILENAME_KEY);
|
||||||
}
|
this.maxArgs = conf.getInt(SCRIPT_ARG_COUNT_KEY, DEFAULT_ARG_COUNT);
|
||||||
|
this.conf = conf;
|
||||||
public RawScriptBasedMapping() {}
|
}
|
||||||
|
|
||||||
public List<String> resolve(List<String> names) {
|
/**
|
||||||
|
* Get the configuration
|
||||||
|
* @return the configuration
|
||||||
|
*/
|
||||||
|
public Configuration getConf () {
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The mapping is not ready to use until
|
||||||
|
* {@link #setConf(Configuration)} has been called
|
||||||
|
*/
|
||||||
|
public RawScriptBasedMapping() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> resolve(List<String> names) {
|
||||||
List <String> m = new ArrayList<String>(names.size());
|
List <String> m = new ArrayList<String>(names.size());
|
||||||
|
|
||||||
if (names.isEmpty()) {
|
if (names.isEmpty()) {
|
||||||
@ -123,45 +159,53 @@ public List<String> resolve(List<String> names) {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String runResolveCommand(List<String> args) {
|
/**
|
||||||
int loopCount = 0;
|
* Build and execute the resolution command. The command is
|
||||||
if (args.size() == 0) {
|
* executed in the directory specified by the system property
|
||||||
return null;
|
* "user.dir" if set; otherwise the current working directory is used
|
||||||
}
|
* @param args a list of arguments
|
||||||
StringBuilder allOutput = new StringBuilder();
|
* @return null if the number of arguments is out of range,
|
||||||
int numProcessed = 0;
|
* or the output of the command.
|
||||||
if (maxArgs < MIN_ALLOWABLE_ARGS) {
|
*/
|
||||||
LOG.warn("Invalid value " + Integer.toString(maxArgs)
|
private String runResolveCommand(List<String> args) {
|
||||||
+ " for " + SCRIPT_ARG_COUNT_KEY + "; must be >= "
|
int loopCount = 0;
|
||||||
+ Integer.toString(MIN_ALLOWABLE_ARGS));
|
if (args.size() == 0) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (numProcessed != args.size()) {
|
|
||||||
int start = maxArgs * loopCount;
|
|
||||||
List <String> cmdList = new ArrayList<String>();
|
|
||||||
cmdList.add(scriptName);
|
|
||||||
for (numProcessed = start; numProcessed < (start + maxArgs) &&
|
|
||||||
numProcessed < args.size(); numProcessed++) {
|
|
||||||
cmdList.add(args.get(numProcessed));
|
|
||||||
}
|
|
||||||
File dir = null;
|
|
||||||
String userDir;
|
|
||||||
if ((userDir = System.getProperty("user.dir")) != null) {
|
|
||||||
dir = new File(userDir);
|
|
||||||
}
|
|
||||||
ShellCommandExecutor s = new ShellCommandExecutor(
|
|
||||||
cmdList.toArray(new String[0]), dir);
|
|
||||||
try {
|
|
||||||
s.execute();
|
|
||||||
allOutput.append(s.getOutput() + " ");
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.warn("Exception: ", e);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
loopCount++;
|
StringBuilder allOutput = new StringBuilder();
|
||||||
|
int numProcessed = 0;
|
||||||
|
if (maxArgs < MIN_ALLOWABLE_ARGS) {
|
||||||
|
LOG.warn("Invalid value " + Integer.toString(maxArgs)
|
||||||
|
+ " for " + SCRIPT_ARG_COUNT_KEY + "; must be >= "
|
||||||
|
+ Integer.toString(MIN_ALLOWABLE_ARGS));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (numProcessed != args.size()) {
|
||||||
|
int start = maxArgs * loopCount;
|
||||||
|
List<String> cmdList = new ArrayList<String>();
|
||||||
|
cmdList.add(scriptName);
|
||||||
|
for (numProcessed = start; numProcessed < (start + maxArgs) &&
|
||||||
|
numProcessed < args.size(); numProcessed++) {
|
||||||
|
cmdList.add(args.get(numProcessed));
|
||||||
|
}
|
||||||
|
File dir = null;
|
||||||
|
String userDir;
|
||||||
|
if ((userDir = System.getProperty("user.dir")) != null) {
|
||||||
|
dir = new File(userDir);
|
||||||
|
}
|
||||||
|
ShellCommandExecutor s = new ShellCommandExecutor(
|
||||||
|
cmdList.toArray(new String[0]), dir);
|
||||||
|
try {
|
||||||
|
s.execute();
|
||||||
|
allOutput.append(s.getOutput() + " ");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warn("Exception: ", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
loopCount++;
|
||||||
|
}
|
||||||
|
return allOutput.toString();
|
||||||
}
|
}
|
||||||
return allOutput.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user