package voldemort.tools;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import voldemort.VoldemortApplicationException;
import voldemort.cluster.Cluster;
import voldemort.server.VoldemortConfig;
import voldemort.server.VoldemortServer;
import voldemort.utils.Utils;
import voldemort.xml.ClusterMapper;
import com.google.common.io.Files;
public class ValidateNodeIdCLI {
private static OptionParser setupParser() {
OptionParser parser = new OptionParser();
parser.accepts("help", "Print usage information").withOptionalArg();
parser.acceptsAll(Arrays.asList("id", "nodeId"), "expected node Id")
.withRequiredArg()
.describedAs("expected node Id")
.ofType(String.class);
parser.acceptsAll(Arrays.asList("path", "clusterPath"), "clusterPath")
.withRequiredArg()
.describedAs("clusterPath")
.ofType(String.class);
return parser;
}
private static void printUsage() {
StringBuilder help = new StringBuilder();
help.append("ValidateNodeIdCLI\n");
help.append(" Validate if the auto detection agrees with the expected node Id \n");
help.append("Options:\n");
help.append(" Required:\n");
help.append(" --id <expected nodeId>\n");
help.append(" --path <comma separated list of file paths>\n");
System.out.print(help.toString());
}
private static void printUsageAndDie(String errMessage) {
printUsage();
Utils.croak("\n" + errMessage);
}
public static String getFilePath(OptionSet options, String name) {
String path = (String) options.valueOf(name);
return path.replace("~", System.getProperty("user.home"));
}
private static Cluster getCluster(File clusterXML) throws IOException {
return new ClusterMapper().readCluster(clusterXML);
}
private static String getTempDirPath() {
File tempdir = Files.createTempDir();
tempdir.delete();
tempdir.mkdir();
tempdir.deleteOnExit();
return tempdir.getAbsolutePath();
}
public static void main(String[] args) throws IOException {
OptionParser parser = null;
OptionSet options = null;
try {
parser = setupParser();
options = parser.parse(args);
} catch(OptionException oe) {
parser.printHelpOn(System.out);
printUsageAndDie("Exception when parsing arguments : " + oe.getMessage());
return;
}
/* validate options */
if(options.has("help")) {
printUsage();
return;
}
if(!options.hasArgument("id") || !options.hasArgument("path")) {
printUsageAndDie("Missing a required argument.");
return;
}
String id = (String) options.valueOf("id");
int expectedNodeId = Integer.parseInt(id);
String clusterPaths = getFilePath(options, "path");
String[] allPaths = clusterPaths.split(",");
boolean isMatch = false;
for(String path: allPaths) {
path = path.replace("~", System.getProperty("user.home"));
File filePath = new File(path);
if(filePath.exists()) {
isMatch = true;
Cluster cluster = getCluster(filePath);
Properties properties = new Properties();
properties.setProperty(VoldemortConfig.ENABLE_NODE_ID_DETECTION,
Boolean.toString(true));
properties.setProperty(VoldemortConfig.VOLDEMORT_HOME, getTempDirPath());
VoldemortConfig config = new VoldemortConfig(properties);
int actualNodeId = VoldemortServer.getNodeId(config, cluster);
if(actualNodeId != expectedNodeId) {
throw new VoldemortApplicationException("Mismatch detected. Computed Node Id "
+ actualNodeId + " Expected "
+ expectedNodeId);
} else {
System.out.println("Expected and Computed node Id matched " + expectedNodeId);
}
config.setNodeId(actualNodeId);
VoldemortServer.validateNodeId(config, cluster);
System.out.println("Validation of node Id passed");
}
}
if(!isMatch) {
throw new VoldemortApplicationException("None of the paths matched the cluster.xml");
}
}
}