Java tutorial
/* * Copyright 2005-2014 WSO2, Inc. (http://wso2.com) * * 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.wso2.carbon.appfactory.ext.appserver; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.messaging.domain.topology.Cluster; import org.apache.stratos.messaging.domain.topology.Member; import org.apache.stratos.messaging.domain.topology.MemberStatus; import org.apache.stratos.messaging.domain.topology.Service; import org.apache.stratos.messaging.event.Event; import org.apache.stratos.messaging.event.topology.CompleteTopologyEvent; import org.apache.stratos.messaging.listener.topology.CompleteTopologyEventListener; import org.apache.stratos.messaging.message.receiver.topology.TopologyEventReceiver; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; /* * This class is use to listen to complete stratos topology * It decides whether the current node should be a notifier based on the node ip in the topology * */ public class LeaderElector { private static final Log log = LogFactory.getLog(LeaderElector.class); private static LeaderElector leaderElector = new LeaderElector(); private static boolean isNotifyEligible; private boolean terminated; private TopologyEventReceiver topologyEventReceiver; private LeaderElector() { isNotifyEligible = false; this.terminated = false; this.topologyEventReceiver = new TopologyEventReceiver(); addEvenListener(); Thread thread = new Thread(topologyEventReceiver); thread.start(); log.info("Stratos Manager topology receiver thread started"); } public static boolean isIsNotifyEligible() { return isNotifyEligible; } public static LeaderElector getInstance() { return leaderElector; } private void addEvenListener() { //add listener to Complete Topology Event topologyEventReceiver.addEventListener(new CompleteTopologyEventListener() { @Override protected void onEvent(Event event) { if (log.isDebugEnabled()) { log.debug("[CompleteTopologyEventListener] Received: " + event.getClass()); } try { String currentNodeIp = InetAddress.getLocalHost().getHostAddress(); Map<String, InetAddress> memberIpMap = new HashMap<String, InetAddress>(); for (Service service : ((CompleteTopologyEvent) event).getTopology().getServices()) { for (Cluster cluster : service.getClusters()) { for (Member member : cluster.getMembers()) { MemberStatus memStatus = member.getStatus(); if (MemberStatus.Activated.equals(memStatus)) { memberIpMap.put(member.getMemberIp(), InetAddress.getByName(member.getMemberIp())); } } } /*if the current node ip is not there in the service cluster; it should be a different service cluster*/ if (memberIpMap.get(currentNodeIp) != null) { break; } else { memberIpMap.clear(); } } if (memberIpMap.isEmpty()) { return; } List<InetAddress> memberIpList = new ArrayList<InetAddress>(memberIpMap.values()); Collections.sort(memberIpList, new Comparator<InetAddress>() { @Override public int compare(InetAddress addr1, InetAddress addr2) { byte[] ba1 = addr1.getAddress(); byte[] ba2 = addr2.getAddress(); // general ordering: ipv4 before ipv6 if (ba1.length < ba2.length) { return -1; } if (ba1.length > ba2.length) { return 1; } // we have 2 ips of the same type, so we have to compare each byte for (int i = 0; i < ba1.length; i++) { int b1 = unsignedByteToInt(ba1[i]); int b2 = unsignedByteToInt(ba2[i]); if (b1 == b2) { continue; } if (b1 < b2) { return -1; } else { return 1; } } return 0; } private int unsignedByteToInt(byte b) { return (int) b & 0xFF; } }); if ((memberIpMap.get(currentNodeIp) != null) && currentNodeIp.equals(memberIpList.get(0).getHostAddress())) { isNotifyEligible = true; } else { isNotifyEligible = false; } } catch (UnknownHostException e) { log.error("Unable to identify the host ip " + e.getMessage(), e); } } }); } //terminate Topology Receiver public void terminate() { topologyEventReceiver.terminate(); log.info("Stratos Manager topology receiver thread terminated"); } }