/* * 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.impl; import java.util.ArrayList; import java.util.Map; import org.mobicents.tools.heartbeat.api.Node; import org.mobicents.tools.sip.balancer.BalancerRunner; import org.mobicents.tools.smpp.balancer.api.ClientConnection; import org.mobicents.tools.smpp.balancer.api.ServerConnection; import org.mobicents.tools.smpp.balancer.impl.ClientConnectionImpl.ClientState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.cloudhopper.smpp.SmppConstants; import com.cloudhopper.smpp.pdu.BaseBind; import com.cloudhopper.smpp.pdu.BaseBindResp; import com.cloudhopper.smpp.pdu.Pdu; import com.cloudhopper.smpp.pdu.Unbind; import com.cloudhopper.smpp.tlv.Tlv; /** * @author Konstantin Nosach (kostyantyn.nosach@telestax.com) */ public class BinderRunnable implements Runnable { private static final Logger logger = LoggerFactory.getLogger(BinderRunnable.class); private int index; private Pdu packet; private ClientConnectionImpl client; private Map<Long, ServerConnection> serverSessions; private Map<Long, ClientConnection> clientSessions; private Long sessionId; private Node firstNode; private ArrayList<Node> nodes; public BinderRunnable(Long sessionId, Pdu packet, Map<Long, ServerConnection> serverSessions, Map<Long, ClientConnection> clientSessions, Node node, BalancerRunner balancerRunner) { this.sessionId = sessionId; this.packet = packet; this.client = (ClientConnectionImpl) clientSessions.get(sessionId); this.firstNode = node; this.nodes = new ArrayList<Node>(balancerRunner.getLatestInvocationContext().smppNodeMap.values()); //this.index = this.nodes.indexOf(node); this.serverSessions = serverSessions; this.clientSessions = clientSessions; } @SuppressWarnings("rawtypes") @Override public void run() { boolean connectSuccesful = true; while (!client.connect()) { logger.warn("Connection to " + client.getConfig().getHost() + ":" + client.getConfig().getPort() + " failed we will try next server"); index ++; if (index == nodes.size()) index = 0; if (index == nodes.indexOf(firstNode)) { connectSuccesful = false; break; } client.getConfig().setHost(nodes.get(index).getIp()); if(!client.getConfig().isUseSsl()) client.getConfig().setPort(Integer.parseInt((String) nodes.get(index).getProperties().get("smppPort"))); else client.getConfig().setPort(Integer.parseInt((String)nodes.get(index).getProperties().get("smppSslPort"))); logger.warn("Next server : " + client.getConfig().getHost() + ":" + client.getConfig().getPort()); } if (connectSuccesful) { client.bind(); } else { if (client.getClientState() == ClientState.INITIAL) { BaseBindResp bindResponse = (BaseBindResp) ((BaseBind) packet).createResponse(); bindResponse.setCommandStatus(SmppConstants.STATUS_SYSERR); bindResponse.setSystemId(client.getConfig().getSystemId()); if (client.getConfig().getInterfaceVersion() >= SmppConstants.VERSION_3_4 && ((BaseBind) packet).getInterfaceVersion() >= SmppConstants.VERSION_3_4) { Tlv scInterfaceVersion = new Tlv(SmppConstants.TAG_SC_INTERFACE_VERSION, new byte[] { client.getConfig().getInterfaceVersion() }); bindResponse.addOptionalParameter(scInterfaceVersion); } serverSessions.get(sessionId).sendBindResponse(bindResponse); client.setClientState(ClientState.CLOSED); clientSessions.remove(sessionId); serverSessions.remove(sessionId); } else { serverSessions.get(sessionId).sendUnbindRequest(new Unbind()); clientSessions.remove(sessionId); } } } }