Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2014, 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
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* JBoss, Home of Professional Open Source
* Copyright 2007-2011, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jdiameter.server.impl.io.tcp;
import static org.jdiameter.server.impl.helpers.Parameters.BindDelay;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.jdiameter.client.api.parser.IMessageParser;
import org.jdiameter.client.impl.transport.tcp.TCPClientConnection;
import org.jdiameter.common.api.concurrent.DummyConcurrentFactory;
import org.jdiameter.common.api.concurrent.IConcurrentFactory;
import org.jdiameter.server.api.IMetaData;
import org.jdiameter.server.api.io.INetworkConnectionListener;
import org.jdiameter.server.api.io.INetworkGuard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TCP implementation of {@link org.jdiameter.server.api.io.INetworkGuard}.
*
* @author Alexandre Mendonca
* @author Bartosz Baranowski
*/
@SuppressWarnings("all") //3rd party lib
public class NetworkGuard implements INetworkGuard {
private static final Logger logger = LoggerFactory.getLogger(NetworkGuard.class);
protected IMessageParser parser;
protected IConcurrentFactory concurrentFactory;
protected int port;
protected long bindDelay;
protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList();
protected boolean isWork = false;
// protected Selector selector;
// protected ServerSocket serverSocket;
//private Thread thread;
private List tasks = new ArrayList();
@Deprecated
public NetworkGuard(InetAddress inetAddress, int port, IMessageParser parser) throws Exception {
this(inetAddress, port, null, parser, null);
}
public NetworkGuard(InetAddress inetAddress, int port,
IConcurrentFactory concurrentFactory, IMessageParser parser,
IMetaData data) throws Exception {
this(new InetAddress[] { inetAddress }, port, concurrentFactory, parser, data);
}
public NetworkGuard(InetAddress[] inetAddress, int port,
IConcurrentFactory concurrentFactory, IMessageParser parser,
IMetaData data) throws Exception {
this.port = port;
this.parser = parser;
this.concurrentFactory = concurrentFactory == null ? new DummyConcurrentFactory() : concurrentFactory;
//this.thread = this.concurrentFactory.getThread("NetworkGuard", this);
this.bindDelay = data.getConfiguration().getLongValue(BindDelay.ordinal(), (Long) BindDelay.defValue());
try {
for (int addrIdx = 0; addrIdx < inetAddress.length; addrIdx++) {
GuardTask guardTask = new GuardTask(new InetSocketAddress(inetAddress[addrIdx], port));
this.concurrentFactory.getThreadPool().execute(guardTask);
tasks.add(guardTask);
}
isWork = true;
} catch (Exception exc) {
destroy();
throw new Exception(exc);
}
}
@Override
public void addListener(INetworkConnectionListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public void remListener(INetworkConnectionListener listener) {
listeners.remove(listener);
}
@Override
public String toString() {
return "NetworkGuard:" + (this.tasks.size() != 0 ? this.tasks : "closed");
}
@Override
public void destroy() {
isWork = false;
Iterator it = this.tasks.iterator();
while (it.hasNext()) {
GuardTask gt = it.next();
it.remove();
gt.cleanTask();
}
}
private class GuardTask implements Runnable {
private Thread thread;
private Selector selector;
private ServerSocket serverSocket;
private final ScheduledExecutorService binder = Executors.newSingleThreadScheduledExecutor();
GuardTask(final InetSocketAddress addr) throws IOException {
if (bindDelay > 0) {
logger.info("Socket binding will be delayed by {}ms...", bindDelay);
}
Runnable task = new Runnable() {
@Override
public void run() {
try {
logger.debug("Binding {} after delaying {}ms...", addr, bindDelay);
final ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
serverSocket = ssc.socket();
serverSocket.bind(addr);
selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT, addr);
logger.info("Open server socket {} ", serverSocket);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
binder.schedule(task, bindDelay, TimeUnit.MILLISECONDS);
}
public void start() {
this.thread.start();
}
@Override
public void run() {
try {
while (isWork) {
if (selector == null) {
logger.trace("Selector is still null, stack is waiting for binding...");
Thread.sleep(250);
continue;
}
// without timeout when we kill socket, this causes errors, bug in VM ?
int num = selector.select(100);
if (num == 0) {
continue;
}
Set keys = selector.selectedKeys();
try {
for (SelectionKey key : keys) {
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
try {
Socket s = serverSocket.accept();
logger.info("Open incomming connection {}", s);
TCPClientConnection client = new TCPClientConnection(null, concurrentFactory, s, parser,
null);
// PCB added logging
logger.debug("Finished initialising TCPClientConnection for {}", s);
for (INetworkConnectionListener listener : listeners) {
listener.newNetworkConnection(client);
}
} catch (Exception e) {
logger.warn("Can not create incoming connection", e);
}
}
}
} catch (Exception e) {
logger.debug("Failed to accept connection,", e);
} finally {
keys.clear();
}
}
} catch (Exception exc) {
logger.warn("Server socket stopped", exc);
}
}
public void cleanTask() {
try {
if (thread != null) {
thread.join(2000);
if (thread.isAlive()) {
// FIXME: remove ASAP
thread.interrupt();
}
thread = null;
}
} catch (InterruptedException e) {
logger.debug("Can not stop thread", e);
}
if (selector != null) {
try {
selector.close();
} catch (Exception e) {
// ignore
}
selector = null;
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (Exception e) {
// ignore
}
serverSocket = null;
}
}
@Override
public String toString() {
return "GuardTask [serverSocket=" + serverSocket + "]";
}
}
}