/* * 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.balancer.core; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.mobicents.tools.heartbeat.api.Node; import org.mobicents.tools.sip.balancer.BalancerRunner; import org.mobicents.tools.sip.balancer.InvocationContext; import org.mobicents.tools.sip.balancer.KeySmpp; import org.mobicents.tools.smpp.balancer.api.ClientConnection; import org.mobicents.tools.smpp.balancer.api.Dispatcher; import org.mobicents.tools.smpp.balancer.api.LbClientListener; import org.mobicents.tools.smpp.balancer.api.LbServerListener; import org.mobicents.tools.smpp.balancer.api.ServerConnection; import org.mobicents.tools.smpp.balancer.impl.BinderRunnable; import org.mobicents.tools.smpp.balancer.impl.ClientConnectionImpl; import org.mobicents.tools.smpp.balancer.impl.ServerConnectionImpl; import com.cloudhopper.smpp.SmppSessionConfiguration; import com.cloudhopper.smpp.pdu.Pdu; /** * @author Konstantin Nosach (kostyantyn.nosach@telestax.com) */ public class BalancerDispatcher extends Dispatcher implements LbClientListener, LbServerListener { private Map<Long, ServerConnection> serverSessions = new ConcurrentHashMap<Long, ServerConnection>(); private Map<Long, ClientConnection> clientSessions = new ConcurrentHashMap<Long, ClientConnection>(); private AtomicInteger notBindClients = new AtomicInteger(0); private AtomicInteger notRespondedPackets = new AtomicInteger(0); private ScheduledExecutorService monitorExecutor; private ExecutorService handlerService = Executors.newCachedThreadPool(); private long reconnectPeriod; private BalancerRunner balancerRunner; private AtomicInteger counterConnections = new AtomicInteger(0); private InvocationContext ctx; public BalancerDispatcher(BalancerRunner balancerRunner, ScheduledExecutorService monitorExecutor) { this.balancerRunner = balancerRunner; this.reconnectPeriod = balancerRunner.balancerContext.lbConfig.getSmppConfiguration().getReconnectPeriod(); this.monitorExecutor = monitorExecutor; this.ctx = balancerRunner.getLatestInvocationContext(); String [] s = balancerRunner.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()); this.ctx.smppNodeMap.put(new KeySmpp(sTmp[0].trim(),Integer.parseInt(sTmp[1].trim())),currNode); } } public AtomicInteger getNotBindClients() { return notBindClients; } public AtomicInteger getNotRespondedPackets() { return notRespondedPackets; } public Map<Long, ServerConnection> getServerSessions() { return serverSessions; } public Map<Long, ClientConnection> getClientSessions() { return clientSessions; } public AtomicInteger getCounterConnections() { return counterConnections; } @Override public void bindRequested(Long sessionId, ServerConnectionImpl serverConnection, Pdu packet) { //InvocationContext invocationContext = balancerRunner.getLatestInvocationContext(); balancerRunner.balancerContext.smppRequestsToServer.getAndIncrement(); balancerRunner.incMessages(); balancerRunner.balancerContext.smppRequestsProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToServer.addAndGet(packet.getCommandLength()); serverSessions.put(sessionId,serverConnection); SmppSessionConfiguration sessionConfig = serverConnection.getConfig(); if(!serverConnection.getConfig().isUseSsl()) sessionConfig.setUseSsl(false); else sessionConfig.setUseSsl(!balancerRunner.balancerContext.terminateTLSTraffic); counterConnections.compareAndSet(Integer.MAX_VALUE, 0); Node currNode = ctx.smppToProviderBalancerAlgorithm.processBindToProvider(); sessionConfig.setHost(currNode.getIp()); sessionConfig.setPort(Integer.parseInt((String) currNode.getProperties().get("smppPort"))); clientSessions.put(sessionId, new ClientConnectionImpl(sessionId, sessionConfig, this, monitorExecutor, balancerRunner , packet, currNode)); handlerService.execute(new BinderRunnable(sessionId, packet, serverSessions, clientSessions, currNode, balancerRunner)); } @Override public void unbindRequested(Long sessionID, Pdu packet) { balancerRunner.balancerContext.smppRequestsToServer.getAndIncrement(); balancerRunner.incMessages(); balancerRunner.balancerContext.smppRequestsProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToServer.addAndGet(packet.getCommandLength()); clientSessions.get(sessionID).sendUnbindRequest(packet); } @Override public void bindSuccesfull(long sessionID, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionID).sendBindResponse(packet); } @Override public void unbindSuccesfull(long sessionID, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionID).sendUnbindResponse(packet); clientSessions.remove(sessionID); serverSessions.remove(sessionID); } @Override public void bindFailed(long sessionID, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionID).sendBindResponse(packet); clientSessions.remove(sessionID); serverSessions.remove(sessionID); } @Override public void smppEntityRequested(Long sessionID, Pdu packet) { balancerRunner.balancerContext.smppRequestsToServer.getAndIncrement(); balancerRunner.incMessages(); balancerRunner.balancerContext.smppRequestsProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToServer.addAndGet(packet.getCommandLength()); clientSessions.get(sessionID).sendSmppRequest(packet); } @Override public void smppEntityResponse(Long sessionID, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionID).sendResponse(packet); } @Override public void smppEntityRequestFromServer(Long sessionId, Pdu packet) { balancerRunner.balancerContext.smppRequestsToClient.getAndIncrement(); balancerRunner.incMessages(); balancerRunner.balancerContext.smppRequestsProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionId).sendRequest(packet); } @Override public void smppEntityResponseFromClient(Long sessionId, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToServer.addAndGet(packet.getCommandLength()); clientSessions.get(sessionId).sendSmppResponse(packet); } @Override public void connectionLost(Long sessionId, Pdu packet, Node node) { serverSessions.get(sessionId).reconnectState(true); monitorExecutor.schedule(new BinderRunnable(sessionId, packet, serverSessions, clientSessions, node, balancerRunner), reconnectPeriod, TimeUnit.MILLISECONDS); } @Override public void reconnectSuccesful(Long sessionId) { serverSessions.get(sessionId).reconnectState(false); } @Override public void checkConnection(Long sessionId) { serverSessions.get(sessionId).generateEnquireLink(); clientSessions.get(sessionId).generateEnquireLink(); } @Override public void enquireLinkReceivedFromServer(Long sessionId) { serverSessions.get(sessionId).updateLastTimeSMPPLinkUpdated(); } @Override public void closeConnection(Long sessionId) { clientSessions.get(sessionId).closeChannel(); clientSessions.remove(sessionId); serverSessions.remove(sessionId); } @Override public void unbindRequestedFromServer(Long sessionId, Pdu packet) { balancerRunner.balancerContext.smppRequestsToClient.getAndIncrement(); balancerRunner.incMessages(); balancerRunner.balancerContext.smppRequestsProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToClient.addAndGet(packet.getCommandLength()); serverSessions.get(sessionId).sendUnbindRequest(packet); } @Override public void unbindSuccesfullFromServer(Long sessionId, Pdu packet) { balancerRunner.balancerContext.smppResponsesProcessedById.get(packet.getCommandId()).incrementAndGet(); balancerRunner.balancerContext.smppBytesToServer.addAndGet(packet.getCommandLength()); if(clientSessions.get(sessionId)!=null) { clientSessions.get(sessionId).sendUnbindResponse(packet); clientSessions.remove(sessionId); } serverSessions.remove(sessionId); } }