use of voldemort.client.protocol.admin.AdminClient in project voldemort by voldemort.
the class ZonedRebalanceNonContiguousZonesTest method testProxyPutDuringRebalancing.
@Test(timeout = 600000)
public void testProxyPutDuringRebalancing() throws Exception {
logger.info("Starting testProxyPutDuringRebalancing");
try {
int[] zoneIds = new int[] { 1, 3 };
int[][] nodesPerZone = new int[][] { { 3, 4, 5 }, { 9, 10, 11 } };
int[][] partitionMap = new int[][] { { 0 }, { 1, 6 }, { 2 }, { 3 }, { 4, 7 }, { 5 } };
Cluster currentCluster = ServerTestUtils.getLocalNonContiguousZonedCluster(zoneIds, nodesPerZone, partitionMap, ClusterTestUtils.getClusterPorts());
Cluster finalCluster = UpdateClusterUtils.createUpdatedCluster(currentCluster, 5, Lists.newArrayList(7));
finalCluster = UpdateClusterUtils.createUpdatedCluster(finalCluster, 11, Lists.newArrayList(6));
/**
* Original partition map
*
* [s3 : p0] [s4 : p1, p6] [s5 : p2]
*
* [s9 : p3] [s10 : p4, p7] [s11 : p5]
*
* final server partition ownership
*
* [s3 : p0] [s4 : p1] [s5 : p2, p7]
*
* [s9 : p3] [s10 : p4] [s11 : p5, p6]
*
* Note that rwStoreDefFileWithReplication is a "2/1/1" store def.
*
* Original server n-ary partition ownership
*
* [s3 : p0, p3-7] [s4 : p0-p7] [s5 : p1-2]
*
* [s9 : p0-3, p6-7] [s10 : p0-p7] [s11 : p4-5]
*
* final server n-ary partition ownership
*
* [s3 : p0, p2-7] [s4 : p0-1] [s5 : p1-p7]
*
* [s9 : p0-3, p5-7] [s10 : p0-4, p7] [s11 : p4-6]
*/
List<Integer> serverList = Arrays.asList(3, 4, 5, 9, 10, 11);
Map<String, String> configProps = new HashMap<String, String>();
configProps.put("admin.max.threads", "5");
final Cluster updatedCurrentCluster = startServers(currentCluster, rwStoreDefFileWithReplication, serverList, configProps);
ExecutorService executors = Executors.newFixedThreadPool(2);
final AtomicBoolean rebalancingComplete = new AtomicBoolean(false);
final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());
// Its is imperative that we test in a single shot since multiple batches would mean the proxy bridges
// being torn down and established multiple times and we cannot test against the source
// cluster topology then. getRebalanceKit uses batch size of infinite, so this should be fine.
String bootstrapUrl = getBootstrapUrl(updatedCurrentCluster, 3);
int maxParallel = 2;
final ClusterTestUtils.RebalanceKit rebalanceKit = ClusterTestUtils.getRebalanceKit(bootstrapUrl, maxParallel, finalCluster);
populateData(currentCluster, rwStoreDefWithReplication);
final AdminClient adminClient = rebalanceKit.controller.getAdminClient();
// the plan would cause these partitions to move:
// Partition : Donor -> stealer
//
// p2 (Z-SEC) : s4 -> s3
// p3-6 (Z-PRI) : s4 -> s5
// p7 (Z-PRI) : s3 -> s5
//
// p5 (Z-SEC): s10 -> s9
// p6 (Z-PRI): s10 -> s11
//
// Rebalancing will run on servers 3, 5, 9, & 11
final List<ByteArray> movingKeysList = sampleKeysFromPartition(adminClient, 4, rwStoreDefWithReplication.getName(), Arrays.asList(6), 20);
assertTrue("Empty list of moving keys...", movingKeysList.size() > 0);
final AtomicBoolean rebalancingStarted = new AtomicBoolean(false);
final AtomicBoolean proxyWritesDone = new AtomicBoolean(false);
final HashMap<String, String> baselineTuples = new HashMap<String, String>(testEntries);
final HashMap<String, VectorClock> baselineVersions = new HashMap<String, VectorClock>();
for (String key : baselineTuples.keySet()) {
baselineVersions.put(key, new VectorClock());
}
final CountDownLatch latch = new CountDownLatch(2);
// start get operation.
executors.execute(new Runnable() {
@Override
public void run() {
SocketStoreClientFactory factory = null;
try {
// wait for the rebalancing to begin
List<VoldemortServer> serverList = Lists.newArrayList(serverMap.get(3), serverMap.get(5), serverMap.get(9), serverMap.get(11));
while (!rebalancingComplete.get()) {
Iterator<VoldemortServer> serverIterator = serverList.iterator();
while (serverIterator.hasNext()) {
VoldemortServer server = serverIterator.next();
if (ByteUtils.getString(server.getMetadataStore().get(MetadataStore.SERVER_STATE_KEY, null).get(0).getValue(), "UTF-8").compareTo(VoldemortState.REBALANCING_MASTER_SERVER.toString()) == 0) {
logger.info("Server " + server.getIdentityNode().getId() + " transitioned into REBALANCING MODE");
serverIterator.remove();
}
}
if (serverList.size() == 0) {
rebalancingStarted.set(true);
break;
}
}
if (rebalancingStarted.get()) {
factory = new SocketStoreClientFactory(new ClientConfig().setBootstrapUrls(getBootstrapUrl(updatedCurrentCluster, 3)).setEnableLazy(false).setSocketTimeout(120, TimeUnit.SECONDS).setClientZoneId(3));
final StoreClient<String, String> storeClientRW = new DefaultStoreClient<String, String>(testStoreNameRW, null, factory, 3);
// Initially, all data now with zero vector clock
for (ByteArray movingKey : movingKeysList) {
try {
String keyStr = ByteUtils.getString(movingKey.get(), "UTF-8");
String valStr = "proxy_write";
storeClientRW.put(keyStr, valStr);
baselineTuples.put(keyStr, valStr);
baselineVersions.get(keyStr).incrementVersion(11, System.currentTimeMillis());
proxyWritesDone.set(true);
if (rebalancingComplete.get()) {
break;
}
} catch (InvalidMetadataException e) {
logger.error("Encountered an invalid metadata exception.. ", e);
}
}
}
} catch (Exception e) {
logger.error("Exception in proxy write thread..", e);
exceptions.add(e);
} finally {
if (factory != null)
factory.close();
latch.countDown();
}
}
});
executors.execute(new Runnable() {
@Override
public void run() {
try {
rebalanceKit.rebalance();
} catch (Exception e) {
logger.error("Error in rebalancing... ", e);
exceptions.add(e);
} finally {
rebalancingComplete.set(true);
latch.countDown();
}
}
});
latch.await();
executors.shutdown();
executors.awaitTermination(300, TimeUnit.SECONDS);
assertEquals("Client did not see all server transition into rebalancing state", rebalancingStarted.get(), true);
assertEquals("Not enough time to begin proxy writing", proxyWritesDone.get(), true);
checkEntriesPostRebalance(updatedCurrentCluster, finalCluster, Lists.newArrayList(rwStoreDefWithReplication), Arrays.asList(3, 4, 5, 9, 10, 11), baselineTuples, baselineVersions);
checkConsistentMetadata(finalCluster, serverList);
// check No Exception
if (exceptions.size() > 0) {
for (Exception e : exceptions) {
e.printStackTrace();
}
fail("Should not see any exceptions.");
}
// check that the proxy writes were made to the original donor, node 4
List<ClockEntry> clockEntries = new ArrayList<ClockEntry>(serverList.size());
for (Integer nodeid : serverList) clockEntries.add(new ClockEntry(nodeid.shortValue(), System.currentTimeMillis()));
VectorClock clusterXmlClock = new VectorClock(clockEntries, System.currentTimeMillis());
for (Integer nodeid : serverList) adminClient.metadataMgmtOps.updateRemoteCluster(nodeid, currentCluster, clusterXmlClock);
adminClient.setAdminClientCluster(currentCluster);
checkForTupleEquivalence(adminClient, 4, testStoreNameRW, movingKeysList, baselineTuples, baselineVersions);
// stop servers
try {
stopServer(serverList);
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (AssertionError ae) {
logger.error("Assertion broken in testProxyPutDuringRebalancing ", ae);
throw ae;
}
}
use of voldemort.client.protocol.admin.AdminClient in project voldemort by voldemort.
the class VerifyOrAddStoreTest method setUp.
@Before
public void setUp() throws IOException {
servers = new VoldemortServer[NUM_SERVERS];
int[][] partitionMap = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
cluster = ServerTestUtils.startVoldemortCluster(servers, partitionMap, serverProps, storesXmlfile);
newStoreDef = new StoreDefinitionsMapper().readStoreList(new File(readOnlyXmlFilePath)).get(0);
newStoreName = newStoreDef.getName();
Node node = cluster.getNodeById(0);
String bootstrapUrl = "tcp://" + node.getHost() + ":" + node.getSocketPort();
clientConfig.setBootstrapUrls(bootstrapUrl);
adminClient = new AdminClient(new AdminClientConfig(), clientConfig);
}
use of voldemort.client.protocol.admin.AdminClient in project voldemort by voldemort.
the class SlopPusherDeadSlopTest method setUp.
@Before
public void setUp() throws Exception {
try {
Properties serverProperties = new Properties();
serverProperties.setProperty("pusher.type", slopPusherType);
serverProperties.setProperty("slop.frequency.ms", SLOP_FREQUENCY_MS.toString());
serverProperties.setProperty("auto.purge.dead.slops", "true");
serverProperties.setProperty("enable.server.routing", "true");
servers = new VoldemortServer[2];
int[][] partitionMap = { { 0, 1 }, { 2, 3 } };
cluster = ServerTestUtils.startVoldemortCluster(servers, partitionMap, serverProperties, "test/common/voldemort/config/single-store.xml");
Properties adminProperties = new Properties();
adminProperties.setProperty("max_connections", "2");
adminClient = new AdminClient(servers[0].getMetadataStore().getCluster(), new AdminClientConfig(adminProperties));
} catch (Exception e) {
logger.error("Error in setup", e);
throw e;
}
}
use of voldemort.client.protocol.admin.AdminClient in project voldemort by voldemort.
the class RequestFileFilter method main.
/**
* Filter requests specified in a file, generating a new file containing
* only requests destined for a specific node.
*
* @param args See usage for more information
* @throws Exception In case of I/O or Voldemort-specific errors
*/
public static void main(String[] args) throws Exception {
OptionParser parser = new OptionParser();
parser.accepts("help", "print usage information");
parser.accepts("node", "[REQUIRED] node id").withRequiredArg().ofType(Integer.class).describedAs("node id");
parser.accepts("store-name", "[REQUIRED] store name").withRequiredArg().describedAs("store name");
parser.accepts("url", "[REQUIRED] bootstrap URL").withRequiredArg().describedAs("bootstrap-url");
parser.accepts("input", "[REQUIRED] input request file").withRequiredArg().describedAs("input-file");
parser.accepts("output", "[REQUIRED] output file").withRequiredArg().describedAs("output-file");
parser.accepts("string-keys");
OptionSet options = parser.parse(args);
if (options.has("help")) {
parser.printHelpOn(System.out);
System.exit(0);
}
Set<String> missing = CmdUtils.missing(options, "node", "store-name", "url", "input", "output");
if (missing.size() > 0) {
System.err.println("Missing required arguments: " + Joiner.on(", ").join(missing));
parser.printHelpOn(System.err);
System.exit(1);
}
int nodeId = (Integer) options.valueOf("node");
String storeName = (String) options.valueOf("store-name");
String bootstrapURL = (String) options.valueOf("url");
String inputFile = (String) options.valueOf("input");
String outputFile = (String) options.valueOf("output");
boolean stringKeys = options.has("string-keys");
AdminClient adminClient = new AdminClient(bootstrapURL);
List<StoreDefinition> storeDefinitionList = adminClient.metadataMgmtOps.getRemoteStoreDefList(nodeId).getValue();
StoreDefinition storeDefinition = null;
for (StoreDefinition def : storeDefinitionList) {
if (storeName.equals(def.getName())) {
storeDefinition = def;
}
}
if (storeDefinition == null) {
Utils.croak("No store found with name\"" + storeName + "\"");
}
Cluster cluster = adminClient.metadataMgmtOps.getRemoteCluster(nodeId).getValue();
Node node = null;
try {
node = cluster.getNodeById(nodeId);
} catch (VoldemortException e) {
Utils.croak("Can't find a node with id " + nodeId);
}
RoutingStrategy routingStrategy = new RoutingStrategyFactory().updateRoutingStrategy(storeDefinition, cluster);
try {
new RequestFileFilter(storeDefinition, routingStrategy, inputFile, outputFile, node, stringKeys).filter();
} catch (FileNotFoundException e) {
Utils.croak(e.getMessage());
}
}
use of voldemort.client.protocol.admin.AdminClient in project voldemort by voldemort.
the class VoldemortAdminTool method main.
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
OptionParser parser = new OptionParser();
// This is a generic argument that should be eventually supported by all
// RW operations.
// If you omit this argument the operation will be executed in a "batch"
// mode which is useful for scripting
// Otherwise you will be presented with a summary of changes and with a
// Y/N prompt
parser.accepts("auto", "[OPTIONAL] enable auto/batch mode");
parser.accepts("help", "print help information");
parser.accepts("url", "[REQUIRED] bootstrap URL").withRequiredArg().describedAs("bootstrap-url").ofType(String.class);
parser.accepts("node", "node id").withRequiredArg().describedAs("node-id").ofType(Integer.class);
parser.accepts("delete-partitions", "Delete partitions").withRequiredArg().describedAs("partition-ids").withValuesSeparatedBy(',').ofType(Integer.class);
parser.accepts("restore", "Restore from replication [ Optional parallelism param - Default - 5 ]").withOptionalArg().describedAs("parallelism").ofType(Integer.class);
parser.accepts("ascii", "Fetch keys as ASCII");
parser.accepts("fetch-keys", "Fetch keys").withOptionalArg().describedAs("partition-ids").withValuesSeparatedBy(',').ofType(Integer.class);
parser.accepts("fetch-entries", "Fetch full entries").withOptionalArg().describedAs("partition-ids").withValuesSeparatedBy(',').ofType(Integer.class);
parser.accepts("outdir", "Output directory").withRequiredArg().describedAs("output-directory").ofType(String.class);
parser.accepts("nodes", "list of nodes").withRequiredArg().describedAs("nodes").withValuesSeparatedBy(',').ofType(Integer.class);
parser.accepts("stores", "Store names").withRequiredArg().describedAs("store-names").withValuesSeparatedBy(',').ofType(String.class);
parser.accepts("store", "Store name for querying keys").withRequiredArg().describedAs("store-name").ofType(String.class);
parser.accepts("add-stores", "Add stores in this stores.xml").withRequiredArg().describedAs("stores.xml containing just the new stores").ofType(String.class);
parser.accepts("delete-store", "Delete store").withRequiredArg().describedAs("store-name").ofType(String.class);
parser.accepts("update-entries", "Insert or update entries").withRequiredArg().describedAs("input-directory").ofType(String.class);
parser.accepts("get-metadata", "retreive metadata information " + MetadataStore.METADATA_KEYS).withOptionalArg().describedAs("metadata-key").ofType(String.class);
parser.accepts("check-metadata", "retreive metadata information from all nodes and checks if they are consistent across [ " + MetadataStore.CLUSTER_KEY + " | " + MetadataStore.STORES_KEY + " | " + MetadataStore.REBALANCING_SOURCE_CLUSTER_XML + " | " + MetadataStore.SERVER_STATE_KEY + " ]").withRequiredArg().describedAs("metadata-key").ofType(String.class);
parser.accepts("ro-metadata", "retrieve version information [current | max | storage-format]").withRequiredArg().describedAs("type").ofType(String.class);
parser.accepts("truncate", "truncate a store").withRequiredArg().describedAs("store-name").ofType(String.class);
parser.accepts("set-metadata", "Forceful setting of metadata [ " + MetadataStore.CLUSTER_KEY + " | " + MetadataStore.STORES_KEY + " | " + MetadataStore.SERVER_STATE_KEY + " | " + MetadataStore.REBALANCING_SOURCE_CLUSTER_XML + " | " + MetadataStore.REBALANCING_STEAL_INFO + " ]").withRequiredArg().describedAs("metadata-key").ofType(String.class);
parser.accepts("set-metadata-value", "The value for the set-metadata [ " + MetadataStore.CLUSTER_KEY + " | " + MetadataStore.STORES_KEY + ", " + MetadataStore.REBALANCING_SOURCE_CLUSTER_XML + ", " + MetadataStore.REBALANCING_STEAL_INFO + " ] - xml file location, [ " + MetadataStore.SERVER_STATE_KEY + " ] - " + MetadataStore.VoldemortState.NORMAL_SERVER + "," + MetadataStore.VoldemortState.REBALANCING_MASTER_SERVER + "," + MetadataStore.VoldemortState.OFFLINE_SERVER).withRequiredArg().describedAs("metadata-value").ofType(String.class);
parser.accepts("update-store-defs", "Update the [" + MetadataStore.STORES_KEY + "] with the new value for only the specified stores in update-value.");
parser.accepts("update-store-value", "The value for update-store-defs ] - xml file location").withRequiredArg().describedAs("stores-xml-value").ofType(String.class);
parser.accepts("set-metadata-pair", "Atomic setting of metadata pair [ " + MetadataStore.CLUSTER_KEY + " & " + MetadataStore.STORES_KEY + " ]").withRequiredArg().describedAs("metadata-keys-pair").withValuesSeparatedBy(',').ofType(String.class);
parser.accepts("set-metadata-value-pair", "The value for the set-metadata pair [ " + MetadataStore.CLUSTER_KEY + " & " + MetadataStore.STORES_KEY + " ]").withRequiredArg().describedAs("metadata-value-pair").withValuesSeparatedBy(',').ofType(String.class);
parser.accepts("clear-rebalancing-metadata", "Remove the metadata related to rebalancing");
parser.accepts("async", "a) Get a list of async job ids [get] b) Stop async job ids [stop] ").withRequiredArg().describedAs("op-type").ofType(String.class);
parser.accepts("async-id", "Comma separated list of async ids to stop").withOptionalArg().describedAs("job-ids").withValuesSeparatedBy(',').ofType(Integer.class);
parser.accepts("repair-job", "Clean after rebalancing is done");
parser.accepts("prune-job", "Prune versioned put data, after rebalancing");
parser.accepts("purge-slops", "Purge the slop stores selectively, based on nodeId or zoneId");
parser.accepts("native-backup", "Perform a native backup").withRequiredArg().describedAs("store-name").ofType(String.class);
parser.accepts("backup-dir").withRequiredArg().describedAs("backup-directory").ofType(String.class);
parser.accepts("backup-timeout").withRequiredArg().describedAs("minutes to wait for backup completion, default 30 mins").ofType(Integer.class);
parser.accepts("backup-verify", "If provided, backup will also verify checksum (with extra overhead)");
parser.accepts("backup-incremental", "Perform an incremental backup for point-in-time recovery." + " By default backup has latest consistent snapshot.");
parser.accepts("zone", "zone id").withRequiredArg().describedAs("zone-id").ofType(Integer.class);
parser.accepts("rollback", "rollback a store").withRequiredArg().describedAs("store-name").ofType(String.class);
parser.accepts("version", "Push version of store to rollback to").withRequiredArg().describedAs("version").ofType(Long.class);
parser.accepts("verify-metadata-version", "Verify the version of Metadata on all the cluster nodes");
parser.accepts("synchronize-metadata-version", "Synchronize the metadata versions across all the nodes.");
parser.accepts("reserve-memory", "Memory in MB to reserve for the store").withRequiredArg().describedAs("size-in-mb").ofType(Long.class);
parser.accepts("query-key", "Get values of a key on specific node").withRequiredArg().describedAs("query-key").ofType(String.class);
parser.accepts("query-key-format", "Format of the query key. Can be one of [hex|readable]").withRequiredArg().describedAs("key-format").ofType(String.class);
parser.accepts("show-routing-plan", "Routing plan of the specified keys").withRequiredArg().describedAs("keys-to-be-routed").withValuesSeparatedBy(',').ofType(String.class);
parser.accepts("mirror-from-url", "Cluster url to mirror data from").withRequiredArg().describedAs("mirror-cluster-bootstrap-url").ofType(String.class);
parser.accepts("mirror-node", "Node id in the mirror cluster to mirror from").withRequiredArg().describedAs("id-of-mirror-node").ofType(Integer.class);
parser.accepts("fetch-orphaned", "Fetch any orphaned keys/entries in the node");
parser.accepts("set-quota", "Enforce some quota on the servers").withRequiredArg().describedAs("quota-type").ofType(String.class);
parser.accepts("quota-value", "Value of the quota enforced on the servers").withRequiredArg().describedAs("quota-value").ofType(String.class);
parser.accepts("unset-quota", "Remove some quota already enforced on the servers").withRequiredArg().describedAs("quota-type").ofType(String.class);
// TODO add a way to retrieve all quotas for a given store.
parser.accepts("get-quota", "Retrieve some quota already enforced on the servers").withRequiredArg().describedAs("quota-type").ofType(String.class);
OptionSet options = parser.parse(args);
if (options.has("help")) {
printHelp(System.out, parser);
System.exit(0);
}
Set<String> missing = CmdUtils.missing(options, "url", "node");
if (missing.size() > 0) {
// options; all these can live without explicit node ids
if (!(missing.equals(ImmutableSet.of("node")) && (options.has("add-stores") || options.has("delete-store") || options.has("ro-metadata") || options.has("set-metadata") || options.has("update-store-defs") || options.has("set-metadata-pair") || options.has("get-metadata") || options.has("check-metadata")) || options.has("truncate") || options.has("clear-rebalancing-metadata") || options.has("async") || options.has("native-backup") || options.has("rollback") || options.has("verify-metadata-version") || options.has("reserve-memory") || options.has("purge-slops") || options.has("show-routing-plan") || options.has("query-key") || options.has("set-quota") || options.has("unset-quota") || options.has("get-quota") || options.has("synchronize-metadata-version"))) {
System.err.println("Missing required arguments: " + Joiner.on(", ").join(missing));
printHelp(System.err, parser);
System.exit(1);
}
}
try {
String url = (String) options.valueOf("url");
Integer nodeId = CmdUtils.valueOf(options, "node", -1);
int parallelism = CmdUtils.valueOf(options, "restore", 5);
Integer zoneId = CmdUtils.valueOf(options, "zone", -1);
AdminClient adminClient = new AdminClient(url);
List<String> storeNames = null;
if (options.has("store") && options.has("stores")) {
throw new VoldemortException("Must not specify both --stores and --store options");
} else if (options.has("stores")) {
storeNames = (List<String>) options.valuesOf("stores");
} else if (options.has("store")) {
storeNames = Arrays.asList((String) options.valueOf("store"));
}
String outputDir = null;
if (options.has("outdir")) {
outputDir = (String) options.valueOf("outdir");
}
if (options.has("add-stores")) {
String storesXml = (String) options.valueOf("add-stores");
executeAddStores(adminClient, storesXml, nodeId);
} else if (options.has("async")) {
String asyncKey = (String) options.valueOf("async");
List<Integer> asyncIds = null;
if (options.hasArgument("async-id"))
asyncIds = (List<Integer>) options.valuesOf("async-id");
executeAsync(nodeId, adminClient, asyncKey, asyncIds);
} else if (options.has("check-metadata")) {
String metadataKey = (String) options.valueOf("check-metadata");
executeCheckMetadata(adminClient, metadataKey);
} else if (options.has("delete-partitions")) {
System.out.println("Starting delete-partitions");
List<Integer> partitionIdList = (List<Integer>) options.valuesOf("delete-partitions");
executeDeletePartitions(nodeId, adminClient, partitionIdList, storeNames);
System.out.println("Finished delete-partitions");
} else if (options.has("ro-metadata")) {
String type = (String) options.valueOf("ro-metadata");
executeROMetadata(nodeId, adminClient, storeNames, type);
} else if (options.has("reserve-memory")) {
if (!options.has("stores")) {
Utils.croak("Specify the list of stores to reserve memory");
}
long reserveMB = (Long) options.valueOf("reserve-memory");
adminClient.quotaMgmtOps.reserveMemory(nodeId, storeNames, reserveMB);
} else if (options.has("get-metadata")) {
String metadataKey = ALL_METADATA;
if (options.hasArgument("get-metadata")) {
metadataKey = (String) options.valueOf("get-metadata");
}
executeGetMetadata(nodeId, adminClient, metadataKey, outputDir);
} else if (options.has("mirror-from-url")) {
if (!options.has("mirror-node")) {
Utils.croak("Specify the mirror node to fetch from");
}
if (nodeId == -1) {
System.err.println("Cannot run mirroring without node id");
System.exit(1);
}
Integer mirrorNodeId = CmdUtils.valueOf(options, "mirror-node", -1);
if (mirrorNodeId == -1) {
System.err.println("Cannot run mirroring without mirror node id");
System.exit(1);
}
adminClient.restoreOps.mirrorData(nodeId, mirrorNodeId, (String) options.valueOf("mirror-from-url"), storeNames);
} else if (options.has("clear-rebalancing-metadata")) {
executeClearRebalancing(nodeId, adminClient);
} else if (options.has("prune-job")) {
if (storeNames == null) {
Utils.croak("Must specify --stores to run the prune job");
}
executePruneJob(nodeId, adminClient, storeNames);
} else if (options.has("fetch-keys")) {
boolean useAscii = options.has("ascii");
System.out.println("Starting fetch keys");
List<Integer> partitionIdList = null;
if (options.hasArgument("fetch-keys"))
partitionIdList = (List<Integer>) options.valuesOf("fetch-keys");
executeFetchKeys(nodeId, adminClient, partitionIdList, outputDir, storeNames, useAscii, options.has("fetch-orphaned"));
} else if (options.has("repair-job")) {
executeRepairJob(nodeId, adminClient);
} else if (options.has("set-metadata-pair")) {
List<String> metadataKeyPair = (List<String>) options.valuesOf("set-metadata-pair");
if (metadataKeyPair.size() != 2) {
throw new VoldemortException("Missing set-metadata-pair keys (only two keys are needed and allowed)");
}
if (!options.has("set-metadata-value-pair")) {
throw new VoldemortException("Missing set-metadata-value-pair");
} else {
List<String> metadataValuePair = (List<String>) options.valuesOf("set-metadata-value-pair");
if (metadataValuePair.size() != 2) {
throw new VoldemortException("Missing set-metadata--value-pair values (only two values are needed and allowed)");
}
if (metadataKeyPair.contains(MetadataStore.CLUSTER_KEY) && metadataKeyPair.contains(MetadataStore.STORES_KEY)) {
ClusterMapper clusterMapper = new ClusterMapper();
StoreDefinitionsMapper storeDefsMapper = new StoreDefinitionsMapper();
// original metadata
Integer nodeIdToGetStoreXMLFrom = nodeId;
if (nodeId < 0) {
Collection<Node> nodes = adminClient.getAdminClientCluster().getNodes();
if (nodes.isEmpty()) {
throw new VoldemortException("No nodes in this cluster");
} else {
nodeIdToGetStoreXMLFrom = nodes.iterator().next().getId();
}
}
Versioned<String> storesXML = adminClient.metadataMgmtOps.getRemoteMetadata(nodeIdToGetStoreXMLFrom, MetadataStore.STORES_KEY);
List<StoreDefinition> oldStoreDefs = storeDefsMapper.readStoreList(new StringReader(storesXML.getValue()));
String clusterXMLPath = metadataValuePair.get(metadataKeyPair.indexOf(MetadataStore.CLUSTER_KEY));
clusterXMLPath = clusterXMLPath.replace("~", System.getProperty("user.home"));
if (!Utils.isReadableFile(clusterXMLPath))
throw new VoldemortException("Cluster xml file path incorrect");
Cluster cluster = clusterMapper.readCluster(new File(clusterXMLPath));
String storesXMLPath = metadataValuePair.get(metadataKeyPair.indexOf(MetadataStore.STORES_KEY));
storesXMLPath = storesXMLPath.replace("~", System.getProperty("user.home"));
if (!Utils.isReadableFile(storesXMLPath))
throw new VoldemortException("Stores definition xml file path incorrect");
List<StoreDefinition> newStoreDefs = storeDefsMapper.readStoreList(new File(storesXMLPath));
StoreDefinitionUtils.validateSchemasAsNeeded(newStoreDefs);
executeSetMetadataPair(nodeId, adminClient, MetadataStore.CLUSTER_KEY, clusterMapper.writeCluster(cluster), MetadataStore.STORES_KEY, storeDefsMapper.writeStoreList(newStoreDefs));
executeUpdateMetadataVersionsOnStores(adminClient, oldStoreDefs, newStoreDefs);
} else {
throw new VoldemortException("set-metadata-pair keys should be <cluster.xml, stores.xml>");
}
}
} else if (options.has("set-metadata")) {
String metadataKey = (String) options.valueOf("set-metadata");
if (!options.has("set-metadata-value")) {
throw new VoldemortException("Missing set-metadata-value");
} else {
String metadataValue = (String) options.valueOf("set-metadata-value");
if (metadataKey.compareTo(MetadataStore.CLUSTER_KEY) == 0 || metadataKey.compareTo(MetadataStore.REBALANCING_SOURCE_CLUSTER_XML) == 0) {
if (!Utils.isReadableFile(metadataValue))
throw new VoldemortException("Cluster xml file path incorrect");
ClusterMapper mapper = new ClusterMapper();
Cluster newCluster = mapper.readCluster(new File(metadataValue));
if (options.has("auto")) {
executeSetMetadata(nodeId, adminClient, metadataKey, mapper.writeCluster(newCluster));
} else {
if (confirmMetadataUpdate(nodeId, adminClient, mapper.writeCluster(newCluster))) {
executeSetMetadata(nodeId, adminClient, metadataKey, mapper.writeCluster(newCluster));
} else {
System.out.println("New metadata has not been set");
}
}
} else if (metadataKey.compareTo(MetadataStore.SERVER_STATE_KEY) == 0) {
VoldemortState newState = VoldemortState.valueOf(metadataValue);
executeSetMetadata(nodeId, adminClient, MetadataStore.SERVER_STATE_KEY, newState.toString());
} else if (metadataKey.compareTo(MetadataStore.STORES_KEY) == 0) {
if (!Utils.isReadableFile(metadataValue))
throw new VoldemortException("Stores definition xml file path incorrect");
StoreDefinitionsMapper mapper = new StoreDefinitionsMapper();
List<StoreDefinition> newStoreDefs = mapper.readStoreList(new File(metadataValue));
StoreDefinitionUtils.validateSchemasAsNeeded(newStoreDefs);
// original metadata
Integer nodeIdToGetStoreXMLFrom = nodeId;
if (nodeId < 0) {
Collection<Node> nodes = adminClient.getAdminClientCluster().getNodes();
if (nodes.isEmpty()) {
throw new VoldemortException("No nodes in this cluster");
} else {
nodeIdToGetStoreXMLFrom = nodes.iterator().next().getId();
}
}
Versioned<String> storesXML = adminClient.metadataMgmtOps.getRemoteMetadata(nodeIdToGetStoreXMLFrom, MetadataStore.STORES_KEY);
List<StoreDefinition> oldStoreDefs = mapper.readStoreList(new StringReader(storesXML.getValue()));
if (options.has("auto")) {
executeSetMetadata(nodeId, adminClient, MetadataStore.STORES_KEY, mapper.writeStoreList(newStoreDefs));
executeUpdateMetadataVersionsOnStores(adminClient, oldStoreDefs, newStoreDefs);
} else {
if (confirmMetadataUpdate(nodeId, adminClient, storesXML.getValue())) {
executeSetMetadata(nodeId, adminClient, MetadataStore.STORES_KEY, mapper.writeStoreList(newStoreDefs));
if (nodeId >= 0) {
System.err.println("WARNING: Metadata version update of stores goes to all servers, " + "although this set-metadata oprations only goes to node " + nodeId);
}
executeUpdateMetadataVersionsOnStores(adminClient, oldStoreDefs, newStoreDefs);
} else {
System.out.println("New metadata has not been set");
}
}
} else if (metadataKey.compareTo(MetadataStore.REBALANCING_STEAL_INFO) == 0) {
if (!Utils.isReadableFile(metadataValue))
throw new VoldemortException("Rebalancing steal info file path incorrect");
String rebalancingStealInfoJsonString = FileUtils.readFileToString(new File(metadataValue));
RebalancerState state = RebalancerState.create(rebalancingStealInfoJsonString);
executeSetMetadata(nodeId, adminClient, MetadataStore.REBALANCING_STEAL_INFO, state.toJsonString());
} else {
throw new VoldemortException("Incorrect metadata key");
}
}
} else if (options.has("update-store-defs")) {
if (!options.has("update-store-value")) {
throw new VoldemortException("Missing update-store-value for update-store-defs");
} else {
String storesXmlValue = (String) options.valueOf("update-store-value");
if (!Utils.isReadableFile(storesXmlValue))
throw new VoldemortException("Stores definition xml file path incorrect");
StoreDefinitionsMapper mapper = new StoreDefinitionsMapper();
List<StoreDefinition> newStoreDefs = mapper.readStoreList(new File(storesXmlValue));
StoreDefinitionUtils.validateSchemasAsNeeded(newStoreDefs);
if (options.has("auto")) {
executeUpdateStoreDefinitions(nodeId, adminClient, newStoreDefs);
} else {
if (confirmMetadataUpdate(nodeId, adminClient, newStoreDefs)) {
executeUpdateStoreDefinitions(nodeId, adminClient, newStoreDefs);
if (nodeId >= 0) {
System.err.println("WARNING: Metadata version update of stores goes to all servers, " + "although this set-metadata oprations only goes to node " + nodeId);
}
} else {
System.out.println("New metadata has not been set");
}
}
System.out.println("The store definitions have been successfully updated.");
}
} else if (options.has("native-backup")) {
if (!options.has("backup-dir")) {
Utils.croak("A backup directory must be specified with backup-dir option");
}
String backupDir = (String) options.valueOf("backup-dir");
String storeName = (String) options.valueOf("native-backup");
int timeout = CmdUtils.valueOf(options, "backup-timeout", 30);
adminClient.storeMntOps.nativeBackup(nodeId, storeName, backupDir, timeout, options.has("backup-verify"), options.has("backup-incremental"));
} else if (options.has("rollback")) {
if (!options.has("version")) {
Utils.croak("A read-only push version must be specified with rollback option");
}
String storeName = (String) options.valueOf("rollback");
long pushVersion = (Long) options.valueOf("version");
executeRollback(nodeId, storeName, pushVersion, adminClient);
} else if (options.has("query-key")) {
String key = (String) options.valueOf("query-key");
String keyFormat = (String) options.valueOf("query-key-format");
if (keyFormat == null) {
keyFormat = "hex";
}
if (!keyFormat.equals("hex") && !keyFormat.equals("readable")) {
throw new VoldemortException("--query-key-format must be hex or readable");
}
executeQueryKey(nodeId, adminClient, storeNames, key, keyFormat);
} else if (options.has("restore")) {
if (nodeId == -1) {
System.err.println("Cannot run restore without node id");
System.exit(1);
}
System.out.println("Starting restore");
adminClient.restoreOps.restoreDataFromReplications(nodeId, parallelism, zoneId);
System.out.println("Finished restore");
} else if (options.has("delete-store")) {
String storeName = (String) options.valueOf("delete-store");
executeDeleteStore(adminClient, storeName, nodeId);
} else if (options.has("truncate")) {
String storeName = (String) options.valueOf("truncate");
executeTruncateStore(nodeId, adminClient, storeName);
} else if (options.has("update-entries")) {
String inputDir = (String) options.valueOf("update-entries");
executeUpdateEntries(nodeId, adminClient, storeNames, inputDir);
} else if (options.has("fetch-entries")) {
boolean useAscii = options.has("ascii");
System.out.println("Starting fetch entries");
List<Integer> partitionIdList = null;
if (options.hasArgument("fetch-entries"))
partitionIdList = (List<Integer>) options.valuesOf("fetch-entries");
executeFetchEntries(nodeId, adminClient, partitionIdList, outputDir, storeNames, useAscii, options.has("fetch-orphaned"));
} else if (options.has("purge-slops")) {
List<Integer> nodesToPurge = null;
if (options.has("nodes")) {
nodesToPurge = (List<Integer>) options.valuesOf("nodes");
}
if (nodesToPurge == null && zoneId == -1 && storeNames == null) {
Utils.croak("Must specify atleast one of --nodes, --zone-id or --stores with --purge-slops");
}
executePurgeSlops(adminClient, nodesToPurge, zoneId, storeNames);
} else if (options.has("synchronize-metadata-version")) {
synchronizeMetadataVersion(adminClient);
} else if (options.has("verify-metadata-version")) {
checkMetadataVersion(adminClient);
} else if (options.has("show-routing-plan")) {
if (!options.has("store")) {
Utils.croak("Must specify the store the keys belong to using --store ");
}
String storeName = (String) options.valueOf("store");
List<String> keysToRoute = (List<String>) options.valuesOf("show-routing-plan");
if (keysToRoute == null || keysToRoute.size() == 0) {
Utils.croak("Must specify comma separated keys list in hex format");
}
executeShowRoutingPlan(adminClient, storeName, keysToRoute);
} else if (options.has("set-quota")) {
String quotaType = (String) options.valueOf("set-quota");
Set<String> validQuotaTypes = QuotaUtils.validQuotaTypes();
if (!validQuotaTypes.contains(quotaType)) {
Utils.croak("Specify a valid quota type from :" + validQuotaTypes);
}
if (!options.has("store")) {
Utils.croak("Must specify the store to enforce the quota on. ");
}
if (!options.has("quota-value")) {
Utils.croak("Must specify the value of the quota being set");
}
String storeName = (String) options.valueOf("store");
String quotaValue = (String) options.valueOf("quota-value");
executeSetQuota(adminClient, storeName, quotaType, quotaValue);
} else if (options.has("unset-quota")) {
String quotaType = (String) options.valueOf("unset-quota");
Set<String> validQuotaTypes = QuotaUtils.validQuotaTypes();
if (!validQuotaTypes.contains(quotaType)) {
Utils.croak("Specify a valid quota type from :" + validQuotaTypes);
}
if (!options.has("store")) {
Utils.croak("Must specify the store to enforce the quota on. ");
}
String storeName = (String) options.valueOf("store");
executeUnsetQuota(adminClient, storeName, quotaType);
} else if (options.has("get-quota")) {
String quotaType = (String) options.valueOf("get-quota");
Set<String> validQuotaTypes = QuotaUtils.validQuotaTypes();
if (!validQuotaTypes.contains(quotaType)) {
Utils.croak("Specify a valid quota type from :" + validQuotaTypes);
}
if (!options.has("store")) {
Utils.croak("Must specify the store to enforce the quota on. ");
}
String storeName = (String) options.valueOf("store");
executeGetQuota(adminClient, storeName, quotaType);
} else {
Utils.croak("At least one of (delete-partitions, restore, add-node, fetch-entries, " + "fetch-keys, add-stores, delete-store, update-entries, get-metadata, ro-metadata, " + "set-metadata, check-metadata, clear-rebalancing-metadata, async, " + "repair-job, native-backup, rollback, reserve-memory, mirror-url," + " verify-metadata-version, prune-job, purge-slops) must be specified");
}
} catch (Exception e) {
e.printStackTrace();
Utils.croak(e.getMessage());
}
}
Aggregations