This is an automated email from the ASF dual-hosted git repository. bschuchardt pushed a commit to branch support/1.13 in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/support/1.13 by this push: new acae4bb GEODE-8697: Propagate ForcedDisconnectException to the user application (#5739) acae4bb is described below commit acae4bb3fa8e4a20f0bad8eb63259eb1b6d79fa3 Author: Bruce Schuchardt <bschucha...@pivotal.io> AuthorDate: Mon Nov 16 07:51:14 2020 -0800 GEODE-8697: Propagate ForcedDisconnectException to the user application (#5739) * GEODE-8697: Propagate ForcedDisconnectException to the user application avoid setting MemberDisconnectedException as a rootCause in ClusterDistributionManager, even temporarily, as it's an internal exception that should not be exposed to applications. * addressing Ernie's comments (cherry picked from commit 403e19c0a2b85369274e8254c16e0ae508b82e94) --- .../internal/ClusterDistributionManager.java | 50 ++++++++++++---------- .../internal/ClusterDistributionManagerTest.java | 40 +++++++++++++++++ 2 files changed, 67 insertions(+), 23 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java index d17ae80..4196965 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java @@ -2206,6 +2206,11 @@ public class ClusterDistributionManager implements DistributionManager { } } + private List<MembershipTestHook> getMembershipTestHooks() { + return membershipTestHooks; + } + + @Override public Set<InternalDistributedMember> getAdminMemberSet() { return distribution.getView().getMembers().stream() @@ -2280,7 +2285,7 @@ public class ClusterDistributionManager implements DistributionManager { * This is the listener implementation for responding from events from the Membership Manager. * */ - private class DMListener implements + static class DMListener implements org.apache.geode.distributed.internal.membership.api.MembershipListener<InternalDistributedMember> { ClusterDistributionManager dm; @@ -2290,26 +2295,25 @@ public class ClusterDistributionManager implements DistributionManager { @Override public void membershipFailure(String reason, Throwable t) { - exceptionInThreads = true; - rootCause = t; - if (rootCause != null && !(rootCause instanceof ForcedDisconnectException)) { - logger.info("cluster membership failed due to ", rootCause); - rootCause = new ForcedDisconnectException(rootCause.getMessage()); + dm.exceptionInThreads = true; + Throwable cause = t; + if (cause != null && !(cause instanceof ForcedDisconnectException)) { + logger.info("cluster membership failed due to ", cause); + cause = new ForcedDisconnectException(cause.getMessage()); } + dm.setRootCause(cause); try { - if (membershipTestHooks != null) { - List<MembershipTestHook> l = membershipTestHooks; - for (final MembershipTestHook aL : l) { - MembershipTestHook dml = aL; - dml.beforeMembershipFailure(reason, rootCause); + List<MembershipTestHook> testHooks = dm.getMembershipTestHooks(); + if (testHooks != null) { + for (final MembershipTestHook testHook : testHooks) { + testHook.beforeMembershipFailure(reason, cause); } } - getSystem().disconnect(reason, true); - if (membershipTestHooks != null) { - List<MembershipTestHook> l = membershipTestHooks; - for (final MembershipTestHook aL : l) { - MembershipTestHook dml = aL; - dml.afterMembershipFailure(reason, rootCause); + dm.getSystem().disconnect(reason, true); + testHooks = dm.getMembershipTestHooks(); + if (testHooks != null) { + for (final MembershipTestHook testHook : testHooks) { + testHook.afterMembershipFailure(reason, cause); } } } catch (RuntimeException re) { @@ -2341,7 +2345,7 @@ public class ClusterDistributionManager implements DistributionManager { @Override public void memberDeparted(InternalDistributedMember theId, boolean crashed, String reason) { try { - boolean wasAdmin = getAdminMemberSet().contains(theId); + boolean wasAdmin = dm.getAdminMemberSet().contains(theId); if (wasAdmin) { // Pretend we received an AdminConsoleDisconnectMessage from the console that // is no longer in the JavaGroup view. @@ -2354,9 +2358,9 @@ public class ClusterDistributionManager implements DistributionManager { message.setIgnoreAlertListenerRemovalFailure(true); // we don't know if it was a listener // so // don't issue a warning - message.setRecipient(localAddress); - message.setReason(reason); // added for #37950 - handleIncomingDMsg(message); + message.setRecipient(dm.getDistributionManagerId()); + message.setReason(reason); + dm.handleIncomingDMsg(message); } dm.handleManagerDeparture(theId, crashed, reason); } catch (DistributedSystemDisconnectedException se) { @@ -2390,8 +2394,8 @@ public class ClusterDistributionManager implements DistributionManager { @Override public void saveConfig() { - if (!getConfig().getDisableAutoReconnect()) { - cache.saveCacheXmlForReconnect(); + if (!dm.getConfig().getDisableAutoReconnect()) { + dm.getCache().saveCacheXmlForReconnect(); } } } diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/ClusterDistributionManagerTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/ClusterDistributionManagerTest.java new file mode 100644 index 0000000..913183a --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/ClusterDistributionManagerTest.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.geode.distributed.internal; + +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import org.apache.geode.ForcedDisconnectException; +import org.apache.geode.distributed.internal.membership.api.MemberDisconnectedException; + +public class ClusterDistributionManagerTest { + + @Test + public void membershipFailureProcessingCreatesForcedDisconnectException() { + ClusterDistributionManager manager = mock(ClusterDistributionManager.class); + ClusterDistributionManager.DMListener listener = + new ClusterDistributionManager.DMListener(manager); + listener.membershipFailure("Testing", new MemberDisconnectedException("testing")); + // the root cause of membership failure should only be set once + verify(manager, times(1)).setRootCause(isA(Throwable.class)); + // the root cause should be a ForcedDisconnectException + verify(manager, times(1)).setRootCause(isA(ForcedDisconnectException.class)); + } +}