Repository: ignite
Updated Branches:
  refs/heads/ignite-2.5 9ad7be2f5 -> 4aa567519


IGNITE-7940 Visor CMD: Added "cache -slp" and "cache -rlp" commands to show and 
reset lost partitions for specified cache.

(cherry picked from commit abfa0f5)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4aa56751
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4aa56751
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4aa56751

Branch: refs/heads/ignite-2.5
Commit: 4aa56751906e5db7aad025a7193933fa929aae26
Parents: 9ad7be2
Author: Vasiliy Sisko <vsi...@gridgain.com>
Authored: Mon Apr 9 22:13:21 2018 +0700
Committer: Alexey Kuznetsov <akuznet...@apache.org>
Committed: Mon Apr 9 22:21:02 2018 +0700

----------------------------------------------------------------------
 .../cache/VisorCacheLostPartitionsTask.java     |  85 ++++++++++
 .../cache/VisorCacheLostPartitionsTaskArg.java  |  73 ++++++++
 .../VisorCacheLostPartitionsTaskResult.java     |  74 ++++++++
 .../VisorCacheResetLostPartitionsTask.java      |  65 +++++++
 .../VisorCacheResetLostPartitionsTaskArg.java   |  73 ++++++++
 .../commands/cache/VisorCacheCommand.scala      |  34 +++-
 .../cache/VisorCacheLostPartitionsCommand.scala | 170 +++++++++++++++++++
 .../VisorCacheResetLostPartitionsCommand.scala  | 132 ++++++++++++++
 8 files changed, 702 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTask.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTask.java
new file mode 100644
index 0000000..24b4069
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTask.java
@@ -0,0 +1,85 @@
+/*
+ * 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.ignite.internal.visor.cache;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorOneNodeTask;
+
+/**
+ * Collect list of lost partitions.
+ */
+@GridInternal
+public class VisorCacheLostPartitionsTask
+    extends VisorOneNodeTask<VisorCacheLostPartitionsTaskArg, 
VisorCacheLostPartitionsTaskResult> {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** {@inheritDoc} */
+    @Override protected VisorCacheLostPartitionsJob 
job(VisorCacheLostPartitionsTaskArg arg) {
+        return new VisorCacheLostPartitionsJob(arg, debug);
+    }
+
+    /**
+     * Job that collect list of lost partitions.
+     */
+    private static class VisorCacheLostPartitionsJob
+        extends VisorJob<VisorCacheLostPartitionsTaskArg, 
VisorCacheLostPartitionsTaskResult> {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /**
+         * @param arg Object with list of cache names to collect lost 
partitions.
+         * @param debug Debug flag.
+         */
+        private VisorCacheLostPartitionsJob(VisorCacheLostPartitionsTaskArg 
arg, boolean debug) {
+            super(arg, debug);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected VisorCacheLostPartitionsTaskResult 
run(VisorCacheLostPartitionsTaskArg arg) {
+            Map<String, List<Integer>> res = new HashMap<>();
+
+            for (String cacheName: arg.getCacheNames()) {
+                IgniteInternalCache cache = ignite.cachex(cacheName);
+
+                if (cache != null) {
+                    GridDhtPartitionTopology topology = 
cache.context().topology();
+                    List<Integer> lostPartitions = new 
ArrayList<>(topology.lostPartitions());
+
+                    if (!lostPartitions.isEmpty())
+                        res.put(cacheName, lostPartitions);
+                }
+            }
+
+            return new VisorCacheLostPartitionsTaskResult(res);
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(VisorCacheLostPartitionsJob.class, this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskArg.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskArg.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskArg.java
new file mode 100644
index 0000000..d6404bf
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskArg.java
@@ -0,0 +1,73 @@
+/*
+ * 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.ignite.internal.visor.cache;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.List;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorDataTransferObject;
+
+/**
+ * Argument for {@link VisorCacheLostPartitionsTask}.
+ */
+public class VisorCacheLostPartitionsTaskArg extends VisorDataTransferObject {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** List of cache names. */
+    private List<String> cacheNames;
+
+    /**
+     * Default constructor.
+     */
+    public VisorCacheLostPartitionsTaskArg() {
+        // No-op.
+    }
+
+    /**
+     * @param cacheNames List of cache names.
+     */
+    public VisorCacheLostPartitionsTaskArg(List<String> cacheNames) {
+        this.cacheNames = cacheNames;
+    }
+
+    /**
+     * @return List of cache names.
+     */
+    public List<String> getCacheNames() {
+        return cacheNames;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws 
IOException {
+        U.writeCollection(out, cacheNames);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(byte protoVer, ObjectInput in) 
throws IOException, ClassNotFoundException {
+        cacheNames = U.readList(in);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheLostPartitionsTaskArg.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskResult.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskResult.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskResult.java
new file mode 100644
index 0000000..b9a0e6b
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheLostPartitionsTaskResult.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ignite.internal.visor.cache;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.List;
+import java.util.Map;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorDataTransferObject;
+
+/**
+ * Result for {@link VisorCacheLostPartitionsTask}.
+ */
+public class VisorCacheLostPartitionsTaskResult extends 
VisorDataTransferObject {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** List of lost partitions by caches. */
+    private Map<String, List<Integer>> lostPartitions;
+
+    /**
+     * Default constructor.
+     */
+    public VisorCacheLostPartitionsTaskResult() {
+        // No-op.
+    }
+
+    /**
+     * @param lostPartitions List of lost partitions by caches.
+     */
+    public VisorCacheLostPartitionsTaskResult(Map<String, List<Integer>> 
lostPartitions) {
+        this.lostPartitions = lostPartitions;
+    }
+
+    /**
+     * @return List of lost partitions by caches.
+     */
+    public Map<String, List<Integer>> getLostPartitions() {
+        return lostPartitions;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws 
IOException {
+        U.writeMap(out, lostPartitions);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(byte protoVer, ObjectInput in) 
throws IOException, ClassNotFoundException {
+        lostPartitions = U.readMap(in);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheLostPartitionsTaskResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTask.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTask.java
new file mode 100644
index 0000000..eb48cd2
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTask.java
@@ -0,0 +1,65 @@
+/*
+ * 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.ignite.internal.visor.cache;
+
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorOneNodeTask;
+
+/**
+ * Reset lost partitions for caches.
+ */
+@GridInternal
+public class VisorCacheResetLostPartitionsTask extends 
VisorOneNodeTask<VisorCacheResetLostPartitionsTaskArg, Void> {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** {@inheritDoc} */
+    @Override protected VisorCacheResetLostPartitionsJob 
job(VisorCacheResetLostPartitionsTaskArg arg) {
+        return new VisorCacheResetLostPartitionsJob(arg, debug);
+    }
+
+    /**
+     * Job that reset lost partitions for caches.
+     */
+    private static class VisorCacheResetLostPartitionsJob extends 
VisorJob<VisorCacheResetLostPartitionsTaskArg, Void> {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /**
+         * @param arg Object with list cache names to reset lost partitons.
+         * @param debug Debug flag.
+         */
+        private 
VisorCacheResetLostPartitionsJob(VisorCacheResetLostPartitionsTaskArg arg, 
boolean debug) {
+            super(arg, debug);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected Void run(VisorCacheResetLostPartitionsTaskArg arg) 
{
+            ignite.resetLostPartitions(arg.getCacheNames());
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(VisorCacheResetLostPartitionsJob.class, this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTaskArg.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTaskArg.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTaskArg.java
new file mode 100644
index 0000000..2f365c8
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheResetLostPartitionsTaskArg.java
@@ -0,0 +1,73 @@
+/*
+ * 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.ignite.internal.visor.cache;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.List;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorDataTransferObject;
+
+/**
+ * Argument for {@link VisorCacheResetLostPartitionsTask}.
+ */
+public class VisorCacheResetLostPartitionsTaskArg extends 
VisorDataTransferObject {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** List of cache names. */
+    private List<String> cacheNames;
+
+    /**
+     * Default constructor.
+     */
+    public VisorCacheResetLostPartitionsTaskArg() {
+        // No-op.
+    }
+
+    /**
+     * @param cacheNames List of cache names.
+     */
+    public VisorCacheResetLostPartitionsTaskArg(List<String> cacheNames) {
+        this.cacheNames = cacheNames;
+    }
+
+    /**
+     * @return List of cache names.
+     */
+    public List<String> getCacheNames() {
+        return cacheNames;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws 
IOException {
+        U.writeCollection(out, cacheNames);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(byte protoVer, ObjectInput in) 
throws IOException, ClassNotFoundException {
+        cacheNames = U.readList(in);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheResetLostPartitionsTaskArg.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
----------------------------------------------------------------------
diff --git 
a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
index d55fed1..e3e2001 100755
--- 
a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
+++ 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
@@ -62,6 +62,10 @@ import scala.language.{implicitConversions, reflectiveCalls}
  * 
+-------------------------------------------------------------------------------------------+
  * | cache -rebalance | Re-balance partitions for cache with specified name.   
                |
  * 
+-------------------------------------------------------------------------------------------+
+ * | cache -slp       | Show list of lost partitions for specified cache.      
                |
+ * 
+-------------------------------------------------------------------------------------------+
+ * | cache -rlp       | Reset lost partitions for specified cache.             
                |
+ * 
+-------------------------------------------------------------------------------------------+
  *
  * }}}
  *
@@ -75,6 +79,8 @@ import scala.language.{implicitConversions, reflectiveCalls}
  *     cache -stop -c=<cache-name>
  *     cache -reset -c=<cache-name>
  *     cache -rebalance -c=<cache-name>
+ *     cache -slp -c=<cache-name>
+ *     cache -rlp -c=<cache-name>
  * }}}
  *
  * ====Arguments====
@@ -123,6 +129,10 @@ import scala.language.{implicitConversions, 
reflectiveCalls}
  *          Reset metrics for cache with specified name.
  *     -rebalance
  *          Re-balance partitions for cache with specified name.
+ *     -slp
+ *          Show list of lost partitions for specified cache.
+ *     -rlp
+ *          Reset lost partitions for specified cache.
  *     -p=<page size>
  *         Number of object to fetch from cache at once.
  *         Valid range from 1 to 100.
@@ -163,6 +173,10 @@ import scala.language.{implicitConversions, 
reflectiveCalls}
  *         Reset metrics for cache with name 'cache'.
  *     cache -rebalance -c=cache
  *         Re-balance partitions for cache with name 'cache'.
+ *     cache -slp -c=cache
+ *         Show list of lost partitions for cache with name 'cache'.
+ *     cache -rlp -c=cache
+ *         Reset lost partitions for cache with name 'cache'.
  *
  * }}}
  */
@@ -265,7 +279,7 @@ class VisorCacheCommand extends VisorConsoleCommand {
             // Get cache stats data from all nodes.
             val aggrData = cacheData(node, cacheName, showSystem)
 
-            if (hasArgFlagIn("clear", "scan", "stop", "reset", "rebalance")) {
+            if (hasArgFlagIn("clear", "scan", "stop", "reset", "rebalance", 
"slp", "rlp")) {
                 if (cacheName.isEmpty)
                     askForCache("Select cache from:", node, showSystem
                         && !hasArgFlagIn("clear", "stop", "reset", 
"rebalance"), aggrData) match {
@@ -291,6 +305,10 @@ class VisorCacheCommand extends VisorConsoleCommand {
                                     VisorCacheResetCommand().reset(argLst, 
node)
                                 else if (hasArgFlag("rebalance", argLst))
                                     
VisorCacheRebalanceCommand().rebalance(argLst, node)
+                                else if (hasArgFlag("slp", argLst))
+                                    
VisorCacheLostPartitionsCommand().showLostPartitions(argLst, node)
+                                else if (hasArgFlag("rlp", argLst))
+                                    
VisorCacheResetLostPartitionsCommand().resetLostPartitions(argLst, node)
                             }
                             else {
                                 if (hasArgFlag("scan", argLst))
@@ -716,7 +734,9 @@ object VisorCacheCommand {
             " ",
             "Clears cache.",
             " ",
-            "Prints list of all entries from cache."
+            "Prints list of all entries from cache.",
+            " ",
+            "Prints or clear list lost partitions from cache."
         ),
         spec = Seq(
             "cache",
@@ -726,7 +746,9 @@ object VisorCacheCommand {
             "cache -scan -c=<cache-name> {-near} 
{-id=<node-id>|id8=<node-id8>} {-p=<page size>}",
             "cache -stop -c=<cache-name>",
             "cache -reset -c=<cache-name>",
-            "cache -rebalance -c=<cache-name>"
+            "cache -rebalance -c=<cache-name>",
+            "cache -slp -c=<cache-name>",
+            "cache -rlp -c=<cache-name>"
   ),
         args = Seq(
             "-id8=<node-id>" -> Seq(
@@ -752,6 +774,8 @@ object VisorCacheCommand {
             "-near" -> "Prints list of all entries from near cache of cache.",
             "-stop" -> "Stop cache with specified name.",
             "-reset" -> "Reset metrics of cache with specified name.",
+            "-slp" -> "Show list of lost partitions for specified cache.",
+            "-rlp" -> "Reset lost partitions for specified cache.",
             "-rebalance" -> "Re-balance partitions for cache with specified 
name.",
             "-s=hi|mi|rd|wr|cn" -> Seq(
                 "Defines sorting type. Sorted by:",
@@ -812,7 +836,9 @@ object VisorCacheCommand {
                 "Prints list entries from near cache of cache with name 
'cache' and node '12345678' ID8.",
             "cache -stop -c=@c0" -> "Stop cache with name taken from 'c0' 
memory variable.",
             "cache -reset -c=@c0" -> "Reset metrics for cache with name taken 
from 'c0' memory variable.",
-            "cache -rebalance -c=cache" -> "Re-balance partitions for cache 
with name 'cache'."
+            "cache -rebalance -c=cache" -> "Re-balance partitions for cache 
with name 'cache'.",
+            "cache -slp -c=@c0" -> "Show list of lost partitions for cache 
with name taken from 'c0' memory variable.",
+            "cache -rlp -c=@c0" -> "Reset lost partitions for cache with name 
taken from 'c0' memory variable."
         ),
         emptyArgs = cmd.cache,
         withArgs = cmd.cache

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheLostPartitionsCommand.scala
----------------------------------------------------------------------
diff --git 
a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheLostPartitionsCommand.scala
 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheLostPartitionsCommand.scala
new file mode 100644
index 0000000..d683031
--- /dev/null
+++ 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheLostPartitionsCommand.scala
@@ -0,0 +1,170 @@
+/*
+ * 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.ignite.visor.commands.cache
+
+import java.util.Collections
+
+import org.apache.ignite.cluster.{ClusterGroupEmptyException, ClusterNode}
+import org.apache.ignite.internal.visor.cache.{VisorCacheLostPartitionsTask, 
VisorCacheLostPartitionsTaskArg}
+import org.apache.ignite.visor.commands.common.VisorTextTable
+import org.apache.ignite.visor.visor._
+import org.apache.ignite.internal.visor.util.VisorTaskUtils._
+
+import scala.collection.JavaConversions._
+import scala.collection.mutable
+
+/**
+ * ==Overview==
+ * Visor 'lost partitions' command implementation.
+ *
+ * ====Specification====
+ * {{{
+ *     cache -slp -c=<cache name>
+ * }}}
+ *
+ * ====Arguments====
+ * {{{
+ *     <cache-name>
+ *         Name of the cache.
+ * }}}
+ *
+ * ====Examples====
+ * {{{
+ *    cache -slp -c=cache
+ *        Show list of lost partitions for cache with name 'cache'.
+ * }}}
+ */
+class VisorCacheLostPartitionsCommand {
+    /**
+     * Prints error message and advise.
+     *
+     * @param errMsgs Error messages.
+     */
+    private def scold(errMsgs: Any*) {
+        assert(errMsgs != null)
+
+        warn(errMsgs: _*)
+        warn("Type 'help cache' to see how to use this command.")
+    }
+
+    private def error(e: Throwable) {
+        var cause: Throwable = e
+
+        while (cause.getCause != null)
+            cause = cause.getCause
+
+        scold(cause.getMessage)
+    }
+
+    /**
+     * ===Command===
+     * Show list of lost partitions in cache with specified name.
+     *
+     * ===Examples===
+     * <ex>cache -slp -c=cache</ex>
+     *     Show list of lost partitions from cache with name 'cache'.
+     *
+     * @param argLst Command arguments.
+     */
+    def showLostPartitions(argLst: ArgList, node: Option[ClusterNode]) {
+        val cacheArg = argValue("c", argLst)
+        val cacheName = cacheArg match {
+            case None => null // default cache.
+
+            case Some(s) if s.startsWith("@") =>
+                warn("Can't find cache variable with specified name: " + s,
+                    "Type 'cache' to see available cache variables."
+                )
+
+                return
+
+            case Some(name) => name
+        }
+
+        val lostPartitions =
+            try
+                executeRandom(groupForDataNode(node, cacheName), 
classOf[VisorCacheLostPartitionsTask],
+                    new 
VisorCacheLostPartitionsTaskArg(Collections.singletonList(cacheName)))
+            catch {
+                case _: ClusterGroupEmptyException =>
+                    scold(messageNodeNotFound(node, cacheName))
+
+                    return
+                case e: Throwable =>
+                    error(e)
+
+                    return
+            }
+
+        if (lostPartitions.getLostPartitions.isEmpty) {
+            println(s"""Lost partitions for cache: "${escapeName(cacheName)}" 
is not found""")
+
+            return
+        }
+
+        lostPartitions.getLostPartitions.foreach(cacheLostPartitions => {
+            val t = VisorTextTable()
+
+            t #= ("Interval", "Partitions")
+
+            val partitions = cacheLostPartitions._2.toIndexedSeq
+            val partitionCnt = partitions.size
+
+            val indexes = mutable.ArrayBuffer.empty[String]
+            val partitionRows = mutable.ArrayBuffer.empty[String]
+            var startIdx = 0
+            var idx = 0
+            val b = new StringBuilder
+
+            partitions.foreach((part) => {
+                if (idx % 10 == 0)
+                    startIdx = part
+
+                b.append(part)
+                idx += 1
+
+                if (idx != partitionCnt)
+                    b.append(", ")
+
+
+                if (idx % 10 == 0 || idx == partitionCnt) {
+                    indexes += startIdx + "-" + part
+                    partitionRows += b.toString().trim
+                    b.clear()
+                }
+            })
+
+            t += (indexes, partitionRows)
+            println(s"Lost partitions for cache: 
${escapeName(cacheLostPartitions._1)} ($partitionCnt)")
+            t.render()
+        })
+    }
+}
+
+/**
+ * Companion object that does initialization of the command.
+ */
+object VisorCacheLostPartitionsCommand {
+    /** Singleton command. */
+    private val cmd = new VisorCacheLostPartitionsCommand
+
+    /**
+     * Singleton.
+     */
+    def apply(): VisorCacheLostPartitionsCommand = cmd
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4aa56751/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheResetLostPartitionsCommand.scala
----------------------------------------------------------------------
diff --git 
a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheResetLostPartitionsCommand.scala
 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheResetLostPartitionsCommand.scala
new file mode 100644
index 0000000..a72a80f
--- /dev/null
+++ 
b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheResetLostPartitionsCommand.scala
@@ -0,0 +1,132 @@
+/*
+ * 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.ignite.visor.commands.cache
+
+import java.util.Collections
+
+import org.apache.ignite.cluster.{ClusterGroupEmptyException, ClusterNode}
+import 
org.apache.ignite.internal.visor.cache.{VisorCacheResetLostPartitionsTask, 
VisorCacheResetLostPartitionsTaskArg}
+import org.apache.ignite.internal.visor.util.VisorTaskUtils._
+import org.apache.ignite.visor.visor._
+
+import scala.language.reflectiveCalls
+
+/**
+ * ==Overview==
+ * Visor 'lost partition reset' command implementation.
+ *
+ * ====Specification====
+ * {{{
+ *     cache -rlp -c=<cache name>
+ * }}}
+ *
+ * ====Arguments====
+ * {{{
+ *     <cache-name>
+ *         Name of the cache.
+ * }}}
+ *
+ * ====Examples====
+ * {{{
+ *    cache -rlp -c=@c0
+ *        Reset lost partition for cache with name taken from 'c0' memory 
variable.
+ * }}}
+ */
+class VisorCacheResetLostPartitionsCommand {
+    /**
+     * Prints error message and advise.
+     *
+     * @param errMsgs Error messages.
+     */
+    private def scold(errMsgs: Any*) {
+        assert(errMsgs != null)
+
+        warn(errMsgs: _*)
+        warn("Type 'help cache' to see how to use this command.")
+    }
+
+    private def error(e: Exception) {
+        var cause: Throwable = e
+
+        while (cause.getCause != null)
+            cause = cause.getCause
+
+        scold(cause.getMessage)
+    }
+
+    /**
+     * ===Command===
+     * Reset lost partitions for cache with specified name.
+     *
+     * ===Examples===
+     * <ex>cache -c=cache -rlp</ex>
+     * Reset lost partitions for cache with name 'cache'.
+     *
+     * @param argLst Command arguments.
+     */
+    def resetLostPartitions(argLst: ArgList, node: Option[ClusterNode]) {
+        val cacheArg = argValue("c", argLst)
+
+        val cacheName = cacheArg match {
+            case None => null // default cache.
+
+            case Some(s) if s.startsWith("@") =>
+                warn("Can't find cache variable with specified name: " + s,
+                    "Type 'cache' to see available cache variables."
+                )
+
+                return
+
+            case Some(name) => name
+        }
+
+        val grp = try {
+            groupForDataNode(node, cacheName)
+        }
+        catch {
+            case _: ClusterGroupEmptyException =>
+                scold(messageNodeNotFound(node, cacheName))
+
+                return
+        }
+
+        try {
+            executeRandom(grp, classOf[VisorCacheResetLostPartitionsTask],
+                new 
VisorCacheResetLostPartitionsTaskArg(Collections.singletonList(cacheName)))
+
+            println("Visor successfully reset lost partitions for cache: " + 
escapeName(cacheName))
+        }
+        catch {
+            case _: ClusterGroupEmptyException => 
scold(messageNodeNotFound(node, cacheName))
+            case e: Exception => error(e)
+        }
+    }
+}
+
+/**
+ * Companion object that does initialization of the command.
+ */
+object VisorCacheResetLostPartitionsCommand {
+    /** Singleton command. */
+    private val cmd = new VisorCacheResetLostPartitionsCommand
+
+    /**
+      * Singleton.
+      */
+    def apply() = cmd
+}

Reply via email to