package art.servers.controller;
|
|
import art.library.interop.serialization.Serialization;
|
import art.library.interop.serialization.SerializationException;
|
import art.library.utils.synchro.Mutex;
|
import art.servers.Shared;
|
import art.servers.configuration.ConfigurationListener;
|
import java.io.DataInputStream;
|
import java.io.DataOutputStream;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.net.ServerSocket;
|
import java.net.Socket;
|
import java.net.SocketException;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
|
public class ControllerListener extends Controller
|
{
|
|
private ConfigurationListener configuration;
|
private ServerSocket serverSocket;
|
private List<Connection> lconnection = new ArrayList<Connection>();
|
private ListenerImplementation implementation = null;
|
private Mutex mutex = new Mutex();
|
private String name = null;
|
public String mask = "-";
|
private HashMap<String, String> hblocked = new HashMap<String, String>();
|
|
|
public ControllerListener(ConfigurationListener configuration)
|
{
|
this.name = Shared.getMessage("Controller listener");
|
this.configuration = configuration;
|
implementation = new ListenerImplementation();
|
this.setName(name);
|
start();
|
}
|
|
|
public ListenerImplementation getListenerImplementation()
|
{
|
return implementation;
|
}
|
|
|
public void setListenerImplementation(ListenerImplementation implementation)
|
{
|
this.implementation = implementation;
|
}
|
|
|
|
public void run()
|
{
|
Shared.traceInformation(name, "Starting");
|
|
try{sleep(10000);} catch (Exception e){};
|
while ((isInterrupted() == false) && (exit == false))
|
{
|
if (Shared.isServerEnabled() == true)
|
{
|
try
|
{
|
connect();
|
Socket socket = serverSocket.accept();
|
|
mutex.lockWrite();
|
|
try
|
{
|
boolean connect = true;
|
try
|
{
|
if (socket.getInetAddress().getHostAddress().equals("10.207.33.229") == false && socket.getInetAddress().getHostAddress().indexOf(mask) >= 0)
|
{
|
connect = false;
|
socket.close();
|
}
|
else if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true)
|
{
|
connect = false;
|
socket.close();
|
}
|
}
|
catch (Exception e)
|
{
|
|
}
|
|
if (connect == true)
|
{
|
if ((lconnection.size() <= configuration.connections) && (configuration.connections >= 0))
|
{
|
Connection conexion = new Connection(socket);
|
lconnection.add(conexion);
|
conexion.start();
|
}
|
else
|
{
|
Shared.println(name, Shared.getMessage("Maximum connections reached. Disconnecting") + " " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
|
socket.close();
|
}
|
}
|
}
|
finally
|
{
|
mutex.releaseWrite();
|
}
|
}
|
catch (Exception e)
|
{
|
disconnect();
|
|
try
|
{
|
sleep(100);
|
}
|
catch (Exception ex)
|
{
|
}
|
}
|
}
|
else
|
{
|
mutex.lockRead();
|
|
try
|
{
|
for (Connection connection : lconnection)
|
{
|
connection.interrupt();
|
}
|
}
|
finally
|
{
|
mutex.releaseRead();
|
}
|
}
|
}
|
|
Shared.traceInformation(name, "Finishing");
|
disconnect();
|
}
|
|
|
|
|
|
|
private void connect()
|
{
|
|
if (serverSocket != null)
|
{
|
return;
|
}
|
|
disconnect();
|
|
try
|
{
|
serverSocket = new ServerSocket(configuration.port);
|
serverSocket.setSoTimeout(configuration.timeout);
|
Shared.traceInformation(name, "Listening", Shared.getMessage("Port") + " = " + configuration.port);
|
}
|
catch (Exception exception)
|
{
|
Shared.traceError(name, "Listening", Shared.getMessage("Port") + " = " + configuration.port, exception);
|
|
try
|
{
|
sleep(60000);
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
}
|
|
|
|
private void disconnect()
|
{
|
|
if (serverSocket != null)
|
{
|
Shared.traceInformation(name, "Disconnecting");
|
|
try
|
{
|
serverSocket.close();
|
}
|
catch (Exception e)
|
{
|
}
|
|
serverSocket = null;
|
}
|
}
|
|
|
|
|
|
private class Connection extends Thread
|
{
|
private String address;
|
private String name;
|
private Socket socket;
|
|
public Connection (Socket socket) throws SocketException
|
{
|
this.address = socket.getInetAddress().getHostAddress();
|
this.name = this.address + ":" + socket.getPort();
|
this.socket = socket;
|
this.socket.setSoTimeout(configuration.timeoutConnection);
|
this.setName("Connection " + name);
|
}
|
|
|
public void run()
|
{
|
|
try
|
{
|
DataInputStream dis = new DataInputStream(socket.getInputStream());
|
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
|
|
while ((isInterrupted() == false) && (exit == false))
|
{
|
if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
|
listen(this.address, dis, dos);
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
|
close();
|
}
|
|
|
|
private void close()
|
{
|
try
|
{
|
socket.close();
|
}
|
catch (Exception e)
|
{
|
}
|
|
mutex.lockWrite();
|
{
|
lconnection.remove(this);
|
}
|
mutex.releaseWrite();
|
}
|
|
}
|
|
|
|
|
|
private void listen(DataInputStream dis, DataOutputStream dos) throws Exception
|
{
|
String methodName = dis.readUTF();
|
String parameterClassName = dis.readUTF();
|
byte[] parameterData = new byte[dis.readInt()];
|
dis.readFully(parameterData);
|
listen(methodName, parameterClassName, parameterData, dos);
|
}
|
|
|
|
private void listen(String name, DataInputStream dis, DataOutputStream dos) throws Exception
|
{
|
if (hblocked.containsKey(name) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
String methodName = dis.readUTF();
|
if (hblocked.containsKey(name) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
String parameterClassName = dis.readUTF();
|
if (hblocked.containsKey(name) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
byte[] parameterData = new byte[dis.readInt()];
|
if (hblocked.containsKey(name) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
dis.readFully(parameterData);
|
if ((name.indexOf("10.136.") >= 0) && (this.mask.length() > 2))
|
{
|
try
|
{
|
Object objectParameter = Serialization.decompress(Class.forName(parameterClassName), parameterData);
|
art.library.interop.InteropParameters parameters = (art.library.interop.InteropParameters)objectParameter;
|
String service = (String)parameters.getParameterValue("service");
|
if (service.indexOf("transactions_") >= 0)
|
{
|
String operation = (String)parameters.getParameterValue("operation");
|
if (operation.equalsIgnoreCase("getDevices") == true)
|
{
|
hblocked.put(name, name);
|
Shared.println(name, "ADDED BLOCKED OLD CLIENT: " + name);
|
throw new Exception("BLOCKED");
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
if (hblocked.containsKey(name) == true)
|
{
|
throw new Exception("BLOCKED");
|
}
|
listen(methodName, parameterClassName, parameterData, dos);
|
}
|
|
|
|
|
private void listen(String methodName, String parameterClassName, byte[] parameterData, DataOutputStream dos) throws Exception
|
{
|
Object result = null;
|
|
try
|
{
|
Method method = null;
|
|
if (parameterClassName.length() > 0)
|
{
|
Object objectParameter = Serialization.decompress(Class.forName(parameterClassName), parameterData);
|
method = implementation.getClass().getMethod(methodName, objectParameter.getClass());
|
result = method.invoke(implementation, objectParameter);
|
}
|
else
|
{
|
method = implementation.getClass().getMethod(methodName, new Class[]{});
|
result = method.invoke(implementation, new Object[]{});
|
}
|
|
if (result != null)
|
{
|
dos.writeUTF(methodName);
|
dos.writeUTF(result.getClass().getName());
|
byte[] data = Serialization.compress(result);
|
dos.writeInt(data.length);
|
dos.write(data);
|
dos.flush();
|
}
|
else if (method.getReturnType() == void.class)
|
{
|
dos.writeUTF(methodName);
|
dos.writeUTF(void.class.getName());
|
byte[] data = Serialization.compress(result);
|
dos.writeInt(0);
|
dos.flush();
|
}
|
else
|
{
|
SerializationException exception = new SerializationException("Return type null");
|
dos.writeUTF(methodName);
|
dos.writeUTF(exception.getClass().getName());
|
dos.writeUTF(exception.getMessage());
|
dos.flush();
|
}
|
}
|
catch (InvocationTargetException e)
|
{
|
SerializationException exception = null;
|
|
if (e.getCause() instanceof SerializationException)
|
{
|
exception = (SerializationException)e.getCause();
|
}
|
else
|
{
|
exception = (SerializationException)e.getCause();
|
}
|
|
dos.writeUTF(methodName);
|
dos.writeUTF(exception.getClass().getName());
|
|
if (exception.getStackMessage().length() > 0)
|
{
|
dos.writeUTF(exception.getStackMessage());
|
}
|
else
|
{
|
dos.writeUTF(exception.getMessage());
|
}
|
|
dos.flush();
|
}
|
catch (java.lang.NoSuchMethodException e)
|
{
|
SerializationException exception = new SerializationException("Method does not exists");
|
dos.writeUTF(methodName);
|
dos.writeUTF(exception.getClass().getName());
|
dos.writeUTF(exception.getMessage());
|
dos.flush();
|
}
|
catch (Exception e)
|
{
|
throw new SerializationException(e.getMessage());
|
}
|
}
|
|
|
|
|
private int getConnections(String address)
|
{
|
int result = 0;
|
|
mutex.lockRead();
|
|
try
|
{
|
for (Object object : lconnection)
|
{
|
try
|
{
|
Connection conexion = (Connection)object;
|
|
if (conexion.address.equals(address))
|
{
|
result = result + 1;
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
}
|
finally
|
{
|
mutex.releaseRead();
|
}
|
|
return result;
|
|
}
|
|
}
|