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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user