Refactor and extend client/server model

This commit is contained in:
2015-06-25 15:59:49 +01:00
parent ef689c9c3a
commit ce7492d9ff
26 changed files with 233 additions and 116 deletions

View File

@@ -0,0 +1,3 @@
package base;
public interface Duplex extends Forwarder, Sender {}

View File

@@ -1,6 +1,4 @@
package base.receiver; package base;
import base.Control;
public interface Forwarder extends Control { public interface Forwarder extends Control {
public void register(Receiver receiver); public void register(Receiver receiver);

View File

@@ -1,7 +1,5 @@
package base.receiver; package base;
public interface Receiver { public interface Receiver {
public void receive(byte[] buffer); public void receive(byte[] buffer);
} }

View File

@@ -1,9 +1,7 @@
package base.sender; package base;
import java.io.IOException; import java.io.IOException;
import base.Control;
public interface Sender extends Control { public interface Sender extends Control {
public void send(byte[] buffer) throws IOException; public void send(byte[] buffer) throws IOException;
} }

View File

@@ -10,14 +10,18 @@ import org.picocontainer.parameters.ConstantParameter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import base.Duplex;
import base.Forwarder;
import base.Sender;
import base.exception.LoaderException; import base.exception.LoaderException;
import base.sender.UdpSender; import base.server.datagram.UdpSender;
import base.server.forwarder.TcpServerChannelForwarder; import base.server.forwarder.UdpDuplexClientForwarder;
import base.server.forwarder.TcpServerSocketForwarder; import base.server.forwarder.UdpDuplexServerForwarder;
import base.server.forwarder.UdpServerForwarder;
public class AbstractLoader<E> { public class AbstractLoader<T> {
protected static final String PROPERTIES_FILE = "loader.properties"; protected static final String PROPERTIES_FILE = "loader.properties";
protected static final Properties SERVER = null;
protected Logger logger = LoggerFactory.getLogger(AbstractLoader.class); protected Logger logger = LoggerFactory.getLogger(AbstractLoader.class);
protected MutablePicoContainer pico; protected MutablePicoContainer pico;
@@ -31,8 +35,8 @@ public class AbstractLoader<E> {
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public static <E> E getLoader() throws LoaderException { public static <T> T getLoader() throws LoaderException {
return (E) new AbstractLoader(readProperties(PROPERTIES_FILE)); return (T) new AbstractLoader(readProperties(PROPERTIES_FILE));
} }
public static Properties readProperties(String propertiesFile) throws LoaderException { public static Properties readProperties(String propertiesFile) throws LoaderException {
@@ -46,51 +50,97 @@ public class AbstractLoader<E> {
return properties; return properties;
} }
protected void addSender(String protocol, String implementation, String host, int port) throws LoaderException { protected Class<?> getSenderClass(String protocol, String implementation) throws LoaderException {
Class<?> senderClass = null;
switch (protocol) { switch (protocol) {
case "tcp": case "tcp":
switch (implementation) { switch (implementation) {
case "channel": case "channel":
senderClass = base.server.channel.TcpClient.class; return base.server.channel.TcpClient.class;
break;
default: default:
case "socket": case "socket":
senderClass = base.server.socket.TcpClient.class; return base.server.socket.TcpClient.class;
} }
break;
case "udp": case "udp":
senderClass = UdpSender.class; return UdpSender.class;
break;
} }
if (senderClass == null) {
throw new LoaderException("Failed to determine <Sender>"); throw new LoaderException("Failed to determine <Sender>");
} }
pico.addComponent(senderClass, senderClass, new Parameter[]{
protected Class<?> getClientForwarderClass(String protocol, String implementation) throws LoaderException {
switch (protocol) {
case "tcp":
switch (implementation) {
case "channel":
return base.server.forwarder.TcpClientChannelForwarder.class;
default:
case "socket":
return base.server.forwarder.TcpClientSocketForwarder.class;
}
case "udp":
return UdpDuplexClientForwarder.class;
}
throw new LoaderException("Failed to determine <Forwarder>");
}
protected Class<?> getServerForwarderClass(String protocol, String implementation) throws LoaderException {
switch (protocol) {
case "tcp":
switch (implementation) {
case "channel":
return base.server.forwarder.TcpChannelServerForwarder.class;
default:
case "socket":
return base.server.forwarder.TcpSocketServerForwarder.class;
}
case "udp":
return UdpDuplexServerForwarder.class;
}
throw new LoaderException("Failed to determine <Forwarder>");
}
protected void addClientSender(String protocol, String implementation, String host, int port) throws LoaderException {
Class<?> senderClass = getSenderClass(protocol, implementation);
logger.debug("Adding " + senderClass);
pico.addComponent(Sender.class, senderClass, new Parameter[]{
new ConstantParameter(host), new ConstantParameter(host),
new ConstantParameter(port)}); new ConstantParameter(port)});
} }
protected void addForwarder(String protocol, String implementation, int port) throws LoaderException { protected void addServerSender(String protocol, String implementation, int port) throws LoaderException {
Class<?> forwarderClass = null; Class<?> senderClass = getSenderClass(protocol, implementation);
switch (protocol) { logger.debug("Adding " + senderClass);
case "tcp": pico.addComponent(Sender.class, senderClass, new Parameter[]{
switch (implementation) { new ConstantParameter(port)});
case "channel":
forwarderClass = TcpServerChannelForwarder.class;
break;
default:
case "socket":
forwarderClass = TcpServerSocketForwarder.class;
} }
break;
case "udp": protected void addClientForwarder(String protocol, String implementation, String host, int port) throws LoaderException {
forwarderClass = UdpServerForwarder.class; Class<?> forwarderClass = getClientForwarderClass(protocol, implementation);
logger.debug("Adding " + forwarderClass);
pico.addComponent(Forwarder.class, forwarderClass, new Parameter[]{
new ConstantParameter(host),
new ConstantParameter(port)});
} }
if (forwarderClass == null) {
throw new LoaderException("Failed to determine <Forwarder>"); protected void addClientDuplex(String protocol, String implementation, String host, int port) throws LoaderException {
Class<?> duplexClass = getClientForwarderClass(protocol, implementation);
logger.debug("Adding " + duplexClass);
pico.addComponent(Duplex.class, duplexClass, new Parameter[]{
new ConstantParameter(host),
new ConstantParameter(port)});
} }
pico.addComponent(forwarderClass, forwarderClass, new Parameter[]{
protected void addServerForwarder(String protocol, String implementation, int port) throws LoaderException {
Class<?> forwarderClass = getServerForwarderClass(protocol, implementation);
logger.debug("Adding " + forwarderClass);
pico.addComponent(Forwarder.class, forwarderClass, new Parameter[]{
new ConstantParameter(port)});
}
protected void addServerDuplex(String protocol, String implementation, int port) throws LoaderException {
Class<?> duplexClass = getServerForwarderClass(protocol, implementation);
logger.debug("Adding " + duplexClass);
pico.addComponent(Duplex.class, duplexClass, new Parameter[]{
new ConstantParameter(port)}); new ConstantParameter(port)});
} }
} }

View File

@@ -1,19 +0,0 @@
package base.sender;
import java.io.IOException;
import base.server.socket.TcpClient;
public abstract class TcpSender extends TcpClient implements Sender {
public TcpSender(String host, int port) {
super(host, port);
}
public void send(byte[] buffer) throws IOException {
if (!active()) {
start();
// Control over threads here?
}
outputStream.write(buffer);
}
}

View File

@@ -10,9 +10,9 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import base.Sender;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.work.Listen; import base.work.Listen;
import base.work.Work; import base.work.Work;
import base.worker.Worker; import base.worker.Worker;

View File

@@ -13,9 +13,9 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import base.Sender;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.server.channel.TcpServerClient; import base.server.channel.TcpServerClient;
import base.work.Work; import base.work.Work;

View File

@@ -4,7 +4,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import base.sender.Sender; import base.Sender;
import base.work.Listen; import base.work.Listen;
public class TcpServerClient extends Listen<byte[]> implements Sender { public class TcpServerClient extends Listen<byte[]> implements Sender {

View File

@@ -0,0 +1,22 @@
package base.server.datagram;
import java.io.IOException;
import base.Sender;
public class UdpDuplexClient extends UdpMulticastClient implements Sender {
public UdpDuplexClient(int port) {
super(port);
}
public void send(byte[] buffer) throws IOException {
// TODO Auto-generated method stub
}
protected void input(byte[] buffer) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,9 @@
package base.server.datagram;
public class UdpDuplexServer extends UdpMulticastServer {
public UdpDuplexServer(int port) {
super(port);
}
}

View File

@@ -5,9 +5,9 @@ import java.net.DatagramPacket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.MulticastSocket; import java.net.MulticastSocket;
import base.Sender;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.work.Listen; import base.work.Listen;
import base.worker.Worker; import base.worker.Worker;

View File

@@ -1,4 +1,4 @@
package base.sender; package base.server.datagram;
import java.io.IOException; import java.io.IOException;
import java.net.DatagramPacket; import java.net.DatagramPacket;
@@ -10,6 +10,8 @@ import java.net.UnknownHostException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import base.Sender;
public class UdpSender implements Sender { public class UdpSender implements Sender {
protected static final String HOST = "localhost"; protected static final String HOST = "localhost";
protected Logger logger = LoggerFactory.getLogger(getClass()); protected Logger logger = LoggerFactory.getLogger(getClass());
@@ -29,21 +31,6 @@ public class UdpSender implements Sender {
this.port = port; this.port = port;
} }
protected boolean setup() {
return true;
}
public void send(byte[] buffer) {
try {
setup();
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, inetAddress, port);
datagramSocket.send(datagramPacket);
} catch (IOException e) {
logger.error("Failed to send buffer", e);
}
}
public void start() { public void start() {
if (datagramSocket == null) { if (datagramSocket == null) {
try { try {
@@ -63,4 +50,14 @@ public class UdpSender implements Sender {
public void exit() { public void exit() {
stop(); stop();
} }
public void send(byte[] buffer) {
try {
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, inetAddress, port);
datagramSocket.send(datagramPacket);
} catch (IOException e) {
logger.error("Failed to send buffer", e);
}
}
} }

View File

@@ -2,15 +2,15 @@ package base.server.forwarder;
import java.util.ArrayList; import java.util.ArrayList;
import base.receiver.Forwarder; import base.Duplex;
import base.receiver.Receiver; import base.Receiver;
import base.server.channel.TcpServer; import base.server.channel.TcpServer;
import base.server.channel.TcpServerClient; import base.server.channel.TcpServerClient;
public class TcpServerChannelForwarder extends TcpServer implements Forwarder { public class TcpChannelServerForwarder extends TcpServer implements Duplex {
protected ArrayList<Receiver> receiverList; protected ArrayList<Receiver> receiverList;
public TcpServerChannelForwarder(int port) { public TcpChannelServerForwarder(int port) {
super(port); super(port);
receiverList = new ArrayList<Receiver>(); receiverList = new ArrayList<Receiver>();
} }

View File

@@ -2,16 +2,16 @@ package base.server.forwarder;
import java.util.ArrayList; import java.util.ArrayList;
import base.receiver.Forwarder; import base.Duplex;
import base.receiver.Receiver; import base.Receiver;
import base.server.socket.TcpClient; import base.server.socket.TcpClient;
import base.server.socket.TcpServerClient; import base.server.socket.TcpServerClient;
public class TcpClientChannelForwarder extends TcpClient implements Forwarder { public class TcpClientChannelForwarder extends TcpClient implements Duplex {
protected ArrayList<Receiver> receiverList; protected ArrayList<Receiver> receiverList;
public TcpClientChannelForwarder(int port) { public TcpClientChannelForwarder(String host, int port) {
super(port); super(host, port);
receiverList = new ArrayList<Receiver>(); receiverList = new ArrayList<Receiver>();
} }

View File

@@ -2,16 +2,16 @@ package base.server.forwarder;
import java.util.ArrayList; import java.util.ArrayList;
import base.receiver.Forwarder; import base.Duplex;
import base.receiver.Receiver; import base.Receiver;
import base.server.channel.TcpClient; import base.server.channel.TcpClient;
import base.server.channel.TcpServerClient; import base.server.channel.TcpServerClient;
public class TcpClientSocketForwarder extends TcpClient implements Forwarder { public class TcpClientSocketForwarder extends TcpClient implements Duplex {
protected ArrayList<Receiver> receiverList; protected ArrayList<Receiver> receiverList;
public TcpClientSocketForwarder(int port) { public TcpClientSocketForwarder(String host, int port) {
super(port); super(host, port);
receiverList = new ArrayList<Receiver>(); receiverList = new ArrayList<Receiver>();
} }

View File

@@ -2,15 +2,15 @@ package base.server.forwarder;
import java.util.ArrayList; import java.util.ArrayList;
import base.receiver.Forwarder; import base.Duplex;
import base.receiver.Receiver; import base.Receiver;
import base.server.socket.TcpServer; import base.server.socket.TcpServer;
import base.server.socket.TcpServerClient; import base.server.socket.TcpServerClient;
public class TcpServerSocketForwarder extends TcpServer implements Forwarder { public class TcpSocketServerForwarder extends TcpServer implements Duplex {
protected ArrayList<Receiver> receiverList; protected ArrayList<Receiver> receiverList;
public TcpServerSocketForwarder(int port) { public TcpSocketServerForwarder(int port) {
super(port); super(port);
receiverList = new ArrayList<Receiver>(); receiverList = new ArrayList<Receiver>();
} }

View File

@@ -0,0 +1,30 @@
package base.server.forwarder;
import java.util.ArrayList;
import base.Duplex;
import base.Receiver;
import base.server.datagram.UdpDuplexClient;
public class UdpDuplexClientForwarder extends UdpDuplexClient implements Duplex {
protected ArrayList<Receiver> receiverList;
public UdpDuplexClientForwarder(String host, int port) {
super(port);
receiverList = new ArrayList<Receiver>();
}
public void register(Receiver receiver) {
receiverList.add(receiver);
}
public void remove(Receiver receiver) {
receiverList.remove(receiver);
}
public void input(byte[] buffer) {
for (Receiver receiver: receiverList) {
receiver.receive(buffer);
}
}
}

View File

@@ -0,0 +1,30 @@
package base.server.forwarder;
import java.util.ArrayList;
import base.Duplex;
import base.Receiver;
import base.server.datagram.UdpDuplexServer;
public class UdpDuplexServerForwarder extends UdpDuplexServer implements Duplex {
protected ArrayList<Receiver> receiverList;
public UdpDuplexServerForwarder(int port) {
super(port);
receiverList = new ArrayList<Receiver>();
}
public void register(Receiver receiver) {
receiverList.add(receiver);
}
public void remove(Receiver receiver) {
receiverList.remove(receiver);
}
public void input(byte[] buffer) {
for (Receiver receiver: receiverList) {
receiver.receive(buffer);
}
}
}

View File

@@ -2,8 +2,8 @@ package base.server.forwarder;
import java.util.ArrayList; import java.util.ArrayList;
import base.receiver.Forwarder; import base.Forwarder;
import base.receiver.Receiver; import base.Receiver;
import base.server.datagram.UdpServer; import base.server.datagram.UdpServer;
public class UdpServerForwarder extends UdpServer implements Forwarder { public class UdpServerForwarder extends UdpServer implements Forwarder {

View File

@@ -1,11 +1,11 @@
package base.server.forwarder; package base.server.receiver;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import base.Control; import base.Control;
import base.receiver.Forwarder; import base.Forwarder;
import base.receiver.Receiver; import base.Receiver;
public abstract class AbstractReceiver implements Receiver, Control { public abstract class AbstractReceiver implements Receiver, Control {
protected Logger logger = LoggerFactory.getLogger(getClass()); protected Logger logger = LoggerFactory.getLogger(getClass());

View File

@@ -5,8 +5,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import base.Sender;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.work.Work; import base.work.Work;
public abstract class AbstractTcpClient extends Work implements Sender { public abstract class AbstractTcpClient extends Work implements Sender {

View File

@@ -4,8 +4,8 @@ import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import base.Sender;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.sender.Sender;
public class TcpClient extends AbstractTcpClient implements Sender { public class TcpClient extends AbstractTcpClient implements Sender {
protected static final String HOST = "localhost"; protected static final String HOST = "localhost";

View File

@@ -6,9 +6,9 @@ import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import base.Sender;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.work.Work; import base.work.Work;
public class TcpServer extends Work implements Sender { public class TcpServer extends Work implements Sender {

View File

@@ -3,6 +3,7 @@ package base.work;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import base.Control;
import base.exception.worker.ActivateException; import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException; import base.exception.worker.DeactivateException;
import base.worker.DirectWorker; import base.worker.DirectWorker;
@@ -11,7 +12,7 @@ import base.worker.Worker;
import base.worker.pool.PooledWorker; import base.worker.pool.PooledWorker;
import base.worker.pool.WorkerPool; import base.worker.pool.WorkerPool;
public abstract class Work { public abstract class Work implements Control {
protected static final Worker.Type WORKER_TYPE = Worker.Type.BACKGROUND; protected static final Worker.Type WORKER_TYPE = Worker.Type.BACKGROUND;
protected Logger logger = LoggerFactory.getLogger(getClass()); protected Logger logger = LoggerFactory.getLogger(getClass());

View File

@@ -7,7 +7,7 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import base.sender.UdpSender; import base.server.datagram.UdpSender;
import base.server.datagram.UdpServer; import base.server.datagram.UdpServer;
public class TestUdpUnicastCommunication { public class TestUdpUnicastCommunication {