Repository: ignite Updated Branches: refs/heads/master 5d8f5709e -> abfa0f50b
IGNITE-7940 Visor CMD: Added "cache -slp" and "cache -rlp" commands to show and reset lost partitions for specified cache. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/abfa0f50 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/abfa0f50 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/abfa0f50 Branch: refs/heads/master Commit: abfa0f50b36e2b91f8c3c70ea0ac7e0417a12e5e Parents: 5d8f570 Author: Vasiliy Sisko <[email protected]> Authored: Mon Apr 9 22:13:21 2018 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Mon Apr 9 22:13:21 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/abfa0f50/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/abfa0f50/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/abfa0f50/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/abfa0f50/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/abfa0f50/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/abfa0f50/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/abfa0f50/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/abfa0f50/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 +}
