org.bidib.jbidibc.netbidib.debug.NetBidibDebugClient Maven / Gradle / Ivy
package org.bidib.jbidibc.netbidib.debug;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.bidib.jbidibc.debug.DebugMessageReceiver;
import org.bidib.jbidibc.messages.ConnectionListener;
import org.bidib.jbidibc.messages.MessageReceiver;
import org.bidib.jbidibc.messages.exception.PortNotOpenedException;
import org.bidib.jbidibc.messages.utils.ThreadFactoryBuilder;
import org.bidib.jbidibc.netbidib.client.DefaultNetMessageHandler;
import org.bidib.jbidibc.netbidib.client.NetBidibClientPort;
import org.bidib.jbidibc.netbidib.client.NetBidibPort;
import org.bidib.jbidibc.netbidib.client.NetMessageHandler;
import org.bidib.jbidibc.netbidib.client.listener.NetBidibPortConnectionStatusListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NetBidibDebugClient implements NetBidibDebugClientInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(NetBidibDebugClient.class);
private String connectedPortName;
private InetAddress address;
private int portNumber;
private String protocol;
private NetBidibPort port;
private final DebugMessageReceiver messageReceiver;
private NetMessageHandler netMessageHandler;
private final ScheduledExecutorService portWorker =
Executors
.newScheduledThreadPool(1,
new ThreadFactoryBuilder().setNameFormat("netBidibDebugPortWorkers-thread-%d").build());
public NetBidibDebugClient(final DebugMessageReceiver debugMessageReceiver) {
this.messageReceiver = debugMessageReceiver;
}
@Override
public void open(String portName, final ConnectionListener connectionListener) throws PortNotOpenedException {
LOGGER.info("Internal open port: {}", portName);
String[] hostAndPort = portName.split(":");
if (hostAndPort.length > 2) {
// protocol provided
protocol = hostAndPort[0];
try {
address = InetAddress.getByName(hostAndPort[1]);
}
catch (UnknownHostException ex) {
throw new PortNotOpenedException("The provided host is not vaild.", hostAndPort[1]);
}
portNumber = Integer.parseInt(hostAndPort[2]);
}
else {
protocol = "tcp";
try {
address = InetAddress.getByName(hostAndPort[0]);
}
catch (UnknownHostException ex) {
throw new PortNotOpenedException("The provided host is not vaild.", hostAndPort[0]);
}
portNumber = Integer.parseInt(hostAndPort[1]);
}
this.connectedPortName = portName;
LOGGER.info("Configured address: {}, portNumber: {}, protocol: {}", address, portNumber, protocol);
final MessageReceiver messageReceiverDelegate = new MessageReceiver() {
@Override
public void cleanup() {
}
@Override
public void receive(ByteArrayOutputStream data) {
messageReceiver.processMessages(data);
}
};
netMessageHandler =
new DefaultNetMessageHandler(messageReceiverDelegate, address, portNumber, connectionListener);
// open the port
final CountDownLatch startupLock = new CountDownLatch(1);
NetBidibPort netBidibPort;
try {
netBidibPort = new NetBidibClientPort(address, portNumber, netMessageHandler);
netBidibPort.addConnectionStatusListener(new NetBidibPortConnectionStatusListener() {
@Override
public void opened() {
LOGGER.info("Opened with countDown latch.");
startupLock.countDown();
if (connectionListener != null) {
connectionListener.opened(connectedPortName);
}
}
@Override
public void closed() {
LOGGER.info("The netBidib connection was closed.");
if (connectionListener != null) {
connectionListener.closed(connectedPortName);
}
}
@Override
public void clientAccepted(String remoteAddress) {
LOGGER.info("Client accepted, remoteAddress: {}", remoteAddress);
// TODO Auto-generated method stub
}
});
LOGGER.info("Prepare and start the port worker for netBidibPort: {}", netBidibPort);
// prepare and start the port worker
portWorker.submit(netBidibPort);
}
catch (IOException ex) {
LOGGER.warn("Open netBidib port failed.", ex);
throw new PortNotOpenedException("Open netBidib port failed.", ex.getMessage());
}
LOGGER.info("The netBidib port was opened: {}", netBidibPort);
this.port = netBidibPort;
}
@Override
public boolean isOpened() {
return port != null;
}
@Override
public void close() {
LOGGER.info("Close the port.");
if (port != null) {
LOGGER.info("Stop the port.");
final NetBidibPort portToClose = this.port;
this.port = null;
portToClose.stop();
if (portWorker != null) {
synchronized (portWorker) {
try {
portWorker.shutdown();
portWorker.awaitTermination(5000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException ex) {
LOGGER.warn("Wait for termination of port worker failed.", ex);
}
}
}
}
else {
LOGGER.info("No port to close available.");
}
}
@Override
public void send(byte[] data) {
if (port != null) {
try {
port.send(data, address, portNumber);
}
catch (IOException ex) {
LOGGER.warn("Send data to port failed.", ex);
}
}
}
}