package io.muoncore.channel.impl; import io.muoncore.channel.Channel; import io.muoncore.channel.ChannelConnection; import io.muoncore.exception.MuonException; import io.muoncore.message.MuonMessage; import io.muoncore.transport.client.TransportMessageDispatcher; import reactor.core.Dispatcher; public class WiretapChannel<GoingLeft extends MuonMessage, GoingRight extends MuonMessage> implements Channel<GoingLeft, GoingRight> { private ChannelConnection<GoingLeft, GoingRight> left; private ChannelConnection<GoingRight, GoingLeft> right; private ChannelConnection.ChannelFunction<GoingLeft> leftFunction; private ChannelConnection.ChannelFunction<GoingRight> rightFunction; public static boolean echoOut = false; public WiretapChannel(Dispatcher dispatcher, TransportMessageDispatcher transportMessageDispatcher) { String leftname = "left"; String rightname = "right"; left = new ChannelConnection<GoingLeft, GoingRight>() { @Override public void receive(ChannelFunction<GoingRight> function) { rightFunction = function; } @Override public void send(GoingLeft message) { if (leftFunction == null) { throw new MuonException("Other side of the channel [" + rightname + "] is not connected to receive data"); } dispatcher.dispatch(message, msg -> { if (echoOut) System.out.println("WiretapChannel[" + leftname + " >>>>> " + rightname + "]: Sending " + msg + " to " + leftFunction); transportMessageDispatcher.dispatch(msg); leftFunction.apply(message); } , Throwable::printStackTrace); } @Override public void shutdown() { leftFunction.apply(null); } }; right = new ChannelConnection<GoingRight, GoingLeft>() { @Override public void receive(ChannelFunction<GoingLeft> function) { leftFunction = function; } @Override public void send(GoingRight message) { if (rightFunction == null) { throw new MuonException("Other side of the channel [" + rightname + "] is not connected to receive data"); } dispatcher.dispatch(message, msg -> { if (echoOut) System.out.println("WiretapChannel[" + leftname + " <<<< " + rightname + "]: " + msg + " to " + rightFunction); transportMessageDispatcher.dispatch(msg); rightFunction.apply(message); }, Throwable::printStackTrace); } @Override public void shutdown() { rightFunction.apply(null); } }; } @Override public ChannelConnection<GoingRight, GoingLeft> right() { return right; } @Override public ChannelConnection<GoingLeft, GoingRight> left() { return left; } }