Skip to content
This repository has been archived by the owner on Sep 23, 2020. It is now read-only.

Commit

Permalink
Admin client improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
labisso committed Oct 14, 2010
1 parent 2d48d6a commit 7287cb8
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 36 deletions.
Expand Up @@ -58,4 +58,15 @@ public String getNetworkAssociations() {
public boolean isVacant() {
return vacant;
}

@Override
public String toString() {
return "VmmNode{" +
"hostname='" + hostname + '\'' +
", poolName='" + poolName + '\'' +
", memory=" + memory +
", networkAssociations='" + networkAssociations + '\'' +
", vacant=" + vacant +
'}';
}
}
Expand Up @@ -60,12 +60,16 @@ public class AdminClient {


final static String[] NODE_FIELDS = new String[] {
FIELD_HOSTNAME, FIELD_POOL, FIELD_MEMORY,
FIELD_NETWORKS, FIELD_IN_USE
};
FIELD_HOSTNAME, FIELD_POOL, FIELD_MEMORY, FIELD_NETWORKS,
FIELD_IN_USE };

final static String[] NODE_REPORT_FIELDS =
new String[] {FIELD_STATUS, FIELD_HOSTNAME};

final static String[] NODE_REPORT_FIELDS = new String[] {
FIELD_HOSTNAME, FIELD_STATUS, FIELD_POOL,
FIELD_MEMORY, FIELD_NETWORKS, FIELD_IN_USE };

final static String[] NODE_REPORT_FIELDS_SHORT = new String[] {
FIELD_HOSTNAME, FIELD_STATUS };

private final Gson gson = new Gson();

Expand All @@ -78,7 +82,6 @@ public class AdminClient {
private String configPath;
private boolean debug;
private File socketDirectory;
private RemotingClient remotingClient;
private String nodePoolBindingName;
private RemoteNodeManagement remoteNodeManagement;
private Reporter reporter;
Expand Down Expand Up @@ -135,11 +138,11 @@ public static void main(String args[]) {
}

if (paramError != null) {
System.err.println("Parameter Problem: " + paramError.getMessage());
System.err.println("Parameter Problem:\n" + paramError.getMessage());
System.err.println("See --help");

} else if (execError != null) {
System.err.println("Execution Problem: " + execError.getMessage());
System.err.println("Execution Problem:\n" + execError.getMessage());
} else {
System.err.println("An unexpected error was encountered. Please report this!");
System.err.println(anyError.getMessage());
Expand Down Expand Up @@ -238,28 +241,42 @@ private void run_listNodes() throws ExecutionProblem {
}

private void run_removeNodes() throws ExecutionProblem {
NodeReport[] reports = null;
try {
final String[] hostnames = this.hosts.toArray(new String[this.hosts.size()]);
this.remoteNodeManagement.removeNodes(hostnames);
final String reportJson = this.remoteNodeManagement.removeNodes(hostnames);
reports = gson.fromJson(reportJson, NodeReport[].class);
} catch (RemoteException e) {
handleRemoteException(e);
}

try {
reporter.report(nodeReportsToMaps(reports), System.out);
} catch (IOException e) {
throw new ExecutionProblem("Problem writing output: " + e.getMessage(), e);
}
}

private void run_updateNodes() throws ExecutionProblem {

//TODO

final List<VmmNode> nodes = new ArrayList<VmmNode>(this.hosts.size());
for (String hostname : this.hosts) {
nodes.add(new VmmNode(hostname, this.nodePool,
this.nodeMemory, this.nodeNetworks, true));
}
NodeReport[] reports = null;
try {
this.remoteNodeManagement.updateNodes(gson.toJson(nodes));
final String reportJson = this.remoteNodeManagement.updateNodes(gson.toJson(nodes));
reports = gson.fromJson(reportJson, NodeReport[].class);
} catch (RemoteException e) {
handleRemoteException(e);
}

try {
reporter.report(nodeReportsToMaps(reports), System.out);
} catch (IOException e) {
throw new ExecutionProblem("Problem writing output: " + e.getMessage(), e);
}
}

private void setupRemoting() throws ExecutionProblem {
Expand All @@ -272,8 +289,6 @@ private void setupRemoting() throws ExecutionProblem {
handleRemoteException(e);
}

this.remotingClient = client;

try {
final Remote remote = client.lookup(this.nodePoolBindingName);
logger.debug("Found remote object " + remote.toString());
Expand Down Expand Up @@ -345,21 +360,25 @@ private void loadConfig(String configPath)
}
this.nodePoolBindingName = nodePoolBinding;

if (!this.nodeMemoryConfigured) {
final String memString = props.getProperty(PROP_DEFAULT_MEMORY);
if (memString != null) {
this.nodeMemory = parseMemory(memString);
this.nodeMemoryConfigured = true;

// only need node parameter values if doing add-nodes
if (this.action == AdminAction.AddNodes) {
if (!this.nodeMemoryConfigured) {
final String memString = props.getProperty(PROP_DEFAULT_MEMORY);
if (memString != null) {
this.nodeMemory = parseMemory(memString);
this.nodeMemoryConfigured = true;
}
}
}

if (this.nodeNetworks == null) {
this.nodeNetworks = props.getProperty(PROP_DEFAULT_NETWORKS);
}
if (this.nodeNetworks == null) {
this.nodeNetworks = props.getProperty(PROP_DEFAULT_NETWORKS);
}

if (this.nodePool == null) {
// if missing or invalid, error will come later if this value is actually needed
this.nodePool = props.getProperty(PROP_DEFAULT_POOL);
if (this.nodePool == null) {
// if missing or invalid, error will come later if this value is actually needed
this.nodePool = props.getProperty(PROP_DEFAULT_POOL);
}
}
}

Expand Down Expand Up @@ -584,20 +603,30 @@ private static Map<String,String> nodeReportToMap(NodeReport nodeReport) {
new HashMap<String, String>(2);
map.put(FIELD_HOSTNAME, nodeReport.getHostname());
map.put(FIELD_STATUS, nodeReport.getState());
final VmmNode node = nodeReport.getNode();
if (node == null) {
map.put(FIELD_POOL, null);
map.put(FIELD_MEMORY, null);
map.put(FIELD_NETWORKS, null);
map.put(FIELD_IN_USE, null);
} else {
map.put(FIELD_POOL, node.getPoolName());
map.put(FIELD_MEMORY, String.valueOf(node.getMemory()));
map.put(FIELD_NETWORKS, node.getNetworkAssociations());
map.put(FIELD_IN_USE, String.valueOf(!node.isVacant()));
}
return map;
}
}

enum AdminAction {

AddNodes(Opts.ADD_NODES, AdminClient.NODE_REPORT_FIELDS),
ListNodes(Opts.LIST_NODES, AdminClient.NODE_FIELDS),
RemoveNodes(Opts.REMOVE_NODES, AdminClient.NODE_REPORT_FIELDS),
RemoveNodes(Opts.REMOVE_NODES, AdminClient.NODE_REPORT_FIELDS_SHORT),
UpdateNodes(Opts.UPDATE_NODES, AdminClient.NODE_REPORT_FIELDS),
Help(Opts.HELP, null);



private final String option;
private final String[] fields;

Expand Down
Expand Up @@ -25,7 +25,7 @@

class Reporter {

public static final String DEFAULT_DELIMITER = ",";
public static final String DEFAULT_DELIMITER = " ";

private final Gson gson;

Expand All @@ -50,7 +50,8 @@ public Reporter(OutputMode mode, String[] fields, String delimiter) {
}

if (mode == OutputMode.Json) {
this.gson = new GsonBuilder().setPrettyPrinting().create();
this.gson = new GsonBuilder().setPrettyPrinting().
serializeNulls().create();
} else {
this.gson = null;
}
Expand Down Expand Up @@ -114,12 +115,18 @@ private void _report(Map<String, String> entry, OutputStreamWriter writer, int k
if (this.mode == OutputMode.Friendly) {
final String formatString = "%1$-" + keyLength + "s : ";
for (Map.Entry<String, String> pair : entry.entrySet()) {
final String key = String.format(formatString, pair.getKey());
writer.append(key).append(pair.getValue()).append("\n");
// skip output of null value entries
if (pair.getValue() != null) {
final String key = String.format(formatString, pair.getKey());
writer.append(key).append(pair.getValue()).append("\n");
}
}
} else if (this.mode == OutputMode.Batch) {
boolean first = true;
for (String value : entry.values()) {
if (value == null) {
value = "";
}
if (first) {
first = false;
} else {
Expand All @@ -144,10 +151,10 @@ private static LinkedHashMap<String, String> _filterMap(Map<String,String> src,
throw new IllegalArgumentException("destination map is not empty!");
}
for (String field : fields) {
final String value = src.get(field);
if (value == null) {
if (!src.containsKey(field)) {
throw new IllegalArgumentException("map is missing '"+field+"' field");
}
final String value = src.get(field);
dest.put(field, value);
}
return dest;
Expand Down
Expand Up @@ -17,6 +17,8 @@

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.globus.workspace.remoting.admin.NodeReport;
import org.globus.workspace.remoting.admin.RemoteNodeManagement;
import org.globus.workspace.remoting.admin.VmmNode;
Expand All @@ -31,6 +33,10 @@
import java.util.List;

public class DefaultRemoteNodeManagement implements RemoteNodeManagement {

private static final Log logger =
LogFactory.getLog(DefaultRemoteNodeManagement.class.getName());

private final Gson gson;
private final TypeToken<Collection<VmmNode>> vmmNodeCollectionTypeToken;

Expand All @@ -48,12 +54,28 @@ public void initialize() throws Exception {
}

public String addNodes(String nodeJson) throws RemoteException {

if (nodeJson == null) {
throw new IllegalArgumentException("nodeJson may not be null");
}

Collection<VmmNode> nodes = gson.fromJson(nodeJson,
vmmNodeCollectionTypeToken.getType());

if (nodes == null || nodes.isEmpty()) {
throw new IllegalArgumentException(
"you must specify at least one node to add");
}

List<NodeReport> reports = new ArrayList<NodeReport>(nodes.size());
for (VmmNode node : nodes) {
final String hostname = node.getHostname();
String hostname = node.getHostname();

if (hostname == null) {
throw new IllegalArgumentException("hostname may not be null");
}

logger.info("Adding VMM node " + hostname);

try {
final ResourcepoolEntry entry =
Expand All @@ -67,6 +89,7 @@ public String addNodes(String nodeJson) throws RemoteException {
NodeReport.STATE_ADDED, resultNode));

} catch (NodeExistsException e) {
logger.info("VMM node " + hostname + " already existed");
reports.add(new NodeReport(hostname,
NodeReport.STATE_NODE_EXISTS, null));
}
Expand All @@ -76,6 +99,8 @@ public String addNodes(String nodeJson) throws RemoteException {

public String listNodes() {

logger.debug("Listing VMM nodes");

final List<ResourcepoolEntry> entries = nodeManagement.getNodes();
final List<VmmNode> nodes = new ArrayList<VmmNode>(entries.size());
for (ResourcepoolEntry entry : entries) {
Expand All @@ -87,22 +112,44 @@ public String listNodes() {

public String getNode(String hostname) {

if (hostname == null) {
throw new IllegalArgumentException("hostname may not be null");
}

logger.debug("Listing VMM node " + hostname);


final ResourcepoolEntry entry = nodeManagement.getNode(hostname);
return gson.toJson(translateResourcepoolEntry(entry));
}

public String updateNodes(String nodeJson) {
if (nodeJson == null) {
throw new IllegalArgumentException("nodeJson may not be null");
}
final Collection<VmmNode> nodes = gson.fromJson(nodeJson,
this.vmmNodeCollectionTypeToken.getType());

if (nodes.isEmpty()) {
throw new IllegalArgumentException(
"You must specify at least one VMM node to update");
}

List<NodeReport> reports = new ArrayList<NodeReport>(nodes.size());
for (VmmNode node : nodes) {
if (node == null) {
throw new IllegalArgumentException("update request has null node");
}
final String hostname = node.getHostname();

logger.info("Updating VMM node: " + node.toString());

try {
nodeManagement.updateNode(translateVmmNode(node));
reports.add(new NodeReport(hostname, NodeReport.STATE_UPDATED,
node));
} catch (NodeInUseException e) {
logger.info("VMM node was in use, failed to update: " + hostname);
reports.add(
new NodeReport(hostname,
NodeReport.STATE_NODE_IN_USE, null));
Expand All @@ -118,6 +165,14 @@ public String removeNode(String hostname) {
}

private NodeReport _removeNode(String hostname) {
if (hostname == null) {
throw new IllegalArgumentException("hostname may not be null");
}
hostname = hostname.trim();
if (hostname.length() == 0) {
throw new IllegalArgumentException("hostname may not be empty");
}
logger.info("Removing VMM node: " + hostname);
String state;
try {

Expand All @@ -134,6 +189,9 @@ private NodeReport _removeNode(String hostname) {
}

public String removeNodes(String[] hostnames) {
if (hostnames == null || hostnames.length == 0) {
throw new IllegalArgumentException("hostnames may not be null or empty");
}
List<NodeReport> reports = new ArrayList<NodeReport>(hostnames.length);
for (String hostname : hostnames) {
reports.add(this._removeNode(hostname));
Expand Down

0 comments on commit 7287cb8

Please sign in to comment.