/* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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.axis2.clustering.tribes; import org.apache.axis2.clustering.control.wka.MemberJoinedCommand; import org.apache.axis2.clustering.management.DefaultGroupManagementAgent; import org.apache.axis2.clustering.management.GroupManagementAgent; import org.apache.catalina.tribes.Channel; import org.apache.catalina.tribes.ChannelException; import org.apache.catalina.tribes.Member; import org.apache.catalina.tribes.MembershipListener; import org.apache.catalina.tribes.RemoteProcessException; import org.apache.catalina.tribes.group.RpcChannel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Represents a member running in load balance mode */ public class ClusterManagementMode implements OperationMode { private static final Log log = LogFactory.getLog(ClusterManagementMode.class); private final byte[] clusterManagerDomain; /** * Map[key, value=Map[key, value]] = [domain, [subDomain, GroupManagementAgent]] */ private final Map<String, Map<String, GroupManagementAgent>> groupManagementAgents; private final List<MembershipManager> membershipManagers = new ArrayList<MembershipManager>(); private final MembershipManager primaryMembershipManager; public ClusterManagementMode(byte[] clusterManagerDomain, Map<String, Map<String, GroupManagementAgent>> groupManagementAgents, MembershipManager primaryMembershipManager) { this.clusterManagerDomain = clusterManagerDomain; this.groupManagementAgents = groupManagementAgents; this.primaryMembershipManager = primaryMembershipManager; } public void addInterceptors(Channel channel) { ClusterManagementInterceptor interceptor = new ClusterManagementInterceptor(clusterManagerDomain); interceptor.setOptionFlag(TribesConstants.MEMBERSHIP_MSG_OPTION); channel.addInterceptor(interceptor); if (log.isDebugEnabled()) { log.debug("Added ClusterManagementInterceptor"); } } public void init(Channel channel) { // Have multiple RPC channels with multiple RPC request handlers for each domain // This is needed only when this member is running as a load balancer for (String domain : groupManagementAgents.keySet()) { Map<String, GroupManagementAgent> groupMgtAgents = groupManagementAgents.get(domain); for (GroupManagementAgent groupMgtAgent : groupMgtAgents.values()) { final MembershipManager membershipManager = new MembershipManager(); membershipManager.setDomain(domain.getBytes()); membershipManager.setGroupManagementAgent(groupMgtAgent); if(groupMgtAgent instanceof DefaultGroupManagementAgent) { ((DefaultGroupManagementAgent) groupMgtAgent).setMembershipManager(membershipManager); } MembershipListener membershipListener = new MembershipListener() { public void memberAdded(org.apache.catalina.tribes.Member member) { membershipManager.memberAdded(member); } public void memberDisappeared(org.apache.catalina.tribes.Member member) { membershipManager.memberDisappeared(member); } }; channel.addMembershipListener(membershipListener); membershipManagers.add(membershipManager); } } } public List<MembershipManager> getMembershipManagers() { return membershipManagers; } public void notifyMemberJoin(final Member member) { if (TribesUtil.isInDomain(member, clusterManagerDomain)) { // A peer load balancer has joined // Notify all members in the LB group primaryMembershipManager.sendMemberJoinedToAll(member); // Send the MEMBER_LISTS of all the groups to the the new LB member for (MembershipManager manager : membershipManagers) { manager.sendMemberList(member); } } else { // An application member has joined. // Need to notify all members in the group of the new app member Thread th = new Thread() { public void run() { for (MembershipManager manager : membershipManagers) { if (TribesUtil.isInDomain(member, manager.getDomain())) { // Send MEMBER_JOINED to the group of the new member manager.sendMemberJoinedToAll(member); // Send MEMBER_JOINED to the load balancer group sendMemberJoinedToLoadBalancerGroup(manager.getRpcMembershipChannel(), member); break; } } } /** * Send MEMBER_JOINED to the load balancer group * @param rpcChannel The RpcChannel corresponding to the member's group * @param member The member who joined */ private void sendMemberJoinedToLoadBalancerGroup(RpcChannel rpcChannel, Member member) { MemberJoinedCommand cmd = new MemberJoinedCommand(); cmd.setMember(member); try { rpcChannel.send(primaryMembershipManager.getMembers(), cmd, RpcChannel.ALL_REPLY, Channel.SEND_OPTIONS_ASYNCHRONOUS, 10000); } catch (ChannelException e) { String errMsg = "Could not send MEMBER_JOINED[" + TribesUtil.getName(member) + "] to all load balancer members "; log.error(errMsg, e); throw new RemoteProcessException(errMsg, e); } } }; th.start(); } } }