/* * 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.membership.gms; import org.apache.geode.CancelException; import org.apache.geode.ForcedDisconnectException; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.distributed.internal.membership.MembershipManager; import org.apache.geode.distributed.internal.membership.gms.interfaces.Manager; import org.apache.geode.distributed.internal.membership.gms.mgr.GMSMembershipManager; import org.apache.geode.test.dunit.Wait; import org.apache.geode.test.dunit.WaitCriterion; /** * This helper class provides access to membership manager information that is not otherwise public * * @since GemFire 5.5 */ public class MembershipManagerHelper { /** returns the JGroupMembershipManager for the given distributed system */ public static MembershipManager getMembershipManager(DistributedSystem sys) { InternalDistributedSystem isys = (InternalDistributedSystem) sys; DistributionManager dm = (DistributionManager) isys.getDM(); MembershipManager mgr = dm.getMembershipManager(); return mgr; } /** * act sick. don't accept new connections and don't process ordered messages. Use * beHealthyMember() to reverse the effects. * <p> * Note that part of beSickMember's processing is to interrupt and stop any reader threads. A slow * listener in a reader thread should eat this interrupt. * * @param sys */ public static void beSickMember(DistributedSystem sys) { ((Manager) getMembershipManager(sys)).beSick(); } /** * inhibit failure detection responses. This can be used in conjunction with beSickMember */ public static void playDead(DistributedSystem sys) { try { ((Manager) getMembershipManager(sys)).playDead(); } catch (CancelException e) { // really dead is as good as playing dead } } public static void beHealthyMember(DistributedSystem sys) { ((Manager) getMembershipManager(sys)).beHealthy(); } /** returns the current coordinator address */ public static DistributedMember getCoordinator(DistributedSystem sys) { return ((Manager) getMembershipManager(sys)).getCoordinator(); } /** returns the current lead member address */ public static DistributedMember getLeadMember(DistributedSystem sys) { return ((Manager) getMembershipManager(sys)).getLeadMember(); } /** register a test hook with the manager */ public static void addTestHook(DistributedSystem sys, org.apache.geode.distributed.internal.membership.MembershipTestHook hook) { getMembershipManager(sys).registerTestHook(hook); } /** remove a registered test hook */ public static void removeTestHook(DistributedSystem sys, org.apache.geode.distributed.internal.membership.MembershipTestHook hook) { getMembershipManager(sys).unregisterTestHook(hook); } // /** // * returns the view lock. Holding this lock will prevent the processing // * of new views, and will prevent other threads from being able to access // * the view // */ // public static Object getViewLock(DistributedSystem sys) { // return getMembershipManager(sys).latestViewLock; // } /** returns true if the given member is shunned */ public static boolean isShunned(DistributedSystem sys, DistributedMember mbr) { return ((Manager) getMembershipManager(sys)).isShunned(mbr); } /** returns true if the given member is a surprise member */ public static boolean isSurpriseMember(DistributedSystem sys, DistributedMember mbr) { return getMembershipManager(sys).isSurpriseMember(mbr); } /** * add a member id to the surprise members set, with the given millisecond clock birth time */ public static void addSurpriseMember(DistributedSystem sys, DistributedMember mbr, long birthTime) { ((Manager) getMembershipManager(sys)).addSurpriseMemberForTesting(mbr, birthTime); } /** * inhibits/enables logging of forced-disconnect messages. For quorum-lost messages this adds * expected-exception annotations before and after the messages to make them invisible to greplogs */ public static void inhibitForcedDisconnectLogging(boolean b) { GMSMembershipManager.inhibitForcedDisconnectLogging(b); } /** * wait for a member to leave the view. Throws an assertionerror if the timeout period elapses * before the member leaves */ public static void waitForMemberDeparture(final DistributedSystem sys, final DistributedMember member, final long timeout) { WaitCriterion ev = new WaitCriterion() { public boolean done() { return !getMembershipManager(sys).getView().contains((InternalDistributedMember) member); } public String description() { String assMsg = "Waited over " + timeout + " ms for " + member + " to depart, but it didn't"; return assMsg; } }; Wait.waitForCriterion(ev, timeout, 200, true); } public static void crashDistributedSystem(final DistributedSystem msys) { msys.getLogWriter().info("crashing distributed system: " + msys); MembershipManagerHelper.inhibitForcedDisconnectLogging(true); MembershipManagerHelper.beSickMember(msys); MembershipManagerHelper.playDead(msys); GMSMembershipManager mgr = ((GMSMembershipManager) getMembershipManager(msys)); mgr.forceDisconnect("for testing"); while (msys.isConnected()) { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } MembershipManagerHelper.inhibitForcedDisconnectLogging(false); } }