Package voldemort.tools.admin.command

Source Code of voldemort.tools.admin.command.AdminCommandDebug

/*
* Copyright 2008-2014 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package voldemort.tools.admin.command;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import joptsimple.OptionParser;
import joptsimple.OptionSet;

import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.JsonDecoder;
import org.apache.commons.codec.DecoderException;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.map.ObjectMapper;

import voldemort.VoldemortException;
import voldemort.client.protocol.admin.AdminClient;
import voldemort.client.protocol.admin.QueryKeyResult;
import voldemort.cluster.Cluster;
import voldemort.cluster.Zone;
import voldemort.routing.BaseStoreRoutingPlan;
import voldemort.routing.StoreRoutingPlan;
import voldemort.serialization.DefaultSerializerFactory;
import voldemort.serialization.SerializationException;
import voldemort.serialization.Serializer;
import voldemort.serialization.SerializerDefinition;
import voldemort.serialization.SerializerFactory;
import voldemort.serialization.json.JsonReader;
import voldemort.store.InvalidMetadataException;
import voldemort.store.StoreDefinition;
import voldemort.store.compress.CompressionStrategy;
import voldemort.store.compress.CompressionStrategyFactory;
import voldemort.tools.admin.AdminParserUtils;
import voldemort.tools.admin.AdminToolUtils;
import voldemort.utils.ByteArray;
import voldemort.utils.ByteUtils;
import voldemort.utils.StoreDefinitionUtils;
import voldemort.utils.Utils;
import voldemort.versioning.VectorClock;
import voldemort.versioning.Versioned;

import com.google.common.base.Objects;
import com.sleepycat.persist.StoreNotFoundException;

/**
* Implements all debug commands.
*/
public class AdminCommandDebug extends AbstractAdminCommand {

    /**
     * Parses command-line and directs to sub-commands.
     *
     * @param args Command-line input
     * @throws Exception
     */
    public static void executeCommand(String[] args) throws Exception {
        String subCmd = (args.length > 0) ? args[0] : "";
        args = AdminToolUtils.copyArrayCutFirst(args);
        if(subCmd.equals("query-keys")) {
            SubCommandDebugQueryKeys.executeCommand(args);
        } else if(subCmd.equals("route")) {
            SubCommandDebugRoute.executeCommand(args);
        } else {
            printHelp(System.out);
        }
    }

    /**
     * Prints command-line help menu.
     */
    public static void printHelp(PrintStream stream) {
        stream.println();
        stream.println("Voldemort Admin Tool Debug Commands");
        stream.println("-----------------------------------");
        stream.println("query-keys   Query stores for a set of keys.");
        stream.println("route        Show detailed routing plan for a given set of keys on a store.");
        stream.println();
        stream.println("To get more information on each command,");
        stream.println("please try \'help debug <command-name>\'.");
        stream.println();
    }

    /**
     * Parses command-line input and prints help menu.
     *
     * @throws Exception
     */
    public static void executeHelp(String[] args, PrintStream stream) throws Exception {
        String subCmd = (args.length > 0) ? args[0] : "";
        if(subCmd.equals("query-keys")) {
            SubCommandDebugQueryKeys.printHelp(stream);
        } else if(subCmd.equals("route")) {
            SubCommandDebugRoute.printHelp(stream);
        } else {
            printHelp(stream);
        }
    }

    /**
     * debug query-keys command
     */
    public static class SubCommandDebugQueryKeys extends AbstractAdminCommand {

        /**
         * Initializes parser
         *
         * @return OptionParser object with all available options
         */
        protected static OptionParser getParser() {
            OptionParser parser = new OptionParser();
            // help options
            AdminParserUtils.acceptsHelp(parser);
            // required options
            AdminParserUtils.acceptsHex(parser); // either --hex or
                                                 // --json
            AdminParserUtils.acceptsJson(parser); // either --hex or
                                                  // --json
            AdminParserUtils.acceptsStoreMultiple(parser);
            AdminParserUtils.acceptsUrl(parser);
            // optional options
            AdminParserUtils.acceptsNodeMultiple(parser); // either
                                                          // --node or
                                                          // --all-nodes
            AdminParserUtils.acceptsAllNodes(parser); // either --node or
                                                      // --all-nodes
            return parser;
        }

        /**
         * Prints help menu for command.
         *
         * @param stream PrintStream object for output
         * @throws IOException
         */
        public static void printHelp(PrintStream stream) throws IOException {
            stream.println();
            stream.println("NAME");
            stream.println("  debug query-keys - Query stores for a set of keys");
            stream.println();
            stream.println("SYNOPSIS");
            stream.println("  debug query-keys ((-x | -j) <key-list>) -s <store-name-list> -u <url>");
            stream.println("                   [-n <node-id-list> | --all-nodes]");
            stream.println();
            getParser().printHelpOn(stream);
            stream.println();
        }

        /**
         * Parses command-line and queries stores for a set of keys
         *
         * @param args Command-line input
         * @param printHelp Tells whether to print help only or execute command
         *        actually
         * @throws IOException
         *
         */
        @SuppressWarnings("unchecked")
        public static void executeCommand(String[] args) throws IOException {

            OptionParser parser = getParser();

            // declare parameters
            String keyType = null;
            List<String> keyStrings = null;
            List<String> storeNames = null;
            String url = null;
            List<Integer> nodeIds = null;
            Boolean allNodes = true;

            // parse command-line input
            OptionSet options = parser.parse(args);
            if(options.has(AdminParserUtils.OPT_HELP)) {
                printHelp(System.out);
                return;
            }

            // check required options and/or conflicting options
            AdminParserUtils.checkRequired(options, AdminParserUtils.OPT_STORE);
            AdminParserUtils.checkRequired(options, AdminParserUtils.OPT_URL);
            AdminParserUtils.checkRequired(options,
                                           AdminParserUtils.OPT_HEX,
                                           AdminParserUtils.OPT_JSON);
            AdminParserUtils.checkOptional(options,
                                           AdminParserUtils.OPT_NODE,
                                           AdminParserUtils.OPT_ALL_NODES);

            // load parameters
            if(options.has(AdminParserUtils.OPT_HEX)) {
                keyType = AdminParserUtils.OPT_HEX;
                keyStrings = (List<String>) options.valuesOf(AdminParserUtils.OPT_HEX);
            } else if(options.has(AdminParserUtils.OPT_JSON)) {
                keyType = AdminParserUtils.OPT_JSON;
                keyStrings = (List<String>) options.valuesOf(AdminParserUtils.OPT_JSON);
            }
            storeNames = (List<String>) options.valuesOf(AdminParserUtils.OPT_STORE);
            url = (String) options.valueOf(AdminParserUtils.OPT_URL);
            if(options.has(AdminParserUtils.OPT_NODE)) {
                nodeIds = (List<Integer>) options.valuesOf(AdminParserUtils.OPT_NODE);
                allNodes = false;
            }

            // execute command
            AdminClient adminClient = AdminToolUtils.getAdminClient(url);

            if(allNodes) {
                nodeIds = AdminToolUtils.getAllNodeIds(adminClient);
            }

            doDebugQueryKeys(adminClient, nodeIds, storeNames, keyStrings, keyType);
        }

        private static void doDebugQueryKey(AdminClient adminClient,
                                            List<Integer> queryingNodes,
                                            List<String> storeNames,
                                            String keyString,
                                            String keyFormat) throws IOException {

            Map<String, StoreDefinition> storeDefinitions = AdminToolUtils.getUserStoreDefMapOnNode(adminClient,
                                                                                                    queryingNodes.get(0));

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

            // iterate through stores
            for(final String storeName: storeNames) {
                // store definition
                StoreDefinition storeDefinition = storeDefinitions.get(storeName);
                if(storeDefinition == null) {
                    throw new StoreNotFoundException("Store " + storeName + " not found");
                }

                out.write("STORE_NAME: " + storeDefinition.getName() + "\n");

                // k-v serializer
                final SerializerDefinition keySerializerDef = storeDefinition.getKeySerializer();
                final SerializerDefinition valueSerializerDef = storeDefinition.getValueSerializer();
                SerializerFactory serializerFactory = new DefaultSerializerFactory();
                @SuppressWarnings("unchecked")
                final Serializer<Object> keySerializer = (Serializer<Object>) serializerFactory.getSerializer(keySerializerDef);
                @SuppressWarnings("unchecked")
                final Serializer<Object> valueSerializer = (Serializer<Object>) serializerFactory.getSerializer(valueSerializerDef);

                // compression strategy
                final CompressionStrategy keyCompressionStrategy;
                final CompressionStrategy valueCompressionStrategy;
                if(keySerializerDef != null && keySerializerDef.hasCompression()) {
                    keyCompressionStrategy = new CompressionStrategyFactory().get(keySerializerDef.getCompression());
                } else {
                    keyCompressionStrategy = null;
                }
                if(valueSerializerDef != null && valueSerializerDef.hasCompression()) {
                    valueCompressionStrategy = new CompressionStrategyFactory().get(valueSerializerDef.getCompression());
                } else {
                    valueCompressionStrategy = null;
                }

                if(keyCompressionStrategy == null) {
                    out.write("KEY_COMPRESSION_STRATEGY: None\n");
                } else {
                    out.write("KEY_COMPRESSION_STRATEGY: " + keyCompressionStrategy.getType()
                              + "\n");
                }
                out.write("KEY_SERIALIZER_NAME: " + keySerializerDef.getName() + "\n");
                for(Map.Entry<Integer, String> entry: keySerializerDef.getAllSchemaInfoVersions()
                                                                      .entrySet()) {
                    out.write(String.format("KEY_SCHEMA VERSION=%d\n", entry.getKey()));
                    out.write("====================================\n");
                    out.write(entry.getValue());
                    out.write("\n====================================\n");
                }
                out.write("\n");
                if(valueCompressionStrategy == null) {
                    out.write("VALUE_COMPRESSION_STRATEGY: None\n");
                } else {
                    out.write("VALUE_COMPRESSION_STRATEGY: " + valueCompressionStrategy.getType()
                              + "\n");
                }
                out.write("VALUE_SERIALIZER_NAME: " + valueSerializerDef.getName() + "\n");
                for(Map.Entry<Integer, String> entry: valueSerializerDef.getAllSchemaInfoVersions()
                                                                        .entrySet()) {
                    out.write(String.format("VALUE_SCHEMA %d\n", entry.getKey()));
                    out.write("====================================\n");
                    out.write(entry.getValue());
                    out.write("\n====================================\n");
                }
                out.write("\n");

                // although the streamingOps support multiple keys, we only
                // query
                // one key here
                ByteArray key;
                try {
                    if(keyFormat.equals(AdminParserUtils.OPT_JSON)) {
                        Object keyObject;
                        String keySerializerName = keySerializerDef.getName();
                        if(isAvroSchema(keySerializerName)) {
                            Schema keySchema = Schema.parse(keySerializerDef.getCurrentSchemaInfo());
                            JsonDecoder decoder = new JsonDecoder(keySchema, keyString);
                            GenericDatumReader<Object> datumReader = new GenericDatumReader<Object>(keySchema);
                            keyObject = datumReader.read(null, decoder);
                        } else if(keySerializerName.equals(DefaultSerializerFactory.JSON_SERIALIZER_TYPE_NAME)) {
                            JsonReader jsonReader = new JsonReader(new StringReader(keyString));
                            keyObject = jsonReader.read();
                        } else {
                            keyObject = keyString;
                        }

                        key = new ByteArray(keySerializer.toBytes(keyObject));
                    } else {
                        key = new ByteArray(ByteUtils.fromHexString(keyString));
                    }
                } catch(SerializationException se) {
                    System.err.println("Error serializing key " + keyString);
                    System.err.println("If this is a JSON key, you need to include escaped quotation marks in the command line if it is a string");
                    se.printStackTrace();
                    return;
                } catch(DecoderException de) {
                    System.err.println("Error decoding key " + keyString);
                    de.printStackTrace();
                    return;
                } catch(IOException io) {
                    System.err.println("Error parsing avro string " + keyString);
                    io.printStackTrace();
                    return;
                }

                boolean printedKey = false;
                // A Map<> could have been used instead of List<Entry<>> if
                // Versioned supported correct hash codes. Read the comment in
                // Versioned about the issue
                List<Entry<List<Versioned<byte[]>>, List<Integer>>> nodeValues = new ArrayList<Entry<List<Versioned<byte[]>>, List<Integer>>>();
                for(final Integer queryNodeId: queryingNodes) {
                    Iterator<QueryKeyResult> iterator;
                    iterator = adminClient.streamingOps.queryKeys(queryNodeId,
                                                                  storeName,
                                                                  Arrays.asList(key).iterator());
                    final StringWriter stringWriter = new StringWriter();

                    QueryKeyResult queryKeyResult = iterator.next();

                    if(!printedKey) {
                        // de-serialize and write key
                        byte[] keyBytes = queryKeyResult.getKey().get();
                        Object keyObject = keySerializer.toObject((null == keyCompressionStrategy) ? keyBytes
                                                                                                  : keyCompressionStrategy.inflate(keyBytes));

                        writeVoldKeyOrValueInternal(keyBytes,
                                                    keySerializer,
                                                    keyCompressionStrategy,
                                                    "KEY",
                                                    out);
                        printedKey = true;
                    }

                    // iterate through, de-serialize and write values
                    if(queryKeyResult.hasValues() && queryKeyResult.getValues().size() > 0) {

                        int elementId = -1;
                        for(int i = 0; i < nodeValues.size(); i++) {
                            if(Objects.equal(nodeValues.get(i).getKey(), queryKeyResult.getValues())) {
                                elementId = i;
                                break;
                            }
                        }

                        if(elementId == -1) {
                            ArrayList<Integer> nodes = new ArrayList<Integer>();
                            nodes.add(queryNodeId);
                            nodeValues.add(new AbstractMap.SimpleEntry<List<Versioned<byte[]>>, List<Integer>>(queryKeyResult.getValues(),
                                                                                                               nodes));
                        } else {
                            nodeValues.get(elementId).getValue().add(queryNodeId);
                        }

                        out.write(String.format("\nQueried node %d on store %s\n",
                                                queryNodeId,
                                                storeName));

                        int versionCount = 0;

                        if(queryKeyResult.getValues().size() > 1) {
                            out.write("VALUE " + versionCount + "\n");
                        }

                        for(Versioned<byte[]> versioned: queryKeyResult.getValues()) {

                            // write version
                            VectorClock version = (VectorClock) versioned.getVersion();
                            out.write("VECTOR_CLOCK_BYTE: "
                                      + ByteUtils.toHexString(version.toBytes()) + "\n");
                            out.write("VECTOR_CLOCK_TEXT: " + version.toString() + '['
                                      + new Date(version.getTimestamp()).toString() + "]\n");

                            // write value
                            byte[] valueBytes = versioned.getValue();
                            writeVoldKeyOrValueInternal(valueBytes,
                                                        valueSerializer,
                                                        valueCompressionStrategy,
                                                        "VALUE",
                                                        out);
                            versionCount++;
                        }
                    } // If a node does not host a key, it returns
                      // invalidmetdata
                      // exception.
                    else if(queryKeyResult.hasException()) {
                        boolean isInvalidMetadataException = queryKeyResult.getException() instanceof InvalidMetadataException;

                        // Print the exception if not InvalidMetadataException
                        // or
                        // you are querying only a single node.
                        if(!isInvalidMetadataException || queryingNodes.size() == 1) {
                            out.write(String.format("\nNode %d on store %s returned exception\n",
                                                    queryNodeId,
                                                    storeName));
                            out.write(queryKeyResult.getException().toString());
                            out.write("\n====================================\n");
                        }
                    } else {
                        if(queryingNodes.size() == 1) {
                            out.write(String.format("\nNode %d on store %s returned NULL\n",
                                                    queryNodeId,
                                                    storeName));
                            out.write("\n====================================\n");
                        }
                    }
                    out.flush();
                }

                out.write("\n====================================\n");
                for(Map.Entry<List<Versioned<byte[]>>, List<Integer>> nodeValue: nodeValues) {
                    out.write("Nodes with same Value "
                              + Arrays.toString(nodeValue.getValue().toArray()));
                    out.write("\n====================================\n");
                }
                if(nodeValues.size() > 1) {
                    out.write("\n*** Multiple (" + nodeValues.size()
                              + ") versions of key/value exist for the key ***\n");
                }
                out.flush();
            }
        }

        private static void writeVoldKeyOrValueInternal(byte[] input,
                                                        Serializer<Object> serializer,
                                                        CompressionStrategy compressionStrategy,
                                                        String prefix,
                                                        BufferedWriter out) throws IOException {
            out.write(prefix + "_BYTES\n====================================\n");
            out.write(ByteUtils.toHexString(input));
            out.write("\n====================================\n");
            try {
                Object inputObject = serializer.toObject((null == compressionStrategy) ? input
                                                                                      : compressionStrategy.inflate(input));

                out.write(prefix + "_TEXT\n====================================\n");
                if(inputObject instanceof GenericRecord) {
                    out.write(inputObject.toString());
                } else {
                    new JsonFactory(new ObjectMapper()).createJsonGenerator(out)
                                                       .writeObject(inputObject);
                }
                out.write("\n====================================\n\n");
            } catch(SerializationException e) {}

        }

        /**
         * Queries stores for a set of keys
         *
         * @param adminClient An instance of AdminClient points to given cluster
         * @param nodeIds Node ids to query keys from
         * @param storeNames Stores to be queried
         * @param keyStrings Keys to be queried
         * @param keyType Format of the keys: hex, json
         * @throws IOException
         *
         */
        public static void doDebugQueryKeys(AdminClient adminClient,
                                            List<Integer> nodeIds,
                                            List<String> storeNames,
                                            List<String> keyStrings,
                                            String keyType) throws IOException {
            // decide queryNode for storeDef
            Integer storeDefNodeId = nodeIds.get(0);
            Map<String, StoreDefinition> storeDefinitions = AdminToolUtils.getUserStoreDefMapOnNode(adminClient,
                                                                                                    storeDefNodeId);

            for(String keyString: keyStrings) {
                doDebugQueryKey(adminClient, nodeIds, storeNames, keyString, keyType);
            }
        }

        /**
         * Tells if serializer is avro schema
         *
         * @param serializerName Serializer to be checked
         * @return
         */
        private static boolean isAvroSchema(String serializerName) {
            if(serializerName.equals(DefaultSerializerFactory.AVRO_GENERIC_VERSIONED_TYPE_NAME)
               || serializerName.equals(DefaultSerializerFactory.AVRO_GENERIC_TYPE_NAME)
               || serializerName.equals(DefaultSerializerFactory.AVRO_REFLECTIVE_TYPE_NAME)
               || serializerName.equals(DefaultSerializerFactory.AVRO_SPECIFIC_TYPE_NAME)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * debug route command
     */
    public static class SubCommandDebugRoute extends AbstractAdminCommand {

        /**
         * Initializes parser
         *
         * @return OptionParser object with all available options
         */
        protected static OptionParser getParser() {
            OptionParser parser = new OptionParser();
            // help options
            AdminParserUtils.acceptsHelp(parser);
            // required options
            AdminParserUtils.acceptsHex(parser); // either --hex or
                                                 // --json
            AdminParserUtils.acceptsJson(parser); // either --hex or
                                                  // --json
            AdminParserUtils.acceptsStoreSingle(parser);
            AdminParserUtils.acceptsUrl(parser);
            return parser;
        }

        /**
         * Prints help menu for command.
         *
         * @param stream PrintStream object for output
         * @throws IOException
         */
        public static void printHelp(PrintStream stream) throws IOException {
            stream.println();
            stream.println("NAME");
            stream.println("  debug route - Show detailed routing plan for a given set of keys on a store");
            stream.println();
            stream.println("SYNOPSIS");
            stream.println("  debug route ((-x | -j) <key-list>) -s <store-name> -u <url>");
            stream.println();
            getParser().printHelpOn(stream);
            stream.println();
        }

        /**
         * Parses command-line and shows detailed routing information for a
         * given set of keys on a store.
         *
         * Usage: debug route ((-h | -j) <key-list>) -s <store-name> -u <url>
         *
         * @param args Command-line input
         * @param printHelp Tells whether to print help only or execute command
         *        actually
         * @throws Exception
         *
         */
        @SuppressWarnings("unchecked")
        public static void executeCommand(String[] args) throws Exception {

            OptionParser parser = getParser();

            // declare parameters
            String keyType = null;
            List<String> keyStrings = null;
            String storeName = null;
            String url = null;

            // parse command-line input
            OptionSet options = parser.parse(args);
            if(options.has(AdminParserUtils.OPT_HELP)) {
                printHelp(System.out);
                return;
            }

            // check required options and/or conflicting options
            AdminParserUtils.checkRequired(options, AdminParserUtils.OPT_STORE);
            AdminParserUtils.checkRequired(options, AdminParserUtils.OPT_URL);
            AdminParserUtils.checkRequired(options,
                                           AdminParserUtils.OPT_HEX,
                                           AdminParserUtils.OPT_JSON);

            // load parameters
            if(options.has(AdminParserUtils.OPT_HEX)) {
                keyType = AdminParserUtils.OPT_HEX;
                keyStrings = (List<String>) options.valuesOf(AdminParserUtils.OPT_HEX);
            } else if(options.has(AdminParserUtils.OPT_JSON)) {
                keyType = AdminParserUtils.OPT_JSON;
                keyStrings = (List<String>) options.valuesOf(AdminParserUtils.OPT_JSON);
                throw new VoldemortException("Key type OPT_JSON not supported.");
            }
            storeName = (String) options.valueOf(AdminParserUtils.OPT_STORE);
            url = (String) options.valueOf(AdminParserUtils.OPT_URL);

            // execute command
            AdminClient adminClient = AdminToolUtils.getAdminClient(url);

            doDebugRoute(adminClient, storeName, keyStrings, keyType);
        }

        /**
         * Shows detailed routing information for a given set of keys on a
         * store.
         *
         * @param adminClient An instance of AdminClient points to given cluster
         * @param storeName Store that contains keys
         * @param keyStrings Keys to show routing plan
         * @param keyType Format of the keys: hex
         * @throws DecoderException
         * @throws IOException
         *
         */
        public static void doDebugRoute(AdminClient adminClient,
                                        String storeName,
                                        List<String> keyStrings,
                                        String keyType) throws DecoderException {
            Cluster cluster = adminClient.getAdminClientCluster();
            List<StoreDefinition> storeDefs = adminClient.metadataMgmtOps.getRemoteStoreDefList()
                                                                         .getValue();
            StoreDefinition storeDef = StoreDefinitionUtils.getStoreDefinitionWithName(storeDefs,
                                                                                       storeName);
            StoreRoutingPlan routingPlan = new StoreRoutingPlan(cluster, storeDef);
            BaseStoreRoutingPlan bRoutingPlan = new BaseStoreRoutingPlan(cluster, storeDef);

            final int COLUMN_WIDTH = 30;

            for(String keyStr: keyStrings) {
                byte[] key = ByteUtils.fromHexString(keyStr);
                System.out.println("Key :" + keyStr);
                System.out.println("Replicating Partitions :"
                                   + routingPlan.getReplicatingPartitionList(key));
                System.out.println("Replicating Nodes :");
                List<Integer> nodeList = routingPlan.getReplicationNodeList(routingPlan.getMasterPartitionId(key));
                for(int i = 0; i < nodeList.size(); i++) {
                    System.out.println(nodeList.get(i) + "\t"
                                       + cluster.getNodeById(nodeList.get(i)).getHost());
                }

                System.out.println("Zone Nary information :");
                HashMap<Integer, Integer> zoneRepMap = storeDef.getZoneReplicationFactor();

                for(Zone zone: cluster.getZones()) {
                    System.out.println("\tZone #" + zone.getId());
                    int numReplicas = -1;
                    if(zoneRepMap == null) {
                        // non zoned cluster
                        numReplicas = storeDef.getReplicationFactor();
                    } else {
                        // zoned cluster
                        if(!zoneRepMap.containsKey(zone.getId())) {
                            Utils.croak("Repfactor for Zone " + zone.getId()
                                        + " not found in storedef");
                        }
                        numReplicas = zoneRepMap.get(zone.getId());
                    }

                    String FormatString = "%s %s %s\n";
                    System.out.format(FormatString,
                                      Utils.paddedString("REPLICA#", COLUMN_WIDTH),
                                      Utils.paddedString("PARTITION", COLUMN_WIDTH),
                                      Utils.paddedString("NODE", COLUMN_WIDTH));
                    for(int i = 0; i < numReplicas; i++) {
                        Integer nodeId = bRoutingPlan.getNodeIdForZoneNary(zone.getId(), i, key);
                        Integer partitionId = routingPlan.getNodesPartitionIdForKey(nodeId, key);
                        System.out.format(FormatString,
                                          Utils.paddedString(i + "", COLUMN_WIDTH),
                                          Utils.paddedString(partitionId.toString(), COLUMN_WIDTH),
                                          Utils.paddedString(nodeId
                                                                     + "("
                                                                     + cluster.getNodeById(nodeId)
                                                                              .getHost() + ")",
                                                             COLUMN_WIDTH));
                    }
                    System.out.println();
                }

                System.out.println("-----------------------------------------------");
                System.out.println();
            }
        }
    }

}
TOP

Related Classes of voldemort.tools.admin.command.AdminCommandDebug

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.