You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by na...@apache.org on 2022/03/31 13:42:12 UTC

[ignite] 01/02: IGNITE-16416 : Fix unreadable result on cluster deactivation via IgniteMXBean (#9775)

This is an automated email from the ASF dual-hosted git repository.

namelchev pushed a commit to branch ignite-2.13
in repository https://gitbox.apache.org/repos/asf/ignite.git

commit aead528889dc26465d27e9873fdbc0e8b3727165
Author: Vladimir Steshin <vl...@gmail.com>
AuthorDate: Wed Mar 30 14:34:19 2022 +0300

    IGNITE-16416 : Fix unreadable result on cluster deactivation via IgniteMXBean (#9775)
    
    (cherry picked from commit 5c90a9f156445003799c42166063f096b07c2601)
---
 .../apache/ignite/internal/IgniteMXBeanImpl.java   | 12 +++----
 .../apache/ignite/internal/util/IgniteUtils.java   |  9 ++---
 .../org/apache/ignite/mxbean/IgniteMXBean.java     | 16 ++++-----
 .../cache/IgniteClusterActivateDeactivateTest.java | 39 +++++++++++++++++-----
 4 files changed, 47 insertions(+), 29 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteMXBeanImpl.java
index 55ab1ab8..924fe23 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteMXBeanImpl.java
@@ -57,7 +57,7 @@ public class IgniteMXBeanImpl implements IgniteMXBean {
     }
 
     /** {@inheritDoc} */
-    @Override public void active(boolean active) {
+    @Override public void active(boolean active) throws JMException {
         clusterState(active ? ACTIVE.toString() : INACTIVE.toString(), false);
     }
 
@@ -273,7 +273,7 @@ public class IgniteMXBeanImpl implements IgniteMXBean {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean pingNodeByAddress(String host) {
+    @Override public boolean pingNodeByAddress(String host) throws JMException {
         ctx.gateway().readLock();
 
         try {
@@ -284,7 +284,7 @@ public class IgniteMXBeanImpl implements IgniteMXBean {
             return false;
         }
         catch (IgniteCheckedException e) {
-            throw U.convertException(e);
+            throw U.jmException(U.convertException(e));
         }
         finally {
             ctx.gateway().readUnlock();
@@ -316,12 +316,12 @@ public class IgniteMXBeanImpl implements IgniteMXBean {
     }
 
     /** {@inheritDoc} */
-    @Override public void clusterState(String state) {
+    @Override public void clusterState(String state) throws JMException {
         clusterState(state, false);
     }
 
     /** {@inheritDoc} */
-    @Override public void clusterState(String state, boolean forceDeactivation) {
+    @Override public void clusterState(String state, boolean forceDeactivation) throws JMException {
         ClusterState newState = ClusterState.valueOf(state);
 
         ctx.gateway().readLock();
@@ -331,7 +331,7 @@ public class IgniteMXBeanImpl implements IgniteMXBean {
                 .forServers().nodes(), false).get();
         }
         catch (IgniteCheckedException e) {
-            throw U.convertException(e);
+            throw U.jmException(e);
         }
         finally {
             ctx.gateway().readUnlock();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index e325fa9..6588b91 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -7789,17 +7789,14 @@ public abstract class IgniteUtils {
     }
 
     /**
-     * Utility method creating {@link JMException} with given cause.
+     * Utility method creating {@link JMException} with given cause. Keeps only the error message to avoid
+     * deserialization failure on remote side due to the other class path.
      *
      * @param e Cause exception.
      * @return Newly created {@link JMException}.
      */
     public static JMException jmException(Throwable e) {
-        JMException x = new JMException();
-
-        x.initCause(e);
-
-        return x;
+        return new JMException(e.getMessage());
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
index e1c3e2b..06fe8ee 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
@@ -21,7 +21,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import javax.management.JMException;
-import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cluster.ClusterState;
 import org.apache.ignite.spi.metric.ReadOnlyMetricRegistry;
 
@@ -388,7 +387,7 @@ public interface IgniteMXBean {
      *
      * @param active Activate/DeActivate flag.
      * @deprecated Use {@link #clusterState(String, boolean)} instead.
-     * @throws IgniteCheckedException if deactivation stopped.
+     * @throws JMException if deactivation is forbidden or stopped.
      */
     @Deprecated
     @MXBeanDescription(
@@ -397,7 +396,7 @@ public interface IgniteMXBean {
     @MXBeanParametersNames(
         "active"
     )
-    public void active(boolean active);
+    public void active(boolean active) throws JMException;
 
     /**
      * Checks if Ignite grid is active. If Ignite grid is not active return {@code False}.
@@ -449,12 +448,13 @@ public interface IgniteMXBean {
      *
      * @param host Host name or IP address of the node to ping.
      * @return Whether or not node is alive.
+     * @throws JMException When ping failed.
      */
     @MXBeanDescription("Pings node with given host name to see if it is alive. " +
         "Returns whether or not node is alive.")
     public boolean pingNodeByAddress(
         @MXBeanParameter(name = "host", description = "Host name or IP address of the node to ping.") String host
-    );
+    ) throws JMException;
 
     /**
      * Gets a formatted instance of configured discovery SPI implementation.
@@ -671,13 +671,13 @@ public interface IgniteMXBean {
      *
      * @param state String representation of new cluster state.
      * @deprecated Use {@link #clusterState(String, boolean)} instead.
-     * @throws IgniteCheckedException if deactivation stopped.
+     * @throws JMException if deactivation is forbidden or stopped.
      */
     @Deprecated
     @MXBeanDescription("Changes current cluster state.")
     public void clusterState(
         @MXBeanParameter(name = "state", description = "New cluster state.") String state
-    );
+    ) throws JMException;
 
     /**
      * Changes current cluster state.
@@ -687,14 +687,14 @@ public interface IgniteMXBean {
      *
      * @param state String representation of new cluster state.
      * @param forceDeactivation If {@code true}, cluster deactivation will be forced.
-     * @throws IgniteCheckedException if deactivation stopped.
+     * @throws JMException if deactivation is forbidden or stopped.
      */
     @MXBeanDescription("Changes current cluster state.")
     public void clusterState(
         @MXBeanParameter(name = "state", description = "New cluster state.") String state,
         @MXBeanParameter(name = "forceDeactivation",
             description = "If true, cluster deactivation will be forced.") boolean forceDeactivation
-    );
+    ) throws JMException;
 
     /**
      * Gets last cluster state change operation.
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
index 2ad649e..b05d3e9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClusterActivateDeactivateTest.java
@@ -25,6 +25,7 @@ import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
+import javax.management.JMException;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
@@ -1422,27 +1423,32 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
         // Create a new cache in order to trigger all needed checks on deactivation.
         ignite.getOrCreateCache("test-partitioned-cache");
 
-        checkDeactivation(ignite, () -> mxBean.active(false), false);
+        checkMXBeanDeactivation(ignite, () -> mxBean.active(false), false);
 
-        checkDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name()), false);
+        checkMXBeanDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name()), false);
 
-        checkDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name(), false), false);
+        checkMXBeanDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name(), false), false);
 
-        checkDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name(), true), true);
+        checkMXBeanDeactivation(ignite, () -> mxBean.clusterState(INACTIVE.name(), true), true);
     }
 
     /**
      * Checks that not forced deactivation fails only if cluster has in-memory caches.
      *
      * @param ignite Ignite instance.
-     * @param deactivator Deactivation call to check.
+     * @param deactivator Deactivation call to check. Assuming from the mx bean.
      * @param forceDeactivation {@code True} if {@code deactivator} is forced.
      */
-    private void checkDeactivation(Ignite ignite, Runnable deactivator, boolean forceDeactivation) {
+    private void checkMXBeanDeactivation(Ignite ignite, MXAction deactivator, boolean forceDeactivation) {
         assertEquals(ACTIVE, ignite.cluster().state());
 
         if (persistenceEnabled() || forceDeactivation) {
-            deactivator.run();
+            try {
+                deactivator.action();
+            }
+            catch (JMException e) {
+                throw new IllegalStateException("Unexpected exception on cluster deactivation.", e);
+            }
 
             assertEquals(INACTIVE, ignite.cluster().state());
 
@@ -1450,10 +1456,19 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
         }
         else {
             assertThrows(log, () -> {
-                deactivator.run();
+                deactivator.action();
 
                 return null;
-            }, IgniteException.class, DATA_LOST_ON_DEACTIVATION_WARNING);
+            }, JMException.class, DATA_LOST_ON_DEACTIVATION_WARNING);
+
+            try {
+                deactivator.action();
+            }
+            catch (JMException e) {
+                assertNull("A JMX exception should not contain any cause. JMX client might be launched with " +
+                        "other class path witout remote class loading and won't be able to deserialize teh stacktrace.",
+                    e.getCause());
+            }
         }
 
         assertEquals(ACTIVE, ignite.cluster().state());
@@ -1817,4 +1832,10 @@ public class IgniteClusterActivateDeactivateTest extends GridCommonAbstractTest
             }
         }, "start" + "-" + (client ? "client" : "server") + "-node" + nodeNumber);
     }
+
+    /** An JMX bean call that can throw JMException. */
+    private interface MXAction {
+        /** */
+        void action() throws JMException;
+    }
 }