Use LogAccessor from SF

* Change main classes to use a `LogAccessor` API to simplify code flow
* Fix tests according `LogAccessor` property
* Fix some Sonar smells
This commit is contained in:
Artem Bilan
2020-10-06 13:56:50 -04:00
parent a66e82b0aa
commit c7ff99a4e8
95 changed files with 1165 additions and 1432 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,9 +88,7 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
boolean isErrorMessage = message instanceof ErrorMessage;
try {
if (this.shuttingDown) {
if (logger.isInfoEnabled()) {
logger.info("Inbound message ignored; shutting down; " + message.toString());
}
logger.info(() -> "Inbound message ignored; shutting down; " + message.toString());
}
else {
if (isErrorMessage) {
@@ -126,9 +124,7 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
private boolean doOnMessage(Message<?> message) {
Message<?> reply = sendAndReceiveMessage(message);
if (reply == null) {
if (logger.isDebugEnabled()) {
logger.debug("null reply received for " + message + " nothing to send");
}
logger.debug(() -> "null reply received for " + message + " nothing to send");
return false;
}
String connectionId = (String) message.getHeaders().get(IpHeaders.CONNECTION_ID);
@@ -138,14 +134,14 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
}
if (connection == null) {
publishNoConnectionEvent(message, connectionId);
logger.error("Connection not found when processing reply " + reply + " for " + message);
logger.error(() -> "Connection not found when processing reply " + reply + " for " + message);
return false;
}
try {
connection.send(reply);
}
catch (Exception e) {
logger.error("Failed to send reply", e);
catch (Exception ex) {
logger.error(ex, "Failed to send reply");
}
return false;
}

View File

@@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.MessageTimeoutException;
import org.springframework.integration.expression.ExpressionUtils;
@@ -61,6 +60,7 @@ import org.springframework.util.concurrent.SettableListenableFuture;
*
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
@@ -113,7 +113,7 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
* @param remoteTimeout the remoteTimeout to set
*/
public void setRemoteTimeout(long remoteTimeout) {
this.remoteTimeoutExpression = new LiteralExpression("" + remoteTimeout);
this.remoteTimeoutExpression = new ValueExpression<>(remoteTimeout);
}
/**
@@ -207,8 +207,7 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
Assert.notNull(this.connectionFactory, this.getClass().getName() +
" requires a client connection factory");
Assert.notNull(this.connectionFactory, () -> getClass().getName() + " requires a client connection factory");
boolean haveSemaphore = false;
TcpConnection connection = null;
String connectionId = null;
@@ -221,9 +220,8 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
AsyncReply reply = new AsyncReply(remoteTimeout, connection, haveSemaphore, requestMessage, async);
connectionId = connection.getConnectionId();
this.pendingReplies.put(connectionId, reply);
if (logger.isDebugEnabled()) {
logger.debug("Added pending reply " + connectionId);
}
String connectionIdToLog = connectionId;
logger.debug(() -> "Added pending reply " + connectionIdToLog);
connection.send(requestMessage);
if (this.closeStreamAfterSend) {
connection.shutdownOutput();
@@ -235,16 +233,16 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
return getReply(requestMessage, connection, connectionId, reply);
}
}
catch (RuntimeException | IOException e) {
logger.error("Tcp Gateway exception", e);
if (e instanceof MessagingException) {
throw (MessagingException) e;
catch (RuntimeException | IOException ex) {
logger.error(ex, "Tcp Gateway exception");
if (ex instanceof MessagingException) {
throw (MessagingException) ex;
}
throw new MessagingException("Failed to send or receive", e);
throw new MessagingException("Failed to send or receive", ex);
}
catch (InterruptedException e) {
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new MessageHandlingException(requestMessage, "Interrupted in the [" + this + ']', e);
throw new MessageHandlingException(requestMessage, "Interrupted in the [" + this + ']', ex);
}
finally {
if (!async) {
@@ -266,9 +264,7 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
if (!this.semaphore.tryAcquire(this.requestTimeout, TimeUnit.MILLISECONDS)) {
throw new MessageTimeoutException(requestMessage, "Timed out waiting for connection");
}
if (logger.isDebugEnabled()) {
logger.debug("got semaphore");
}
logger.debug("got semaphore");
return true;
}
return false;
@@ -279,10 +275,8 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
Long.class);
if (remoteTimeout == null) {
remoteTimeout = DEFAULT_REMOTE_TIMEOUT;
if (logger.isWarnEnabled()) {
logger.warn("remoteTimeoutExpression evaluated to null; falling back to default for message "
+ requestMessage);
}
logger.warn(() -> "remoteTimeoutExpression evaluated to null; falling back to default for message "
+ requestMessage);
}
return remoteTimeout;
}
@@ -292,25 +286,19 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
Message<?> replyMessage = reply.getReply();
if (replyMessage == null) {
if (logger.isDebugEnabled()) {
logger.debug("Remote Timeout on " + connectionId);
}
logger.debug(() -> "Remote Timeout on " + connectionId);
// The connection is dirty - force it closed.
this.connectionFactory.forceClose(connection);
throw new MessageTimeoutException(requestMessage, "Timed out waiting for response");
}
if (logger.isDebugEnabled()) {
logger.debug("Response " + replyMessage);
}
logger.debug(() -> "Response " + replyMessage);
return replyMessage;
}
private void cleanUp(boolean haveSemaphore, TcpConnection connection, String connectionId) {
if (connectionId != null) {
this.pendingReplies.remove(connectionId);
if (logger.isDebugEnabled()) {
logger.debug("Removed pending reply " + connectionId);
}
logger.debug(() -> "Removed pending reply " + connectionId);
if (this.isSingleUse) {
connection.close();
}
@@ -332,9 +320,7 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
publishNoConnectionEvent(message, null, "Cannot correlate response - no connection id");
return false;
}
if (logger.isTraceEnabled()) {
logger.trace("onMessage: " + connectionId + "(" + message + ")");
}
logger.trace(() -> "onMessage: " + connectionId + "(" + message + ")");
AsyncReply reply = this.pendingReplies.get(connectionId);
if (reply == null) {
if (message instanceof ErrorMessage) {
@@ -374,8 +360,8 @@ public class TcpOutboundGateway extends AbstractReplyProducingMessageHandler
try {
this.messagingTemplate.send(this.unsolicitedMessageChannel, message);
}
catch (Exception e) {
logger.error("Failed to send unsolicited message " + message, e);
catch (Exception ex) {
logger.error(ex, "Failed to send unsolicited message " + message);
}
return true;
}

View File

@@ -85,9 +85,9 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
try {
connection = this.clientConnectionFactory.getConnection();
}
catch (Exception e) {
logger.error("Error creating connection", e);
throw new MessageHandlingException(message, "Failed to obtain a connection in the [" + this + ']', e);
catch (Exception ex) {
logger.error(ex, "Error creating connection");
throw new MessageHandlingException(message, "Failed to obtain a connection in the [" + this + ']', ex);
}
return connection;
}
@@ -119,7 +119,7 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
connection.send(message);
}
catch (Exception ex) {
logger.error("Error sending message", ex);
logger.error(ex, "Error sending message");
connection.close();
throw IntegrationUtils.wrapInHandlingExceptionIfNecessary(message,
() -> "Error sending message in the [" + this + ']', ex);
@@ -131,7 +131,7 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
}
}
else {
logger.error("Unable to find outbound socket for " + message);
logger.error(() -> "Unable to find outbound socket for " + message);
MessageHandlingException messageHandlingException =
new MessageHandlingException(message, "Unable to find outbound socket in the [" + this + ']');
publishNoConnectionEvent(messageHandlingException, connectionId);
@@ -145,16 +145,14 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
try {
connection = doWrite(message);
}
catch (MessageHandlingException e) {
catch (MessageHandlingException ex) {
// retry - socket may have closed
if (e.getCause() instanceof IOException) {
if (logger.isDebugEnabled()) {
logger.debug("Fail on first write attempt", e);
}
if (ex.getCause() instanceof IOException) {
logger.debug(ex, "Fail on first write attempt");
connection = doWrite(message);
}
else {
throw e;
throw ex;
}
}
finally {
@@ -176,9 +174,8 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
TcpConnection connection = null;
try {
connection = obtainConnection(message);
if (logger.isDebugEnabled()) {
logger.debug("Got Connection " + connection.getConnectionId());
}
TcpConnection connectionToLog = connection;
logger.debug(() -> "Got Connection " + connectionToLog.getConnectionId());
connection.send(message);
}
catch (Exception ex) {
@@ -197,8 +194,10 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
}
private void publishNoConnectionEvent(MessageHandlingException messageHandlingException, String connectionId) {
AbstractConnectionFactory cf = this.serverConnectionFactory != null ? this.serverConnectionFactory
: this.clientConnectionFactory;
AbstractConnectionFactory cf =
this.serverConnectionFactory != null
? this.serverConnectionFactory
: this.clientConnectionFactory;
ApplicationEventPublisher applicationEventPublisher = cf.getApplicationEventPublisher();
if (applicationEventPublisher != null) {
applicationEventPublisher.publishEvent(

View File

@@ -369,8 +369,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
* @param listenerToRegister the TcpListener.
*/
public void registerListener(TcpListener listenerToRegister) {
Assert.isNull(this.listener, this.getClass().getName() +
" may only be used by one inbound adapter");
Assert.isNull(this.listener, () -> getClass().getName() + " may only be used by one inbound adapter");
this.listener = listenerToRegister;
}
@@ -535,9 +534,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
@Override
public void start() {
if (logger.isInfoEnabled()) {
logger.info("started " + this);
}
logger.info(() -> "started " + this);
}
/**
@@ -594,9 +591,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
}
}
}
if (logger.isInfoEnabled()) {
logger.info("stopped " + this);
}
logger.info(() -> "stopped " + this);
}
protected TcpConnectionSupport wrapConnection(TcpConnectionSupport connectionArg) {
@@ -666,15 +661,11 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
if (!connection.isServer() &&
now - connection.getLastSend() < this.soTimeout &&
now - connection.getLastRead() < this.soTimeout * 2) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping a connection timeout because we have a recent send " +
connection.getConnectionId());
}
logger.debug(() -> "Skipping a connection timeout because we have a recent send " +
connection.getConnectionId());
}
else {
if (logger.isWarnEnabled()) {
logger.warn("Timing out TcpNioConnection " + connection.getConnectionId());
}
logger.warn(() -> "Timing out TcpNioConnection " + connection.getConnectionId());
Exception exception = new SocketTimeoutException("Timing out connection");
connection.publishConnectionExceptionEvent(exception);
connection.timeout();
@@ -685,14 +676,16 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
}
}
harvestClosedConnections();
if (logger.isTraceEnabled()) {
logger.trace(() -> {
if (this.host == null) {
logger.trace("Port " + this.port + " SelectionCount: " + selectionCount);
return "Port " + this.port + " SelectionCount: " + selectionCount;
}
else {
logger.trace("Host " + this.host + " port " + this.port + " SelectionCount: " + selectionCount);
return "Host " + this.host + " port " + this.port + " SelectionCount: " + selectionCount;
}
}
});
if (selectionCount > 0) {
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
@@ -720,7 +713,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
}
catch (Exception e2) {
if (connection.isOpen()) {
logger.error("Exception on read " +
logger.error(() -> "Exception on read " +
connection.getConnectionId() + " " +
e2.getMessage());
connection.close();
@@ -748,8 +741,8 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
try {
doAccept(selector, server, now);
}
catch (Exception e) {
logger.error("Exception accepting new connection(s)", e);
catch (Exception ex) {
logger.error(ex, "Exception accepting new connection(s)");
}
}
else {
@@ -757,12 +750,10 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
}
}
catch (@SuppressWarnings(UNUSED) CancelledKeyException e) {
if (logger.isDebugEnabled()) {
logger.debug("Selection key " + key + " cancelled");
}
logger.debug(() -> "Selection key " + key + " cancelled");
}
catch (Exception e) {
logger.error("Exception on selection key " + key, e);
catch (Exception ex) {
logger.error(ex, () -> "Exception on selection key " + key);
}
}
}
@@ -771,13 +762,11 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
protected void delayRead(Selector selector, long now, final SelectionKey key) {
TcpNioConnection connection = (TcpNioConnection) key.attachment();
if (!this.delayedReads.add(new PendingIO(now, key))) { // should never happen - unbounded queue
logger.error("Failed to delay read; closing " + connection.getConnectionId());
logger.error(() -> "Failed to delay read; closing " + connection.getConnectionId());
connection.close();
}
else {
if (logger.isDebugEnabled()) {
logger.debug("No threads available, delaying read for " + connection.getConnectionId());
}
logger.debug(() -> "No threads available, delaying read for " + connection.getConnectionId());
// wake the selector in case it is currently blocked, and waiting for longer than readDelay
selector.wakeup();
}
@@ -798,10 +787,8 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
if (pendingRead.key.channel().isOpen()) {
pendingRead.key.interestOps(SelectionKey.OP_READ);
wakeSelector = true;
if (logger.isDebugEnabled()) {
logger.debug("Rescheduling delayed read for " +
((TcpNioConnection) pendingRead.key.attachment()).getConnectionId());
}
logger.debug(() -> "Rescheduling delayed read for " +
((TcpNioConnection) pendingRead.key.attachment()).getConnectionId());
}
else {
((TcpNioConnection) pendingRead.key.attachment())
@@ -840,9 +827,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
return;
}
this.connections.put(connection.getConnectionId(), connection);
if (logger.isDebugEnabled()) {
logger.debug(getComponentName() + ": Added new connection: " + connection.getConnectionId());
}
logger.debug(() -> getComponentName() + ": Added new connection: " + connection.getConnectionId());
}
}
@@ -859,16 +844,12 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
TcpConnectionSupport connection = entry.getValue();
if (!connection.isOpen()) {
iterator.remove();
if (logger.isDebugEnabled()) {
logger.debug(getComponentName() + ": Removed closed connection: " +
connection.getConnectionId());
}
logger.debug(() -> getComponentName() + ": Removed closed connection: " +
connection.getConnectionId());
}
else {
openConnectionIds.add(entry.getKey());
if (logger.isTraceEnabled()) {
logger.trace(getComponentName() + ": Connection is open: " + connection.getConnectionId());
}
logger.trace(() -> getComponentName() + ": Connection is open: " + connection.getConnectionId());
}
}
return openConnectionIds;
@@ -941,11 +922,9 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
connection.close();
closed = true;
}
catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to close connection " + connectionId, e);
}
connection.publishConnectionExceptionEvent(e);
catch (Exception ex) {
logger.debug(ex, () -> "Failed to close connection " + connectionId);
connection.publishConnectionExceptionEvent(ex);
}
}
return closed;

View File

@@ -141,8 +141,8 @@ public abstract class AbstractServerConnectionFactory extends AbstractConnection
try {
socket.setSoTimeout(DEFAULT_REPLY_TIMEOUT);
}
catch (SocketException e) {
logger.error("Error setting default reply timeout", e);
catch (SocketException ex) {
logger.error(ex, "Error setting default reply timeout");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,12 +41,12 @@ import org.springframework.util.Assert;
*/
public class TcpNetServerConnectionFactory extends AbstractServerConnectionFactory {
private volatile ServerSocket serverSocket;
private volatile TcpSocketFactorySupport tcpSocketFactorySupport = new DefaultTcpNetSocketFactorySupport();
private TcpSocketFactorySupport tcpSocketFactorySupport = new DefaultTcpNetSocketFactorySupport();
private TcpNetConnectionSupport tcpNetConnectionSupport = new DefaultTcpNetConnectionSupport();
private volatile ServerSocket serverSocket;
/**
* Listens for incoming connections on the port.
* @param port The port.
@@ -81,6 +81,11 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
}
}
public void setTcpSocketFactorySupport(TcpSocketFactorySupport tcpSocketFactorySupport) {
Assert.notNull(tcpSocketFactorySupport, "TcpSocketFactorySupport may not be null");
this.tcpSocketFactorySupport = tcpSocketFactorySupport;
}
/**
* Set the {@link TcpNetConnectionSupport} to use to create connection objects.
* @param connectionSupport the connection support.
@@ -102,7 +107,7 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
public void run() {
ServerSocket theServerSocket = null;
if (getListener() == null) {
logger.info(this + " No listener bound to server connection factory; will not read; exiting...");
logger.info(() -> this + " No listener bound to server connection factory; will not read; exiting...");
return;
}
try {
@@ -116,7 +121,7 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
getTcpSocketSupport().postProcessServerSocket(theServerSocket);
this.serverSocket = theServerSocket;
setListening(true);
logger.info(this + " Listening");
logger.info(() -> this + " Listening");
publishServerListeningEvent(getPort());
while (true) {
final Socket socket;
@@ -126,9 +131,7 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
*/
try {
if (this.serverSocket == null) {
if (logger.isDebugEnabled()) {
logger.debug(this + " stopped before accept");
}
logger.debug(() -> this + " stopped before accept");
throw new IOException(this + " stopped before accept");
}
else {
@@ -136,24 +139,18 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
}
}
catch (@SuppressWarnings("unused") SocketTimeoutException ste) {
if (logger.isDebugEnabled()) {
logger.debug("Timed out on accept; continuing");
}
logger.debug("Timed out on accept; continuing");
continue;
}
if (isShuttingDown()) {
if (logger.isInfoEnabled()) {
logger.info("New connection from " + socket.getInetAddress().getHostAddress()
+ ":" + socket.getPort()
+ " rejected; the server is in the process of shutting down.");
}
logger.info(() -> "New connection from " + socket.getInetAddress().getHostAddress()
+ ":" + socket.getPort()
+ " rejected; the server is in the process of shutting down.");
socket.close();
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Accepted connection from " + socket.getInetAddress().getHostAddress()
+ ":" + socket.getPort());
}
logger.debug(() -> "Accepted connection from " + socket.getInetAddress().getHostAddress()
+ ":" + socket.getPort());
try {
setSocketAttributes(socket);
TcpConnectionSupport connection = this.tcpNetConnectionSupport.createNewConnection(socket, true,
@@ -164,9 +161,10 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
harvestClosedConnections();
connection.publishConnectionOpenEvent();
}
catch (RuntimeException e) {
this.logger.error("Failed to create and configure a TcpConnection for the new socket: "
+ socket.getInetAddress().getHostAddress() + ":" + socket.getPort(), e);
catch (RuntimeException ex) {
this.logger.error(ex, () ->
"Failed to create and configure a TcpConnection for the new socket: "
+ socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
try {
socket.close();
}
@@ -177,14 +175,14 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
}
}
}
catch (IOException e) { // NOSONAR flow control via exceptions
catch (IOException ex) { // NOSONAR flow control via exceptions
// don't log an error if we had a good socket once and now it's closed
if (e instanceof SocketException && theServerSocket != null) {
if (ex instanceof SocketException && theServerSocket != null) {
logger.info("Server Socket closed");
}
else if (isActive()) {
logger.error("Error on ServerSocket; port = " + getPort(), e);
publishServerExceptionEvent(e);
logger.error(ex, "Error on ServerSocket; port = " + getPort());
publishServerExceptionEvent(ex);
stop();
}
}
@@ -241,9 +239,4 @@ public class TcpNetServerConnectionFactory extends AbstractServerConnectionFacto
return this.tcpSocketFactorySupport;
}
public void setTcpSocketFactorySupport(TcpSocketFactorySupport tcpSocketFactorySupport) {
Assert.notNull(tcpSocketFactorySupport, "TcpSocketFactorySupport may not be null");
this.tcpSocketFactorySupport = tcpSocketFactorySupport;
}
}

View File

@@ -157,8 +157,8 @@ public class TcpNioClientConnectionFactory extends
try {
this.selector.close();
}
catch (Exception e) {
logger.error("Error closing selector", e);
catch (Exception ex) {
logger.error(ex, "Error closing selector");
}
}
super.stop();
@@ -177,9 +177,7 @@ public class TcpNioClientConnectionFactory extends
@Override
public void run() {
if (logger.isDebugEnabled()) {
logger.debug("Read selector running for connections to " + getHost() + ":" + getPort());
}
logger.debug(() -> "Read selector running for connections to " + getHost() + ':' + getPort());
try {
this.selector = Selector.open();
while (isActive()) {
@@ -188,16 +186,14 @@ public class TcpNioClientConnectionFactory extends
}
catch (ClosedSelectorException cse) {
if (isActive()) {
logger.error("Selector closed", cse);
logger.error(cse, "Selector closed");
}
}
catch (Exception e) {
logger.error("Exception in read selector thread", e);
catch (Exception ex) {
logger.error(ex, "Exception in read selector thread");
setActive(false);
}
if (logger.isDebugEnabled()) {
logger.debug("Read selector exiting for connections to " + getHost() + ":" + getPort());
}
logger.debug(() -> "Read selector exiting for connections to " + getHost() + ':' + getPort());
}
private void processSelectorWhileActive() throws IOException {

View File

@@ -95,8 +95,8 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
port = ((InetSocketAddress) address).getPort();
}
}
catch (IOException e) {
logger.error("Error getting port", e);
catch (IOException ex) {
logger.error(ex, "Error getting port");
}
}
return port;
@@ -109,8 +109,8 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
try {
return this.serverChannel.getLocalAddress();
}
catch (IOException e) {
logger.error("Error getting local address", e);
catch (IOException ex) {
logger.error(ex, "Error getting local address");
}
}
return null;
@@ -126,7 +126,7 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
@Override
public void run() {
if (getListener() == null) {
logger.info(this + " No listener bound to server connection factory; will not read; exiting...");
logger.info(() -> this + " No listener bound to server connection factory; will not read; exiting...");
return;
}
try {
@@ -134,21 +134,18 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
int port = super.getPort();
getTcpSocketSupport().postProcessServerSocket(this.serverChannel.socket());
this.serverChannel.configureBlocking(false);
if (getLocalAddress() == null) {
String localAddress = getLocalAddress();
if (localAddress == null) {
this.serverChannel.socket().bind(new InetSocketAddress(port), Math.abs(getBacklog()));
}
else {
InetAddress whichNic = InetAddress.getByName(getLocalAddress());
InetAddress whichNic = InetAddress.getByName(localAddress);
this.serverChannel.socket().bind(new InetSocketAddress(whichNic, port), Math.abs(getBacklog()));
}
if (logger.isInfoEnabled()) {
logger.info(this + " Listening");
}
logger.info(() -> this + " Listening");
final Selector theSelector = Selector.open();
if (this.serverChannel == null) {
if (logger.isDebugEnabled()) {
logger.debug(this + " stopped before registering the server channel");
}
logger.debug(() -> this + " stopped before registering the server channel");
}
else {
this.serverChannel.register(theSelector, SelectionKey.OP_ACCEPT);
@@ -158,10 +155,10 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
doSelect(this.serverChannel, theSelector);
}
}
catch (IOException e) {
catch (IOException ex) {
if (isActive()) {
logger.error("Error on ServerChannel; port = " + getPort(), e);
publishServerExceptionEvent(e);
logger.error(ex, "Error on ServerChannel; port = " + getPort());
publishServerExceptionEvent(ex);
}
stop();
}
@@ -180,20 +177,19 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
* is complete, the socket is again registered for read interest.
* @param server the ServerSocketChannel to select
* @param selectorToSelect the Selector multiplexor
* @throws IOException
* @throws IOException a thrown IO exception
*/
private void doSelect(ServerSocketChannel server, final Selector selectorToSelect) throws IOException {
while (isActive()) {
int soTimeout = getSoTimeout();
int selectionCount = 0;
int selectionCount;
try {
long timeout = Math.max(soTimeout, 0);
if (getDelayedReads().size() > 0 && (timeout == 0 || getReadDelay() < timeout)) {
timeout = getReadDelay();
}
if (logger.isTraceEnabled()) {
logger.trace("Delayed reads: " + getDelayedReads().size() + " timeout " + timeout);
}
long timeoutToLog = timeout;
logger.trace(() -> "Delayed reads: " + getDelayedReads().size() + " timeout " + timeoutToLog);
selectionCount = selectorToSelect.select(timeout);
processNioSelections(selectionCount, selectorToSelect, server, this.channelMap);
}
@@ -202,7 +198,7 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
}
catch (ClosedSelectorException cse) {
if (isActive()) {
logger.error("Selector closed", cse);
logger.error(cse, "Selector closed");
publishServerExceptionEvent(cse);
break;
}
@@ -221,20 +217,20 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
try {
SocketChannel channel;
do {
channel = server.accept();
if (channel != null) {
SocketChannel theChannel = server.accept();
if (theChannel != null) {
if (isShuttingDown()) {
if (logger.isInfoEnabled()) {
logger.info("New connection from " + channel.socket().getInetAddress().getHostAddress()
+ ":" + channel.socket().getPort()
+ " rejected; the server is in the process of shutting down.");
}
channel.close();
logger.info(() ->
"New connection from " + theChannel.socket().getInetAddress().getHostAddress()
+ ":" + theChannel.socket().getPort()
+ " rejected; the server is in the process of shutting down.");
theChannel.close();
}
else if (createConnectionForAcceptedChannel(selectorForNewSocket, now, channel) == null) {
else if (createConnectionForAcceptedChannel(selectorForNewSocket, now, theChannel) == null) {
return;
}
}
channel = theChannel;
}
while (this.multiAccept && channel != null);
}
@@ -265,10 +261,10 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
connection.publishConnectionOpenEvent();
}
}
catch (IOException e) {
logger.error("Exception accepting new connection from "
catch (IOException ex) {
logger.error(ex, "Exception accepting new connection from "
+ channel.socket().getInetAddress().getHostAddress()
+ ":" + channel.socket().getPort(), e);
+ ":" + channel.socket().getPort());
channel.close();
}
return connection;
@@ -284,8 +280,8 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
initializeConnection(wrappedConnection, socketChannel.socket());
return connection;
}
catch (Exception e) {
logger.error("Failed to establish new incoming connection", e);
catch (Exception ex) {
logger.error(ex, "Failed to establish new incoming connection");
return null;
}
}
@@ -297,8 +293,8 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
try {
this.selector.close();
}
catch (Exception e) {
logger.error("Error closing selector", e);
catch (Exception ex) {
logger.error(ex, "Error closing selector");
}
}
if (this.serverChannel != null) {

View File

@@ -152,9 +152,7 @@ public class MulticastSendingMessageHandler extends UnicastSendingMessageHandler
if (soReceiveBufferSize > 0) {
socket.setReceiveBufferSize(soReceiveBufferSize);
}
if (logger.isDebugEnabled()) {
logger.debug("Listening for acks on port: " + socket.getLocalPort());
}
logger.debug(() -> "Listening for acks on port: " + socket.getLocalPort());
setSocket(socket);
updateAckAddress();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,17 +42,21 @@ import org.springframework.messaging.MessagingException;
* information indicating an acknowledgment needs to be sent.
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolReceivingChannelAdapter {
private volatile DatagramSocket socket;
private static final Pattern ADDRESS_PATTERN = Pattern.compile("([^:]*):([0-9]*)");
private final DatagramPacketMessageMapper mapper = new DatagramPacketMessageMapper();
private volatile int soSendBufferSize = -1;
private DatagramSocket socket;
private static Pattern addressPattern = Pattern.compile("([^:]*):([0-9]*)");
private boolean socketExplicitlySet;
private int soSendBufferSize = -1;
/**
@@ -103,7 +107,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
@Override
protected void onInit() {
super.onInit();
this.mapper.setBeanFactory(this.getBeanFactory());
this.mapper.setBeanFactory(getBeanFactory());
}
@Override
@@ -115,29 +119,27 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
publisher.publishEvent(new UdpServerListeningEvent(this, getPort()));
}
if (logger.isDebugEnabled()) {
logger.debug("UDP Receiver running on port:" + this.getPort());
}
logger.debug(() -> "UDP Receiver running on port: " + getPort());
setListening(true);
// Do as little as possible here so we can loop around and catch the next packet.
// Just schedule the packet for processing.
while (this.isActive()) {
while (isActive()) {
try {
asyncSendMessage(receive());
}
catch (SocketTimeoutException e) {
catch (SocketTimeoutException ex) {
// continue
}
catch (SocketException e) {
this.stop();
catch (SocketException ex) {
stop();
}
catch (Exception e) {
if (e instanceof MessagingException) {
throw (MessagingException) e;
catch (Exception ex) {
if (ex instanceof MessagingException) {
throw (MessagingException) ex;
}
throw new MessagingException("failed to receive DatagramPacket", e);
throw new MessagingException("failed to receive DatagramPacket", ex);
}
}
setListening(false);
@@ -147,12 +149,12 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
MessageHeaders headers = message.getHeaders();
Object id = headers.get(IpHeaders.ACK_ID);
if (id == null) {
logger.error("No " + IpHeaders.ACK_ID + " header; cannot send ack");
logger.error(() -> "No " + IpHeaders.ACK_ID + " header; cannot send ack");
return;
}
byte[] ack = id.toString().getBytes();
String ackAddress = (headers.get(IpHeaders.ACK_ADDRESS, String.class)).trim(); // NOSONAR caller checks header
Matcher mat = addressPattern.matcher(ackAddress);
Matcher mat = ADDRESS_PATTERN.matcher(ackAddress);
if (!mat.matches()) {
throw new MessagingException(message,
"Ack requested but could not decode acknowledgment address: " + ackAddress);
@@ -160,9 +162,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
String host = mat.group(1);
int port = Integer.parseInt(mat.group(2));
InetSocketAddress whereTo = new InetSocketAddress(host, port);
if (logger.isDebugEnabled()) {
logger.debug("Sending ack for " + id + " to " + ackAddress);
}
logger.debug(() -> "Sending ack for " + id + " to " + ackAddress);
try {
DatagramPacket ackPack = new DatagramPacket(ack, ack.length, whereTo);
DatagramSocket out = new DatagramSocket();
@@ -172,21 +172,19 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
out.send(ackPack);
out.close();
}
catch (IOException e) {
throw new MessagingException(message, "Failed to send acknowledgment to: " + ackAddress, e);
catch (IOException ex) {
throw new MessagingException(message, "Failed to send acknowledgment to: " + ackAddress, ex);
}
}
protected boolean asyncSendMessage(final DatagramPacket packet) {
protected boolean asyncSendMessage(DatagramPacket packet) {
Executor taskExecutor = getTaskExecutor();
if (taskExecutor != null) {
try {
taskExecutor.execute(() -> doSend(packet));
}
catch (RejectedExecutionException e) {
if (logger.isDebugEnabled()) {
logger.debug("Adapter stopped, sending on main thread");
}
logger.debug("Adapter stopped, sending on main thread");
doSend(packet);
}
}
@@ -197,12 +195,11 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
Message<byte[]> message = null;
try {
message = this.mapper.toMessage(packet);
if (logger.isDebugEnabled()) {
logger.debug("Received:" + message);
}
Message<byte[]> messageToLog = message;
logger.debug(() -> "Received: " + messageToLog);
}
catch (Exception e) {
logger.error("Failed to map packet to message ", e);
catch (Exception ex) {
logger.error(ex, "Failed to map packet to message ");
}
if (message != null) {
if (message.getHeaders().containsKey(IpHeaders.ACK_ADDRESS)) {
@@ -211,14 +208,14 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
try {
sendMessage(message);
}
catch (Exception e) {
this.logger.error("Failed to send message " + message, e);
catch (Exception ex) {
this.logger.error(ex, "Failed to send message " + message);
}
}
}
protected DatagramPacket receive() throws IOException {
final byte[] buffer = new byte[this.getReceiveBufferSize()];
final byte[] buffer = new byte[getReceiveBufferSize()];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
getSocket().receive(packet);
return packet;
@@ -229,6 +226,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
*/
public void setSocket(DatagramSocket socket) {
this.socket = socket;
this.socketExplicitlySet = true;
}
@Nullable
@@ -239,8 +237,8 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
public synchronized DatagramSocket getSocket() {
if (this.socket == null) {
try {
DatagramSocket datagramSocket = null;
String localAddress = this.getLocalAddress();
DatagramSocket datagramSocket;
String localAddress = getLocalAddress();
int port = super.getPort();
if (localAddress == null) {
datagramSocket = port == 0 ? new DatagramSocket() : new DatagramSocket(port);
@@ -265,10 +263,9 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
* @param socket The socket.
* @throws SocketException Any socket exception.
*/
protected void setSocketAttributes(DatagramSocket socket)
throws SocketException {
socket.setSoTimeout(this.getSoTimeout());
int soReceiveBufferSize = this.getSoReceiveBufferSize();
protected void setSocketAttributes(DatagramSocket socket) throws SocketException {
socket.setSoTimeout(getSoTimeout());
int soReceiveBufferSize = getSoReceiveBufferSize();
if (soReceiveBufferSize > 0) {
socket.setReceiveBufferSize(soReceiveBufferSize);
}
@@ -279,7 +276,9 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
super.doStop();
try {
DatagramSocket datagramSocket = this.socket;
this.socket = null;
if (!this.socketExplicitlySet) {
this.socket = null;
}
datagramSocket.close();
}
catch (Exception e) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2001-2019 the original author or authors.
* Copyright 2001-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,43 +68,43 @@ public class UnicastSendingMessageHandler extends
private final DatagramPacketMessageMapper mapper = new DatagramPacketMessageMapper();
private final Expression destinationExpression;
private final Map<String, CountDownLatch> ackControl = Collections.synchronizedMap(new HashMap<>());
private volatile DatagramSocket socket;
private final Expression destinationExpression;
/**
* If true adds headers to instruct receiving adapter to return an ack.
*/
private volatile boolean waitForAck = false;
private boolean waitForAck = false;
private volatile boolean acknowledge = false;
private boolean acknowledge = false;
private volatile String ackHost;
private String ackHost;
private volatile int ackPort;
private int ackPort;
private volatile int ackTimeout = DEFAULT_ACK_TIMEOUT;
private int ackTimeout = DEFAULT_ACK_TIMEOUT;
private volatile int ackCounter = 1;
private int ackCounter = 1;
private volatile Map<String, CountDownLatch> ackControl = Collections.synchronizedMap(new HashMap<>());
private int soReceiveBufferSize = -1;
private volatile int soReceiveBufferSize = -1;
private String localAddress;
private volatile String localAddress;
private DatagramSocket socket;
private volatile CountDownLatch ackLatch;
private Executor taskExecutor;
private volatile boolean ackThreadRunning;
private volatile Executor taskExecutor;
private volatile boolean taskExecutorSet;
private boolean taskExecutorSet;
private Expression socketExpression;
private EvaluationContext evaluationContext;
private volatile CountDownLatch ackLatch;
private volatile boolean ackThreadRunning;
/**
* Basic constructor; no reliability; no acknowledgment.
* @param host Destination host.
@@ -175,6 +175,7 @@ public class UnicastSendingMessageHandler extends
String ackHost,
int ackPort,
int ackTimeout) {
super(host, port);
this.destinationExpression = null;
setReliabilityAttributes(false, acknowledge, ackHost, ackPort,
@@ -198,6 +199,7 @@ public class UnicastSendingMessageHandler extends
String ackHost,
int ackPort,
int ackTimeout) {
super(host, port);
this.destinationExpression = null;
setReliabilityAttributes(lengthCheck, acknowledge, ackHost, ackPort,
@@ -206,6 +208,7 @@ public class UnicastSendingMessageHandler extends
protected final void setReliabilityAttributes(boolean lengthCheck,
boolean acknowledge, String ackHost, int ackPort, int ackTimeout) {
this.mapper.setLengthCheck(lengthCheck);
this.waitForAck = acknowledge;
this.mapper.setAcknowledge(acknowledge);
@@ -246,7 +249,7 @@ public class UnicastSendingMessageHandler extends
@Override
protected void doStop() {
this.closeSocketIfNeeded();
closeSocketIfNeeded();
if (!this.taskExecutorSet && this.taskExecutor != null) {
((ExecutorService) this.taskExecutor).shutdown();
this.taskExecutor = null;
@@ -305,8 +308,8 @@ public class UnicastSendingMessageHandler extends
try {
getSocket();
}
catch (IOException e) {
logger.error("Error creating socket", e);
catch (IOException ex) {
logger.error(ex, "Error creating socket");
}
this.ackLatch = new CountDownLatch(1);
this.taskExecutor.execute(this);
@@ -354,14 +357,10 @@ public class UnicastSendingMessageHandler extends
if (packet != null) {
packet.setSocketAddress(destinationAddress);
datagramSocket.send(packet);
if (logger.isDebugEnabled()) {
logger.debug("Sent packet for message " + message + " to " + packet.getSocketAddress());
}
logger.debug(() -> "Sent packet for message " + message + " to " + packet.getSocketAddress());
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Mapper created no packet for message " + message);
}
logger.debug(() -> "Mapper created no packet for message " + message);
}
}
@@ -387,9 +386,7 @@ public class UnicastSendingMessageHandler extends
if (this.soReceiveBufferSize > 0) {
this.socket.setReceiveBufferSize(this.soReceiveBufferSize);
}
if (logger.isDebugEnabled()) {
logger.debug("Listening for acks on port: " + getAckPort());
}
logger.debug(() -> "Listening for acks on port: " + getAckPort());
updateAckAddress();
}
else {
@@ -401,7 +398,7 @@ public class UnicastSendingMessageHandler extends
}
protected void updateAckAddress() {
this.mapper.setAckAddress(this.ackHost + ":" + getAckPort());
this.mapper.setAckAddress(this.ackHost + ':' + getAckPort());
}
/**
@@ -490,11 +487,13 @@ public class UnicastSendingMessageHandler extends
}
protected void setSocketAttributes(DatagramSocket socket) throws SocketException {
if (this.getSoTimeout() >= 0) {
socket.setSoTimeout(this.getSoTimeout());
int soTimeout = getSoTimeout();
if (soTimeout >= 0) {
socket.setSoTimeout(soTimeout);
}
if (this.getSoSendBufferSize() > 0) {
socket.setSendBufferSize(this.getSoSendBufferSize());
int soSendBufferSize = getSoSendBufferSize();
if (soSendBufferSize > 0) {
socket.setSendBufferSize(soSendBufferSize);
}
}
@@ -508,20 +507,18 @@ public class UnicastSendingMessageHandler extends
this.ackLatch.countDown();
DatagramPacket ackPack = new DatagramPacket(new byte[100], 100);
while (true) {
this.getSocket().receive(ackPack);
getSocket().receive(ackPack);
String id = new String(ackPack.getData(), ackPack.getOffset(), ackPack.getLength());
if (logger.isDebugEnabled()) {
logger.debug("Received ack for " + id + " from " + ackPack.getAddress().getHostAddress());
}
logger.debug(() -> "Received ack for " + id + " from " + ackPack.getAddress().getHostAddress());
CountDownLatch latch = this.ackControl.get(id);
if (latch != null) {
latch.countDown();
}
}
}
catch (IOException e) {
catch (IOException ex) {
if (this.socket != null && !this.socket.isClosed()) {
logger.error("Error on UDP Acknowledge thread: " + e.getMessage());
logger.error(() -> "Error on UDP Acknowledge thread: " + ex.getMessage());
}
}
finally {

View File

@@ -49,6 +49,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.junit.jupiter.api.Test;
@@ -62,6 +63,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.ip.IpHeaders;
@@ -725,7 +727,7 @@ public class CachingClientConnectionFactoryTests {
gate.setOutputChannel(outputChannel);
gate.setBeanFactory(mock(BeanFactory.class));
gate.afterPropertiesSet();
Log logger = spy(TestUtils.getPropertyValue(gate, "logger", Log.class));
LogAccessor logger = spy(TestUtils.getPropertyValue(gate, "logger", LogAccessor.class));
new DirectFieldAccessor(gate).setPropertyValue("logger", logger);
when(logger.isDebugEnabled()).thenReturn(true);
doAnswer(new Answer<Void>() {
@@ -735,7 +737,7 @@ public class CachingClientConnectionFactoryTests {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
invocation.callRealMethod();
String log = invocation.getArgument(0);
String log = ((Supplier<String>) invocation.getArgument(0)).get();
if (log.startsWith("Response")) {
new SimpleAsyncTaskExecutor()
.execute(() -> gate.handleMessage(new GenericMessage<>("bar")));
@@ -747,7 +749,7 @@ public class CachingClientConnectionFactoryTests {
}
return null;
}
}).when(logger).debug(anyString());
}).when(logger).debug(any(Supplier.class));
gate.start();
gate.handleMessage(new GenericMessage<>("foo"));
Message<byte[]> result = (Message<byte[]>) outputChannel.receive(10000);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,14 +40,14 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.net.ServerSocketFactory;
import org.apache.commons.logging.Log;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.serializer.Serializer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.IpHeaders;
@@ -74,7 +74,7 @@ public class ConnectionEventTests {
@Test
public void testConnectionEvents() throws Exception {
Socket socket = mock(Socket.class);
final List<TcpConnectionEvent> theEvent = new ArrayList<TcpConnectionEvent>();
final List<TcpConnectionEvent> theEvent = new ArrayList<>();
TcpNetConnection conn = new TcpNetConnection(socket, false, false, new ApplicationEventPublisher() {
@Override
@@ -99,7 +99,7 @@ public class ConnectionEventTests {
conn.setMapper(new TcpMessageMapper());
conn.setSerializer(serializer);
try {
conn.send(new GenericMessage<String>("bar"));
conn.send(new GenericMessage<>("bar"));
fail("Expected exception");
}
catch (Exception e) {
@@ -142,7 +142,7 @@ public class ConnectionEventTests {
}
};
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<ApplicationEvent>();
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<>();
scf.setApplicationEventPublisher(new ApplicationEventPublisher() {
@Override
@@ -182,7 +182,7 @@ public class ConnectionEventTests {
public void run() {
}
};
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<ApplicationEvent>();
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<>();
scf.setApplicationEventPublisher(new ApplicationEventPublisher() {
@Override
@@ -218,7 +218,7 @@ public class ConnectionEventTests {
AbstractClientConnectionFactory ccf = new AbstractClientConnectionFactory("localhost", 0) {
};
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<ApplicationEvent>();
final AtomicReference<ApplicationEvent> theEvent = new AtomicReference<>();
ccf.setApplicationEventPublisher(new ApplicationEventPublisher() {
@Override
@@ -246,7 +246,7 @@ public class ConnectionEventTests {
assertThat(messagingException.getFailedMessage()).isSameAs(message);
assertThat(messagingException.getMessage()).isEqualTo("Cannot correlate response - no pending reply for bar");
message = new GenericMessage<String>("foo");
message = new GenericMessage<>("foo");
gw.onMessage(message);
assertThat(theEvent.get()).isNotNull();
event = (TcpConnectionFailedCorrelationEvent) theEvent.get();
@@ -261,8 +261,7 @@ public class ConnectionEventTests {
private void testServerExceptionGuts(AbstractServerConnectionFactory factory) throws Exception {
ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
factory.setPort(ss.getLocalPort());
final AtomicReference<TcpConnectionServerExceptionEvent> theEvent =
new AtomicReference<TcpConnectionServerExceptionEvent>();
final AtomicReference<TcpConnectionServerExceptionEvent> theEvent = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
factory.setApplicationEventPublisher(new ApplicationEventPublisher() {
@@ -280,8 +279,8 @@ public class ConnectionEventTests {
});
factory.setBeanName("sf");
factory.registerListener(message -> false);
Log logger = spy(TestUtils.getPropertyValue(factory, "logger", Log.class));
doNothing().when(logger).error(anyString(), any(Throwable.class));
LogAccessor logger = spy(TestUtils.getPropertyValue(factory, "logger", LogAccessor.class));
doNothing().when(logger).error(any(Throwable.class), anyString());
new DirectFieldAccessor(factory).setPropertyValue("logger", logger);
factory.start();
@@ -293,7 +292,7 @@ public class ConnectionEventTests {
ArgumentCaptor<String> reasonCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Throwable> throwableCaptor = ArgumentCaptor.forClass(Throwable.class);
verify(logger).error(reasonCaptor.capture(), throwableCaptor.capture());
verify(logger).error(throwableCaptor.capture(), reasonCaptor.capture());
assertThat(reasonCaptor.getValue()).startsWith("Error on Server");
assertThat(reasonCaptor.getValue()).endsWith("; port = " + factory.getPort());
assertThat(throwableCaptor.getValue()).isInstanceOf(BindException.class);
@@ -316,7 +315,7 @@ public class ConnectionEventTests {
};
final AtomicReference<ApplicationEvent> failEvent = new AtomicReference<ApplicationEvent>();
final AtomicReference<ApplicationEvent> failEvent = new AtomicReference<>();
ccf.setApplicationEventPublisher(new ApplicationEventPublisher() {
@Override

View File

@@ -21,7 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.fail;
import static org.awaitility.Awaitility.await;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -50,6 +51,8 @@ import org.mockito.ArgumentCaptor;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.log.LogMessage;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.channel.QueueChannel;
@@ -199,12 +202,14 @@ public class ConnectionFactoryTests {
private void testEarlyClose(final AbstractServerConnectionFactory factory, String property,
String message) throws Exception {
factory.setApplicationEventPublisher(mock(ApplicationEventPublisher.class));
factory.setBeanName("foo");
factory.registerListener(mock(TcpListener.class));
factory.afterPropertiesSet();
Log logger = spy(TestUtils.getPropertyValue(factory, "logger", Log.class));
new DirectFieldAccessor(factory).setPropertyValue("logger", logger);
LogAccessor logAccessor = TestUtils.getPropertyValue(factory, "logger", LogAccessor.class);
Log logger = spy(logAccessor.getLog());
new DirectFieldAccessor(logAccessor).setPropertyValue("log", logger);
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final CountDownLatch latch3 = new CountDownLatch(1);
@@ -215,11 +220,11 @@ public class ConnectionFactoryTests {
// wait until the stop nulls the channel
latch2.await(10, TimeUnit.SECONDS);
return null;
}).when(logger).info(contains("Listening"));
}).when(logger).info(argThat(logMessage -> logMessage.toString().contains("Listening")));
doAnswer(invocation -> {
latch3.countDown();
return null;
}).when(logger).debug(contains(message));
}).when(logger).debug(argThat(logMessage -> logMessage.toString().contains(message)));
factory.start();
assertThat(latch1.await(10, TimeUnit.SECONDS)).as("missing info log").isTrue();
// stop on a different thread because it waits for the executor
@@ -232,9 +237,9 @@ public class ConnectionFactoryTests {
latch2.countDown();
assertThat(latch3.await(10, TimeUnit.SECONDS)).as("missing debug log").isTrue();
String expected = "bean 'foo', port=" + factory.getPort() + message;
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<LogMessage> captor = ArgumentCaptor.forClass(LogMessage.class);
verify(logger, atLeast(1)).debug(captor.capture());
assertThat(captor.getAllValues()).contains(expected);
assertThat(captor.getAllValues().stream().map(Object::toString).collect(Collectors.toList())).contains(expected);
factory.stop();
}
@@ -315,7 +320,7 @@ public class ConnectionFactoryTests {
gateway.start();
if (fail) {
assertThatExceptionOfType(MessagingException.class).isThrownBy(() ->
gateway.handleMessage(new GenericMessage<>("test1")))
gateway.handleMessage(new GenericMessage<>("test1")))
.withMessageContaining("Connection test failed for");
}
else {