package org.sdnplatform.sync.internal.config;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.sdnplatform.sync.error.SyncException;
/**
* Represent the configuration of a cluster in the sync manager
* @author readams
*/
public class ClusterConfig {
private HashMap<Short, Node> allNodes =
new HashMap<Short, Node>();
private HashMap<Short, List<Node>> localDomains =
new HashMap<Short, List<Node>>();
private Node thisNode;
private AuthScheme authScheme;
private String keyStorePath;
private String keyStorePassword;
private String listenAddress;
public ClusterConfig() {
super();
}
/**
* Initialize a cluster config using a list of nodes
* @param nodes the nodes to use
* @param thisNodeId the node ID for the current node
* @throws SyncException
*/
public ClusterConfig(List<Node> nodes, short thisNodeId)
throws SyncException {
init(nodes, thisNodeId, AuthScheme.NO_AUTH, null, null);
}
/**
* Initialize a cluster config using a list of nodes
* @param nodes the nodes to use
* @param thisNodeId the node ID for the current node
* @param authScheme the {@link AuthScheme}
* @param keyStorePath the path to a java key store containing
* credentials necessary for implementing the {@link AuthScheme}
* @param keyStorePassword the password for the key store.
* @throws SyncException
*/
public ClusterConfig(List<Node> nodes, short thisNodeId,
AuthScheme authScheme,
String keyStorePath,
String keyStorePassword)
throws SyncException {
init(nodes, thisNodeId, authScheme, keyStorePath, keyStorePassword);
}
/**
* Initialize a cluster config using a list of nodes
* @param nodes the nodes to use
* @param thisNodeId the node ID for the current node
* @param listenAddress String representing the address to listen on
* @param authScheme the {@link AuthScheme}
* @param keyStorePath the path to a java key store containing
* credentials necessary for implementing the {@link AuthScheme}
* @param keyStorePassword the password for the key store.
* @throws SyncException
*/
public ClusterConfig(List<Node> nodes, short thisNodeId,
String listenAddress,
AuthScheme authScheme,
String keyStorePath,
String keyStorePassword)
throws SyncException {
init(nodes, thisNodeId, authScheme, keyStorePath, keyStorePassword);
this.listenAddress = listenAddress;
}
/**
* Get a collection containing all configured nodes
* @return the collection of nodes
*/
public Collection<Node> getNodes() {
return Collections.unmodifiableCollection(allNodes.values());
}
/**
* A collection of the nodes in the local domain for the current node
* @return the list of nodes
*/
public Collection<Node> getDomainNodes() {
return getDomainNodes(thisNode.getDomainId());
}
/**
* A collection of the nodes in the local domain specified
* @param domainId the domain ID
* @return the list of nodes
*/
public Collection<Node> getDomainNodes(short domainId) {
List<Node> r = localDomains.get(domainId);
return Collections.unmodifiableCollection(r);
}
/**
* Get the {@link Node} object for the current node
*/
public Node getNode() {
return thisNode;
}
/**
* The a list of the nodes in the local domain specified
* @param nodeId the node ID to retrieve
* @return the node (or null if there is no such node
*/
public Node getNode(short nodeId) {
return allNodes.get(nodeId);
}
/**
* Get a string representing the host/address on which the local
* node should listen
* @return the listen address
*/
public String getListenAddress() {
return listenAddress;
}
/**
* Get the authentication scheme to use for authenticating RPC connections
* @return the {@link AuthScheme} object
*/
public AuthScheme getAuthScheme() {
return authScheme;
}
/**
* Get the key store path where credentials can be found
* @return the path to a java {@link KeyStore} containing necessary
* credentials
* @see ClusterConfig#getKeyStorePassword()
*/
public String getKeyStorePath() {
return keyStorePath;
}
/**
* Get the password for reading data from the {@link KeyStore} returned
* by {@link ClusterConfig#getKeyStorePath()}
* @return the password
* @see ClusterConfig#getKeyStorePath()
*/
public String getKeyStorePassword() {
return keyStorePassword;
}
/**
* Add a new node to the cluster
* @param node the {@link Node} to add
* @throws SyncException if the node already exists
*/
private void addNode(Node node) throws SyncException {
Short nodeId = node.getNodeId();
if (allNodes.get(nodeId) != null) {
throw new SyncException("Error adding node " + node +
": a node with that ID already exists");
}
allNodes.put(nodeId, node);
Short domainId = node.getDomainId();
List<Node> localDomain = localDomains.get(domainId);
if (localDomain == null) {
localDomains.put(domainId,
localDomain = new ArrayList<Node>());
}
localDomain.add(node);
}
private void init(List<Node> nodes, short thisNodeId,
AuthScheme authScheme,
String keyStorePath,
String keyStorePassword)
throws SyncException {
for (Node n : nodes) {
addNode(n);
}
thisNode = getNode(thisNodeId);
if (thisNode == null) {
throw new SyncException("Cannot set thisNode " +
"node: No node with ID " + thisNodeId);
}
this.authScheme = authScheme;
if (this.authScheme == null)
this.authScheme = AuthScheme.NO_AUTH;
this.keyStorePath = keyStorePath;
this.keyStorePassword = keyStorePassword;
}
@Override
public String toString() {
return "ClusterConfig [allNodes=" + allNodes + ", authScheme="
+ authScheme + ", keyStorePath=" + keyStorePath
+ ", keyStorePassword is " +
(keyStorePassword == null ? "unset" : "set") + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((allNodes == null) ? 0 : allNodes.hashCode());
result = prime * result
+ ((authScheme == null) ? 0 : authScheme.hashCode());
result = prime
* result
+ ((keyStorePassword == null) ? 0
: keyStorePassword.hashCode());
result = prime * result
+ ((keyStorePath == null) ? 0 : keyStorePath.hashCode());
result = prime * result
+ ((localDomains == null) ? 0 : localDomains.hashCode());
result = prime * result
+ ((thisNode == null) ? 0 : thisNode.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ClusterConfig other = (ClusterConfig) obj;
if (allNodes == null) {
if (other.allNodes != null) return false;
} else if (!allNodes.equals(other.allNodes)) return false;
if (authScheme != other.authScheme) return false;
if (keyStorePassword == null) {
if (other.keyStorePassword != null) return false;
} else if (!keyStorePassword.equals(other.keyStorePassword))
return false;
if (keyStorePath == null) {
if (other.keyStorePath != null) return false;
} else if (!keyStorePath.equals(other.keyStorePath)) return false;
if (thisNode == null) {
if (other.thisNode != null) return false;
} else if (!thisNode.equals(other.thisNode)) return false;
return true;
}
}