Search in sources :

Example 11 with AdminClient

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;
    }
}
Also used : DefaultStoreClient(voldemort.client.DefaultStoreClient) StoreClient(voldemort.client.StoreClient) HashMap(java.util.HashMap) InvalidMetadataException(voldemort.store.InvalidMetadataException) ArrayList(java.util.ArrayList) VoldemortServer(voldemort.server.VoldemortServer) SocketStoreClientFactory(voldemort.client.SocketStoreClientFactory) Iterator(java.util.Iterator) ByteArray(voldemort.utils.ByteArray) List(java.util.List) ArrayList(java.util.ArrayList) ClientConfig(voldemort.client.ClientConfig) VectorClock(voldemort.versioning.VectorClock) Cluster(voldemort.cluster.Cluster) CountDownLatch(java.util.concurrent.CountDownLatch) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) IOException(java.io.IOException) InvalidMetadataException(voldemort.store.InvalidMetadataException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClusterTestUtils(voldemort.ClusterTestUtils) ExecutorService(java.util.concurrent.ExecutorService) ClockEntry(voldemort.versioning.ClockEntry) AdminClient(voldemort.client.protocol.admin.AdminClient) Test(org.junit.Test)

Example 12 with AdminClient

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);
}
Also used : AdminClientConfig(voldemort.client.protocol.admin.AdminClientConfig) Node(voldemort.cluster.Node) StoreDefinitionsMapper(voldemort.xml.StoreDefinitionsMapper) File(java.io.File) AdminClient(voldemort.client.protocol.admin.AdminClient) Before(org.junit.Before)

Example 13 with AdminClient

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;
    }
}
Also used : AdminClientConfig(voldemort.client.protocol.admin.AdminClientConfig) Properties(java.util.Properties) IOException(java.io.IOException) AdminClient(voldemort.client.protocol.admin.AdminClient) Before(org.junit.Before)

Example 14 with AdminClient

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());
    }
}
Also used : RoutingStrategyFactory(voldemort.routing.RoutingStrategyFactory) Node(voldemort.cluster.Node) FileNotFoundException(java.io.FileNotFoundException) Cluster(voldemort.cluster.Cluster) OptionParser(joptsimple.OptionParser) VoldemortException(voldemort.VoldemortException) StoreDefinition(voldemort.store.StoreDefinition) RoutingStrategy(voldemort.routing.RoutingStrategy) OptionSet(joptsimple.OptionSet) AdminClient(voldemort.client.protocol.admin.AdminClient)

Example 15 with AdminClient

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());
    }
}
Also used : VoldemortState(voldemort.store.metadata.MetadataStore.VoldemortState) OptionSet(joptsimple.OptionSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) Versioned(voldemort.versioning.Versioned) Node(voldemort.cluster.Node) OptionParser(joptsimple.OptionParser) StoreDefinition(voldemort.store.StoreDefinition) StringReader(java.io.StringReader) RebalancerState(voldemort.server.rebalance.RebalancerState) List(java.util.List) ArrayList(java.util.ArrayList) StoreDefinitionsMapper(voldemort.xml.StoreDefinitionsMapper) Cluster(voldemort.cluster.Cluster) ClusterMapper(voldemort.xml.ClusterMapper) StoreNotFoundException(com.sleepycat.persist.StoreNotFoundException) DecoderException(org.apache.commons.codec.DecoderException) EOFException(java.io.EOFException) SerializationException(voldemort.serialization.SerializationException) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) InvalidMetadataException(voldemort.store.InvalidMetadataException) Collection(java.util.Collection) OptionSet(joptsimple.OptionSet) File(java.io.File) AdminClient(voldemort.client.protocol.admin.AdminClient)

Aggregations

AdminClient (voldemort.client.protocol.admin.AdminClient)80 Test (org.junit.Test)35 Cluster (voldemort.cluster.Cluster)26 Node (voldemort.cluster.Node)26 Properties (java.util.Properties)19 StoreDefinition (voldemort.store.StoreDefinition)19 ArrayList (java.util.ArrayList)18 AdminClientConfig (voldemort.client.protocol.admin.AdminClientConfig)18 VoldemortException (voldemort.VoldemortException)17 IOException (java.io.IOException)14 Before (org.junit.Before)14 ByteArray (voldemort.utils.ByteArray)14 HashMap (java.util.HashMap)13 StoreDefinitionsMapper (voldemort.xml.StoreDefinitionsMapper)13 File (java.io.File)11 VoldemortServer (voldemort.server.VoldemortServer)11 ClientConfig (voldemort.client.ClientConfig)10 VectorClock (voldemort.versioning.VectorClock)10 Versioned (voldemort.versioning.Versioned)9 ClusterMapper (voldemort.xml.ClusterMapper)9