/* * TeleStax, Open Source Cloud Communications * Copyright 2011-2015, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.mobicents.tools.smpp.multiplexer; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.Logger; import org.mobicents.tools.heartbeat.api.Node; import org.mobicents.tools.sip.balancer.KeySmpp; import com.cloudhopper.smpp.pdu.Pdu; /** * @author Konstantin Nosach (kostyantyn.nosach@telestax.com) */ public class SmppToProviderRoundRobinAlgorithm extends DefaultSmppAlgorithm { private static final Logger logger = Logger.getLogger(SmppToProviderRoundRobinAlgorithm.class); protected Iterator<Entry<Long, MClientConnectionImpl>> connectionToProviderIterator = null; protected Iterator<Entry<KeySmpp, Node>> nodeIterator = null; @Override public void processSubmitToNode(ConcurrentHashMap<Long, MServerConnectionImpl> connectionsToNodes, Long serverSessionId, Pdu packet) { // TODO Auto-generated method stub } @Override public synchronized void processSubmitToProvider(ConcurrentHashMap<Long, MClientConnectionImpl> connectionsToProviders, Long sessionId, Pdu packet) { if(connectionToProviderIterator==null) connectionToProviderIterator = connectionsToProviders.entrySet().iterator(); Entry<Long, MClientConnectionImpl> pair = null; while(connectionToProviderIterator.hasNext()) { pair = connectionToProviderIterator.next(); if(connectionsToProviders.containsKey(pair.getKey())) pair.getValue().sendSmppRequest(sessionId,packet); return; } connectionToProviderIterator = connectionsToProviders.entrySet().iterator(); if(connectionToProviderIterator.hasNext()) { pair = connectionToProviderIterator.next(); pair.getValue().sendSmppRequest(sessionId,packet); return; } else throw new RuntimeException("LB does not have connected Providers, but trying send them request"); } @Override public synchronized Node processBindToProvider() { if(invocationContext.smppNodeMap.size() == 0) return null; if(nodeIterator==null) nodeIterator = invocationContext.smppNodeMap.entrySet().iterator(); Entry<KeySmpp, Node> pair = null; while(nodeIterator.hasNext()) { pair = nodeIterator.next(); if(invocationContext.smppNodeMap.containsKey(pair.getKey())) return pair.getValue(); } nodeIterator = invocationContext.smppNodeMap.entrySet().iterator(); if(nodeIterator.hasNext()) { pair = nodeIterator.next(); return pair.getValue(); } else return null; } @Override public void init() { // TODO Auto-generated method stub } @Override public void stop() { // TODO Auto-generated method stub } @Override public void configurationChanged() { ConcurrentHashMap<KeySmpp, Node> newSmppNodeMap = new ConcurrentHashMap<KeySmpp, Node>(); String [] s = balancerContext.lbConfig.getSmppConfiguration().getRemoteServers().split(","); String [] sTmp = new String[2]; for(int i = 0; i < s.length; i++) { sTmp = s[i].split(":"); Node currNode = new Node("SMPP server " + i, sTmp[0].trim()); currNode.getProperties().put("smppPort", sTmp[1].trim()); newSmppNodeMap.put(new KeySmpp(sTmp[0].trim(),Integer.parseInt(sTmp[1].trim())),currNode); } ConcurrentHashMap<KeySmpp, Node> removedSmppNodes = null; ConcurrentHashMap<KeySmpp, Node> addedSmppNodes = null; logger.info("Nodes removed : " + (removedSmppNodes = mapDifference(newSmppNodeMap, invocationContext.smppNodeMap)).values()); for(KeySmpp key:removedSmppNodes.keySet()) invocationContext.smppNodeMap.remove(key); logger.info("Nodes added : " + (addedSmppNodes = mapDifference(invocationContext.smppNodeMap, newSmppNodeMap)).values()); invocationContext.smppNodeMap.putAll(addedSmppNodes); logger.info("Updated SMPP node map after changing config file : " + invocationContext.smppNodeMap.values()); } private ConcurrentHashMap<KeySmpp, Node> mapDifference(ConcurrentHashMap<KeySmpp, Node> left, ConcurrentHashMap<KeySmpp, Node> right) { ConcurrentHashMap<KeySmpp, Node> difference = new ConcurrentHashMap<>(); difference.putAll(left); difference.putAll(right); difference.entrySet().removeAll(left.entrySet()); return difference; } }