cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dbros...@apache.org
Subject [2/5] cassandra git commit: Move NodeToolCmd subclasses to their own package patch by dbrosius reviewed yukim for cassandra-8995
Date Wed, 08 Apr 2015 00:14:55 GMT
http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java
new file mode 100644
index 0000000..7ce0017
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/GetLoggingLevels.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import java.util.Map;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "getlogginglevels", description = "Get the runtime logging levels")
+public class GetLoggingLevels extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        // what if some one set a very long logger name? 50 space may not be enough...
+        System.out.printf("%n%-50s%10s%n", "Logger Name", "Log Level");
+        for (Map.Entry<String, String> entry : probe.getLoggingLevels().entrySet())
+            System.out.printf("%-50s%10s%n", entry.getKey(), entry.getValue());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
new file mode 100644
index 0000000..2c5d46b
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "getsstables", description = "Print the sstable filenames that own the key")
+public class GetSSTables extends NodeToolCmd
+{
+    @Arguments(usage = "<keyspace> <table> <key>", description = "The keyspace, the table, and the key")
+    private List<String> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() == 3, "getsstables requires ks, cf and key args");
+        String ks = args.get(0);
+        String cf = args.get(1);
+        String key = args.get(2);
+
+        List<String> sstables = probe.getSSTables(ks, cf, key);
+        for (String sstable : sstables)
+        {
+            System.out.println(sstable);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java
new file mode 100644
index 0000000..437eb54
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/GetStreamThroughput.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "getstreamthroughput", description = "Print the Mb/s throughput cap for streaming in the system")
+public class GetStreamThroughput extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        System.out.println("Current stream throughput: " + probe.getStreamThroughput() + " Mb/s");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java
new file mode 100644
index 0000000..2acfcf1
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/GossipInfo.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "gossipinfo", description = "Shows the gossip information for the cluster")
+public class GossipInfo extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        System.out.println(probe.getGossipInfo());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/HostStat.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/HostStat.java b/src/java/org/apache/cassandra/tools/nodetool/HostStat.java
new file mode 100644
index 0000000..19c0448
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/HostStat.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import java.net.InetAddress;
+
+public class HostStat
+{
+    public final InetAddress endpoint;
+    public final boolean resolveIp;
+    public final Float owns;
+    public final String token;
+
+    public HostStat(String token, InetAddress endpoint, boolean resolveIp, Float owns)
+    {
+        this.token = token;
+        this.endpoint = endpoint;
+        this.resolveIp = resolveIp;
+        this.owns = owns;
+    }
+
+    public String ipOrDns()
+    {
+        return resolveIp ? endpoint.getHostName() : endpoint.getHostAddress();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Info.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Info.java b/src/java/org/apache/cassandra/tools/nodetool/Info.java
new file mode 100644
index 0000000..5852fc7
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Info.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.lang.management.MemoryUsage;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.InstanceNotFoundException;
+
+import org.apache.cassandra.db.ColumnFamilyStoreMBean;
+import org.apache.cassandra.io.util.FileUtils;
+import org.apache.cassandra.service.CacheServiceMBean;
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "info", description = "Print node information (uptime, load, ...)")
+public class Info extends NodeToolCmd
+{
+    @Option(name = {"-T", "--tokens"}, description = "Display all tokens")
+    private boolean tokens = false;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        boolean gossipInitialized = probe.isInitialized();
+
+        System.out.printf("%-23s: %s%n", "ID", probe.getLocalHostId());
+        System.out.printf("%-23s: %s%n", "Gossip active", gossipInitialized);
+        System.out.printf("%-23s: %s%n", "Thrift active", probe.isThriftServerRunning());
+        System.out.printf("%-23s: %s%n", "Native Transport active", probe.isNativeTransportRunning());
+        System.out.printf("%-23s: %s%n", "Load", probe.getLoadString());
+        if (gossipInitialized)
+            System.out.printf("%-23s: %s%n", "Generation No", probe.getCurrentGenerationNumber());
+        else
+            System.out.printf("%-23s: %s%n", "Generation No", 0);
+
+        // Uptime
+        long secondsUp = probe.getUptime() / 1000;
+        System.out.printf("%-23s: %d%n", "Uptime (seconds)", secondsUp);
+
+        // Memory usage
+        MemoryUsage heapUsage = probe.getHeapMemoryUsage();
+        double memUsed = (double) heapUsage.getUsed() / (1024 * 1024);
+        double memMax = (double) heapUsage.getMax() / (1024 * 1024);
+        System.out.printf("%-23s: %.2f / %.2f%n", "Heap Memory (MB)", memUsed, memMax);
+        try
+        {
+            System.out.printf("%-23s: %.2f%n", "Off Heap Memory (MB)", getOffHeapMemoryUsed(probe));
+        }
+        catch (RuntimeException e)
+        {
+            // offheap-metrics introduced in 2.1.3 - older versions do not have the appropriate mbeans
+            if (!(e.getCause() instanceof InstanceNotFoundException))
+                throw e;
+        }
+
+        // Data Center/Rack
+        System.out.printf("%-23s: %s%n", "Data Center", probe.getDataCenter());
+        System.out.printf("%-23s: %s%n", "Rack", probe.getRack());
+
+        // Exceptions
+        System.out.printf("%-23s: %s%n", "Exceptions", probe.getStorageMetric("Exceptions"));
+
+        CacheServiceMBean cacheService = probe.getCacheServiceMBean();
+
+        // Key Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds
+        System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n",
+                "Key Cache",
+                probe.getCacheMetric("KeyCache", "Entries"),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("KeyCache", "Size")),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("KeyCache", "Capacity")),
+                probe.getCacheMetric("KeyCache", "Hits"),
+                probe.getCacheMetric("KeyCache", "Requests"),
+                probe.getCacheMetric("KeyCache", "HitRate"),
+                cacheService.getKeyCacheSavePeriodInSeconds());
+
+        // Row Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds
+        System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n",
+                "Row Cache",
+                probe.getCacheMetric("RowCache", "Entries"),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("RowCache", "Size")),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("RowCache", "Capacity")),
+                probe.getCacheMetric("RowCache", "Hits"),
+                probe.getCacheMetric("RowCache", "Requests"),
+                probe.getCacheMetric("RowCache", "HitRate"),
+                cacheService.getRowCacheSavePeriodInSeconds());
+
+        // Counter Cache: Hits, Requests, RecentHitRate, SavePeriodInSeconds
+        System.out.printf("%-23s: entries %d, size %s, capacity %s, %d hits, %d requests, %.3f recent hit rate, %d save period in seconds%n",
+                "Counter Cache",
+                probe.getCacheMetric("CounterCache", "Entries"),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("CounterCache", "Size")),
+                FileUtils.stringifyFileSize((long) probe.getCacheMetric("CounterCache", "Capacity")),
+                probe.getCacheMetric("CounterCache", "Hits"),
+                probe.getCacheMetric("CounterCache", "Requests"),
+                probe.getCacheMetric("CounterCache", "HitRate"),
+                cacheService.getCounterCacheSavePeriodInSeconds());
+
+        // Tokens
+        List<String> tokens = probe.getTokens();
+        if (tokens.size() == 1 || this.tokens)
+            for (String token : tokens)
+                System.out.printf("%-23s: %s%n", "Token", token);
+        else
+            System.out.printf("%-23s: (invoke with -T/--tokens to see all %d tokens)%n", "Token", tokens.size());
+    }
+
+    /**
+     * Returns the total off heap memory used in MB.
+     * @return the total off heap memory used in MB.
+     */
+    private static double getOffHeapMemoryUsed(NodeProbe probe)
+    {
+        long offHeapMemUsedInBytes = 0;
+        // get a list of column family stores
+        Iterator<Map.Entry<String, ColumnFamilyStoreMBean>> cfamilies = probe.getColumnFamilyStoreMBeanProxies();
+
+        while (cfamilies.hasNext())
+        {
+            Entry<String, ColumnFamilyStoreMBean> entry = cfamilies.next();
+            String keyspaceName = entry.getKey();
+            String cfName = entry.getValue().getColumnFamilyName();
+
+            offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "MemtableOffHeapSize");
+            offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "BloomFilterOffHeapMemoryUsed");
+            offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "IndexSummaryOffHeapMemoryUsed");
+            offHeapMemUsedInBytes += (Long) probe.getColumnFamilyMetric(keyspaceName, cfName, "CompressionMetadataOffHeapMemoryUsed");
+        }
+
+        return offHeapMemUsedInBytes / (1024d * 1024);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java
new file mode 100644
index 0000000..a5f0ebc
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateCounterCache.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "invalidatecountercache", description = "Invalidate the counter cache")
+public class InvalidateCounterCache extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.invalidateCounterCache();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java
new file mode 100644
index 0000000..70abd53
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateKeyCache.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "invalidatekeycache", description = "Invalidate the key cache")
+public class InvalidateKeyCache extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.invalidateKeyCache();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java b/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java
new file mode 100644
index 0000000..149f80b
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/InvalidateRowCache.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "invalidaterowcache", description = "Invalidate the row cache")
+public class InvalidateRowCache extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.invalidateRowCache();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Join.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Join.java b/src/java/org/apache/cassandra/tools/nodetool/Join.java
new file mode 100644
index 0000000..5815591
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Join.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkState;
+import io.airlift.command.Command;
+
+import java.io.IOException;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "join", description = "Join the ring")
+public class Join extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkState(!probe.isJoined(), "This node has already joined the ring.");
+
+        try
+        {
+            probe.joinRing();
+        } catch (IOException e)
+        {
+            throw new RuntimeException("Error during joining the ring", e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java
new file mode 100644
index 0000000..ee7bf34
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/ListSnapshots.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.openmbean.TabularData;
+
+import org.apache.cassandra.io.util.FileUtils;
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "listsnapshots", description = "Lists all the snapshots along with the size on disk and true size.")
+public class ListSnapshots extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        try
+        {
+            System.out.println("Snapshot Details: ");
+
+            final Map<String,TabularData> snapshotDetails = probe.getSnapshotDetails();
+            if (snapshotDetails.isEmpty())
+            {
+                System.out.printf("There are no snapshots");
+                return;
+            }
+
+            final long trueSnapshotsSize = probe.trueSnapshotsSize();
+            final String format = "%-20s%-29s%-29s%-19s%-19s%n";
+            // display column names only once
+            final List<String> indexNames = snapshotDetails.entrySet().iterator().next().getValue().getTabularType().getIndexNames();
+            System.out.printf(format, (Object[]) indexNames.toArray(new String[indexNames.size()]));
+
+            for (final Map.Entry<String, TabularData> snapshotDetail : snapshotDetails.entrySet())
+            {
+                Set<?> values = snapshotDetail.getValue().keySet();
+                for (Object eachValue : values)
+                {
+                    final List<?> value = (List<?>) eachValue;
+                    System.out.printf(format, value.toArray(new Object[value.size()]));
+                }
+            }
+
+            System.out.println("\nTotal TrueDiskSpaceUsed: " + FileUtils.stringifyFileSize(trueSnapshotsSize) + "\n");
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Error during list snapshot", e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Move.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Move.java b/src/java/org/apache/cassandra/tools/nodetool/Move.java
new file mode 100644
index 0000000..fc6b1bf
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Move.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.io.IOException;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "move", description = "Move node on the token ring to a new token")
+public class Move extends NodeToolCmd
+{
+    @Arguments(usage = "<new token>", description = "The new token.", required = true)
+    private String newToken = EMPTY;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        try
+        {
+            probe.move(newToken);
+        } catch (IOException e)
+        {
+            throw new RuntimeException("Error during moving node", e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/NetStats.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/NetStats.java b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java
new file mode 100644
index 0000000..cd2f1a2
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/NetStats.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.util.Set;
+
+import org.apache.cassandra.io.util.FileUtils;
+import org.apache.cassandra.net.MessagingServiceMBean;
+import org.apache.cassandra.streaming.ProgressInfo;
+import org.apache.cassandra.streaming.SessionInfo;
+import org.apache.cassandra.streaming.StreamState;
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "netstats", description = "Print network information on provided host (connecting node by default)")
+public class NetStats extends NodeToolCmd
+{
+    @Option(title = "human_readable",
+            name = {"-H", "--human-readable"},
+            description = "Display bytes in human readable form, i.e. KB, MB, GB, TB")
+    private boolean humanReadable = false;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        System.out.printf("Mode: %s%n", probe.getOperationMode());
+        Set<StreamState> statuses = probe.getStreamStatus();
+        if (statuses.isEmpty())
+            System.out.println("Not sending any streams.");
+        for (StreamState status : statuses)
+        {
+            System.out.printf("%s %s%n", status.description, status.planId.toString());
+            for (SessionInfo info : status.sessions)
+            {
+                System.out.printf("    %s", info.peer.toString());
+                // print private IP when it is used
+                if (!info.peer.equals(info.connecting))
+                {
+                    System.out.printf(" (using %s)", info.connecting.toString());
+                }
+                System.out.printf("%n");
+                if (!info.receivingSummaries.isEmpty())
+                {
+                    if (humanReadable)
+                        System.out.printf("        Receiving %d files, %s total. Already received %d files, %s total%n", info.getTotalFilesToReceive(), FileUtils.stringifyFileSize(info.getTotalSizeToReceive()), info.getTotalFilesReceived(), FileUtils.stringifyFileSize(info.getTotalSizeReceived()));
+                    else
+                        System.out.printf("        Receiving %d files, %d bytes total. Already received %d files, %d bytes total%n", info.getTotalFilesToReceive(), info.getTotalSizeToReceive(), info.getTotalFilesReceived(), info.getTotalSizeReceived());
+                    for (ProgressInfo progress : info.getReceivingFiles())
+                    {
+                        System.out.printf("            %s%n", progress.toString());
+                    }
+                }
+                if (!info.sendingSummaries.isEmpty())
+                {
+                    if (humanReadable)
+                        System.out.printf("        Sending %d files, %s total. Already sent %d files, %s total%n", info.getTotalFilesToSend(), FileUtils.stringifyFileSize(info.getTotalSizeToSend()), info.getTotalFilesSent(), FileUtils.stringifyFileSize(info.getTotalSizeSent()));
+                    else
+                        System.out.printf("        Sending %d files, %d bytes total. Already sent %d files, %d bytes total%n", info.getTotalFilesToSend(), info.getTotalSizeToSend(), info.getTotalFilesSent(), info.getTotalSizeSent());
+                    for (ProgressInfo progress : info.getSendingFiles())
+                    {
+                        System.out.printf("            %s%n", progress.toString());
+                    }
+                }
+            }
+        }
+
+        if (!probe.isStarting())
+        {
+            System.out.printf("Read Repair Statistics:%nAttempted: %d%nMismatch (Blocking): %d%nMismatch (Background): %d%n", probe.getReadRepairAttempted(), probe.getReadRepairRepairedBlocking(), probe.getReadRepairRepairedBackground());
+
+            MessagingServiceMBean ms = probe.msProxy;
+            System.out.printf("%-25s", "Pool Name");
+            System.out.printf("%10s", "Active");
+            System.out.printf("%10s", "Pending");
+            System.out.printf("%15s%n", "Completed");
+
+            int pending;
+            long completed;
+
+            pending = 0;
+            for (int n : ms.getLargeMessagePendingTasks().values())
+                pending += n;
+            completed = 0;
+            for (long n : ms.getLargeMessageCompletedTasks().values())
+                completed += n;
+            System.out.printf("%-25s%10s%10s%15s%n", "Large messages", "n/a", pending, completed);
+
+            pending = 0;
+            for (int n : ms.getSmallMessagePendingTasks().values())
+                pending += n;
+            completed = 0;
+            for (long n : ms.getSmallMessageCompletedTasks().values())
+                completed += n;
+            System.out.printf("%-25s%10s%10s%15s%n", "Small messages", "n/a", pending, completed);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java
new file mode 100644
index 0000000..ed1f655
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/PauseHandoff.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "pausehandoff", description = "Pause hints delivery process")
+public class PauseHandoff extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.pauseHintsDelivery();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java
new file mode 100644
index 0000000..2a2851d
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/ProxyHistograms.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static java.lang.String.format;
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "proxyhistograms", description = "Print statistic histograms for network operations")
+public class ProxyHistograms extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        String[] percentiles = new String[]{"50%", "75%", "95%", "98%", "99%", "Min", "Max"};
+        double[] readLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Read"));
+        double[] writeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("Write"));
+        double[] rangeLatency = probe.metricPercentilesAsArray(probe.getProxyMetric("RangeSlice"));
+
+        System.out.println("proxy histograms");
+        System.out.println(format("%-10s%18s%18s%18s",
+                "Percentile", "Read Latency", "Write Latency", "Range Latency"));
+        System.out.println(format("%-10s%18s%18s%18s",
+                "", "(micros)", "(micros)", "(micros)"));
+        for (int i = 0; i < percentiles.length; i++)
+        {
+            System.out.println(format("%-10s%18.2f%18.2f%18.2f",
+                    percentiles[i],
+                    readLatency[i],
+                    writeLatency[i],
+                    rangeLatency[i]));
+        }
+        System.out.println();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java
new file mode 100644
index 0000000..e079a4b
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/RangeKeySample.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "rangekeysample", description = "Shows the sampled keys held across all keyspaces")
+public class RangeKeySample extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        System.out.println("RangeKeySample: ");
+        List<String> tokenStrings = probe.sampleKeyRange();
+        for (String tokenString : tokenStrings)
+        {
+            System.out.println("\t" + tokenString);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java
new file mode 100644
index 0000000..8a6dbf1
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "rebuild", description = "Rebuild data by streaming from other nodes (similarly to bootstrap)")
+public class Rebuild extends NodeToolCmd
+{
+    @Arguments(usage = "<src-dc-name>", description = "Name of DC from which to select sources for streaming. By default, pick any DC")
+    private String sourceDataCenterName = null;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.rebuild(sourceDataCenterName);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java b/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java
new file mode 100644
index 0000000..9985b2b
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/RebuildIndex.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.toArray;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "rebuild_index", description = "A full rebuild of native secondary indexes for a given table")
+public class RebuildIndex extends NodeToolCmd
+{
+    @Arguments(usage = "<keyspace> <table> <indexName...>", description = "The keyspace and table name followed by a list of index names (IndexNameExample: Standard3.IdxName Standard3.IdxName1)")
+    List<String> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() >= 3, "rebuild_index requires ks, cf and idx args");
+        probe.rebuildIndex(args.get(0), args.get(1), toArray(args.subList(2, args.size()), String.class));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Refresh.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Refresh.java b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java
new file mode 100644
index 0000000..153255c
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Refresh.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "refresh", description = "Load newly placed SSTables to the system without restart")
+public class Refresh extends NodeToolCmd
+{
+    @Arguments(usage = "<keyspace> <table>", description = "The keyspace and table name")
+    private List<String> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() == 2, "refresh requires ks and cf args");
+        probe.loadNewSSTables(args.get(0), args.get(1));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java b/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java
new file mode 100644
index 0000000..416aff0
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/ReloadTriggers.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "reloadtriggers", description = "Reload trigger classes")
+public class ReloadTriggers extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.reloadTriggers();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java
new file mode 100644
index 0000000..848049e
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/RemoveNode.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "removenode", description = "Show status of current node removal, force completion of pending removal or remove provided ID")
+public class RemoveNode extends NodeToolCmd
+{
+    @Arguments(title = "remove_operation", usage = "<status>|<force>|<ID>", description = "Show status of current node removal, force completion of pending removal, or remove provided ID", required = true)
+    private String removeOperation = EMPTY;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        switch (removeOperation)
+        {
+            case "status":
+                System.out.println("RemovalStatus: " + probe.getRemovalStatus());
+                break;
+            case "force":
+                System.out.println("RemovalStatus: " + probe.getRemovalStatus());
+                probe.forceRemoveCompletion();
+                break;
+            default:
+                probe.removeNode(removeOperation);
+                break;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Repair.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Repair.java b/src/java/org/apache/cassandra/tools/nodetool/Repair.java
new file mode 100644
index 0000000..45b3d98
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Repair.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cassandra.repair.RepairParallelism;
+import org.apache.cassandra.repair.messages.RepairOption;
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+import org.apache.commons.lang3.StringUtils;
+
+@Command(name = "repair", description = "Repair one or more tables")
+public class Repair extends NodeToolCmd
+{
+    @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables")
+    private List<String> args = new ArrayList<>();
+
+    @Option(title = "seqential", name = {"-seq", "--sequential"}, description = "Use -seq to carry out a sequential repair")
+    private boolean sequential = false;
+
+    @Option(title = "dc parallel", name = {"-dcpar", "--dc-parallel"}, description = "Use -dcpar to repair data centers in parallel.")
+    private boolean dcParallel = false;
+
+    @Option(title = "local_dc", name = {"-local", "--in-local-dc"}, description = "Use -local to only repair against nodes in the same datacenter")
+    private boolean localDC = false;
+
+    @Option(title = "specific_dc", name = {"-dc", "--in-dc"}, description = "Use -dc to repair specific datacenters")
+    private List<String> specificDataCenters = new ArrayList<>();
+
+    @Option(title = "specific_host", name = {"-hosts", "--in-hosts"}, description = "Use -hosts to repair specific hosts")
+    private List<String> specificHosts = new ArrayList<>();
+
+    @Option(title = "start_token", name = {"-st", "--start-token"}, description = "Use -st to specify a token at which the repair range starts")
+    private String startToken = EMPTY;
+
+    @Option(title = "end_token", name = {"-et", "--end-token"}, description = "Use -et to specify a token at which repair range ends")
+    private String endToken = EMPTY;
+
+    @Option(title = "primary_range", name = {"-pr", "--partitioner-range"}, description = "Use -pr to repair only the first range returned by the partitioner")
+    private boolean primaryRange = false;
+
+    @Option(title = "full", name = {"-full", "--full"}, description = "Use -full to issue a full repair.")
+    private boolean fullRepair = false;
+
+    @Option(title = "job_threads", name = {"-j", "--job-threads"}, description = "Number of threads to run repair jobs. " +
+                                                                                 "Usually this means number of CFs to repair concurrently. " +
+                                                                                 "WARNING: increasing this puts more load on repairing nodes, so be careful. (default: 1, max: 4)")
+    private int numJobThreads = 1;
+
+    @Option(title = "trace_repair", name = {"-tr", "--trace"}, description = "Use -tr to trace the repair. Traces are logged to system_traces.events.")
+    private boolean trace = false;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        List<String> keyspaces = parseOptionalKeyspace(args, probe);
+        String[] cfnames = parseOptionalColumnFamilies(args);
+
+        if (primaryRange && (!specificDataCenters.isEmpty() || !specificHosts.isEmpty()))
+            throw new RuntimeException("Primary range repair should be performed on all nodes in the cluster.");
+
+        for (String keyspace : keyspaces)
+        {
+            Map<String, String> options = new HashMap<>();
+            RepairParallelism parallelismDegree = RepairParallelism.PARALLEL;
+            if (sequential)
+                parallelismDegree = RepairParallelism.SEQUENTIAL;
+            else if (dcParallel)
+                parallelismDegree = RepairParallelism.DATACENTER_AWARE;
+            options.put(RepairOption.PARALLELISM_KEY, parallelismDegree.getName());
+            options.put(RepairOption.PRIMARY_RANGE_KEY, Boolean.toString(primaryRange));
+            options.put(RepairOption.INCREMENTAL_KEY, Boolean.toString(!fullRepair));
+            options.put(RepairOption.JOB_THREADS_KEY, Integer.toString(numJobThreads));
+            options.put(RepairOption.TRACE_KEY, Boolean.toString(trace));
+            options.put(RepairOption.COLUMNFAMILIES_KEY, StringUtils.join(cfnames, ","));
+            if (!startToken.isEmpty() || !endToken.isEmpty())
+            {
+                options.put(RepairOption.RANGES_KEY, startToken + ":" + endToken);
+            }
+            if (localDC)
+            {
+                options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(newArrayList(probe.getDataCenter()), ","));
+            }
+            else
+            {
+                options.put(RepairOption.DATACENTERS_KEY, StringUtils.join(specificDataCenters, ","));
+            }
+            options.put(RepairOption.HOSTS_KEY, StringUtils.join(specificHosts, ","));
+            try
+            {
+                probe.repairAsync(System.out, keyspace, options);
+            } catch (Exception e)
+            {
+                throw new RuntimeException("Error occurred during repair", e);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java b/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java
new file mode 100644
index 0000000..43280ab
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/ResetLocalSchema.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import java.io.IOException;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "resetlocalschema", description = "Reset node's local schema and resync")
+public class ResetLocalSchema extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        try
+        {
+            probe.resetLocalSchema();
+        } catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java b/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java
new file mode 100644
index 0000000..584ab64
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/ResumeHandoff.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "resumehandoff", description = "Resume hints delivery process")
+public class ResumeHandoff extends NodeToolCmd
+{
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.resumeHintsDelivery();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Ring.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Ring.java b/src/java/org/apache/cassandra/tools/nodetool/Ring.java
new file mode 100644
index 0000000..5102029
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Ring.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static java.lang.String.format;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+import com.google.common.collect.LinkedHashMultimap;
+
+@Command(name = "ring", description = "Print information about the token ring")
+public class Ring extends NodeToolCmd
+{
+    @Arguments(description = "Specify a keyspace for accurate ownership information (topology awareness)")
+    private String keyspace = null;
+
+    @Option(title = "resolve_ip", name = {"-r", "--resolve-ip"}, description = "Show node domain names instead of IPs")
+    private boolean resolveIp = false;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap();
+        LinkedHashMultimap<String, String> endpointsToTokens = LinkedHashMultimap.create();
+        boolean haveVnodes = false;
+        for (Map.Entry<String, String> entry : tokensToEndpoints.entrySet())
+        {
+            haveVnodes |= endpointsToTokens.containsKey(entry.getValue());
+            endpointsToTokens.put(entry.getValue(), entry.getKey());
+        }
+
+        int maxAddressLength = Collections.max(endpointsToTokens.keys(), new Comparator<String>()
+        {
+            @Override
+            public int compare(String first, String second)
+            {
+                return ((Integer) first.length()).compareTo(second.length());
+            }
+        }).length();
+
+        String formatPlaceholder = "%%-%ds  %%-12s%%-7s%%-8s%%-16s%%-20s%%-44s%%n";
+        String format = format(formatPlaceholder, maxAddressLength);
+
+        StringBuffer errors = new StringBuffer();
+        boolean showEffectiveOwnership = true;
+        // Calculate per-token ownership of the ring
+        Map<InetAddress, Float> ownerships;
+        try
+        {
+            ownerships = probe.effectiveOwnership(keyspace);
+        }
+        catch (IllegalStateException ex)
+        {
+            ownerships = probe.getOwnership();
+            errors.append("Note: " + ex.getMessage() + "%n");
+            showEffectiveOwnership = false;
+        }
+        catch (IllegalArgumentException ex)
+        {
+            System.out.printf("%nError: " + ex.getMessage() + "%n");
+            return;
+        }
+
+
+        System.out.println();
+        for (Entry<String, SetHostStat> entry : NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships).entrySet())
+            printDc(probe, format, entry.getKey(), endpointsToTokens, entry.getValue(),showEffectiveOwnership);
+
+        if (haveVnodes)
+        {
+            System.out.println("  Warning: \"nodetool ring\" is used to output all the tokens of a node.");
+            System.out.println("  To view status related info of a node use \"nodetool status\" instead.\n");
+        }
+
+        System.out.printf("%n  " + errors.toString());
+    }
+
+    private void printDc(NodeProbe probe, String format,
+                         String dc,
+                         LinkedHashMultimap<String, String> endpointsToTokens,
+                         SetHostStat hoststats,boolean showEffectiveOwnership)
+    {
+        Collection<String> liveNodes = probe.getLiveNodes();
+        Collection<String> deadNodes = probe.getUnreachableNodes();
+        Collection<String> joiningNodes = probe.getJoiningNodes();
+        Collection<String> leavingNodes = probe.getLeavingNodes();
+        Collection<String> movingNodes = probe.getMovingNodes();
+        Map<String, String> loadMap = probe.getLoadMap();
+
+        System.out.println("Datacenter: " + dc);
+        System.out.println("==========");
+
+        // get the total amount of replicas for this dc and the last token in this dc's ring
+        List<String> tokens = new ArrayList<>();
+        String lastToken = "";
+
+        for (HostStat stat : hoststats)
+        {
+            tokens.addAll(endpointsToTokens.get(stat.endpoint.getHostAddress()));
+            lastToken = tokens.get(tokens.size() - 1);
+        }
+
+        System.out.printf(format, "Address", "Rack", "Status", "State", "Load", "Owns", "Token");
+
+        if (hoststats.size() > 1)
+            System.out.printf(format, "", "", "", "", "", "", lastToken);
+        else
+            System.out.println();
+
+        for (HostStat stat : hoststats)
+        {
+            String endpoint = stat.endpoint.getHostAddress();
+            String rack;
+            try
+            {
+                rack = probe.getEndpointSnitchInfoProxy().getRack(endpoint);
+            }
+            catch (UnknownHostException e)
+            {
+                rack = "Unknown";
+            }
+
+            String status = liveNodes.contains(endpoint)
+                    ? "Up"
+                    : deadNodes.contains(endpoint)
+                            ? "Down"
+                            : "?";
+
+            String state = "Normal";
+
+            if (joiningNodes.contains(endpoint))
+                state = "Joining";
+            else if (leavingNodes.contains(endpoint))
+                state = "Leaving";
+            else if (movingNodes.contains(endpoint))
+                state = "Moving";
+
+            String load = loadMap.containsKey(endpoint)
+                    ? loadMap.get(endpoint)
+                    : "?";
+            String owns = stat.owns != null && showEffectiveOwnership? new DecimalFormat("##0.00%").format(stat.owns) : "?";
+            System.out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token);
+        }
+        System.out.println();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/Scrub.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Scrub.java b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java
new file mode 100644
index 0000000..8064b8e
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/Scrub.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "scrub", description = "Scrub (rebuild sstables for) one or more tables")
+public class Scrub extends NodeToolCmd
+{
+    @Arguments(usage = "[<keyspace> <tables>...]", description = "The keyspace followed by one or many tables")
+    private List<String> args = new ArrayList<>();
+
+    @Option(title = "disable_snapshot",
+            name = {"-ns", "--no-snapshot"},
+            description = "Scrubbed CFs will be snapshotted first, if disableSnapshot is false. (default false)")
+    private boolean disableSnapshot = false;
+
+    @Option(title = "skip_corrupted",
+            name = {"-s", "--skip-corrupted"},
+            description = "Skip corrupted partitions even when scrubbing counter tables. (default false)")
+    private boolean skipCorrupted = false;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        List<String> keyspaces = parseOptionalKeyspace(args, probe);
+        String[] cfnames = parseOptionalColumnFamilies(args);
+
+        for (String keyspace : keyspaces)
+        {
+            try
+            {
+                probe.scrub(System.out, disableSnapshot, skipCorrupted, keyspace, cfnames);
+            } catch (IllegalArgumentException e)
+            {
+                throw e;
+            } catch (Exception e)
+            {
+                throw new RuntimeException("Error occurred during scrubbing", e);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java b/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java
new file mode 100644
index 0000000..6c280d8
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetCacheCapacity.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "setcachecapacity", description = "Set global key, row, and counter cache capacities (in MB units)")
+public class SetCacheCapacity extends NodeToolCmd
+{
+    @Arguments(title = "<key-cache-capacity> <row-cache-capacity> <counter-cache-capacity>",
+               usage = "<key-cache-capacity> <row-cache-capacity> <counter-cache-capacity>",
+               description = "Key cache, row cache, and counter cache (in MB)",
+               required = true)
+    private List<Integer> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() == 3, "setcachecapacity requires key-cache-capacity, row-cache-capacity, and counter-cache-capacity args.");
+        probe.setCacheCapacities(args.get(0), args.get(1), args.get(2));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java b/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java
new file mode 100644
index 0000000..12a4570
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetCacheKeysToSave.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "setcachekeystosave", description = "Set number of keys saved by each cache for faster post-restart warmup. 0 to disable")
+public class SetCacheKeysToSave extends NodeToolCmd
+{
+    @Arguments(title = "<key-cache-keys-to-save> <row-cache-keys-to-save> <counter-cache-keys-to-save>",
+               usage = "<key-cache-keys-to-save> <row-cache-keys-to-save> <counter-cache-keys-to-save>",
+               description = "The number of keys saved by each cache. 0 to disable",
+               required = true)
+    private List<Integer> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() == 3, "setcachekeystosave requires key-cache-keys-to-save, row-cache-keys-to-save, and counter-cache-keys-to-save args.");
+        probe.setCacheKeysToSave(args.get(0), args.get(1), args.get(2));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java
new file mode 100644
index 0000000..304f2b7
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThreshold.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.Integer.parseInt;
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "setcompactionthreshold", description = "Set min and max compaction thresholds for a given table")
+public class SetCompactionThreshold extends NodeToolCmd
+{
+    @Arguments(title = "<keyspace> <table> <minthreshold> <maxthreshold>", usage = "<keyspace> <table> <minthreshold> <maxthreshold>", description = "The keyspace, the table, min and max threshold", required = true)
+    private List<String> args = new ArrayList<>();
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        checkArgument(args.size() == 4, "setcompactionthreshold requires ks, cf, min, and max threshold args.");
+
+        int minthreshold = parseInt(args.get(2));
+        int maxthreshold = parseInt(args.get(3));
+        checkArgument(minthreshold >= 0 && maxthreshold >= 0, "Thresholds must be positive integers");
+        checkArgument(minthreshold <= maxthreshold, "Min threshold cannot be greater than max.");
+        checkArgument(minthreshold >= 2 || maxthreshold == 0, "Min threshold must be at least 2");
+
+        probe.setCompactionThreshold(args.get(0), args.get(1), minthreshold, maxthreshold);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java
new file mode 100644
index 0000000..0111a20
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetCompactionThroughput.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "setcompactionthroughput", description = "Set the MB/s throughput cap for compaction in the system, or 0 to disable throttling")
+public class SetCompactionThroughput extends NodeToolCmd
+{
+    @Arguments(title = "compaction_throughput", usage = "<value_in_mb>", description = "Value in MB, 0 to disable throttling", required = true)
+    private Integer compactionThroughput = null;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.setCompactionThroughput(compactionThroughput);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c5a81900/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java b/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java
new file mode 100644
index 0000000..d20ff3f
--- /dev/null
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetHintedHandoffThrottleInKB.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.cassandra.tools.nodetool;
+
+import io.airlift.command.Arguments;
+import io.airlift.command.Command;
+
+import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+
+@Command(name = "sethintedhandoffthrottlekb", description =  "Set hinted handoff throttle in kb per second, per delivery thread.")
+public class SetHintedHandoffThrottleInKB extends NodeToolCmd
+{
+    @Arguments(title = "throttle_in_kb", usage = "<value_in_kb_per_sec>", description = "Value in KB per second", required = true)
+    private Integer throttleInKB = null;
+
+    @Override
+    public void execute(NodeProbe probe)
+    {
+        probe.setHintedHandoffThrottleInKB(throttleInKB);
+    }
+}
\ No newline at end of file


Mime
View raw message