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:
@@ -494,8 +494,8 @@ public abstract class AbstractAmqpOutboundEndpoint extends AbstractReplyProducin
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
logger.error("Failed to eagerly establish the connection.", e);
|
||||
catch (RuntimeException ex) {
|
||||
logger.error(ex, "Failed to eagerly establish the connection.");
|
||||
}
|
||||
}
|
||||
doStart();
|
||||
@@ -659,9 +659,7 @@ public abstract class AbstractAmqpOutboundEndpoint extends AbstractReplyProducin
|
||||
protected void handleConfirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||
CorrelationDataWrapper wrapper = (CorrelationDataWrapper) correlationData;
|
||||
if (correlationData == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No correlation data provided for ack: " + ack + " cause:" + cause);
|
||||
}
|
||||
logger.debug(() -> "No correlation data provided for ack: " + ack + " cause:" + cause);
|
||||
return;
|
||||
}
|
||||
Object userCorrelationData = wrapper.getUserData();
|
||||
@@ -675,11 +673,8 @@ public abstract class AbstractAmqpOutboundEndpoint extends AbstractReplyProducin
|
||||
sendOutput(buildConfirmMessage(ack, cause, wrapper, userCorrelationData), nackChannel, true);
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Nowhere to send publisher confirm "
|
||||
+ (ack ? "ack" : "nack") + " for "
|
||||
+ userCorrelationData);
|
||||
}
|
||||
logger.debug(() -> "Nowhere to send publisher confirm " + (ack ? "ack" : "nack") + " for "
|
||||
+ userCorrelationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class AsyncAmqpOutboundGateway extends AbstractAmqpOutboundEndpoint {
|
||||
new MessagingException(replyMessageBuilder.build(), exceptionToLogAndSend);
|
||||
}
|
||||
}
|
||||
logger.error("Failed to send async reply: " + result.toString(), exceptionToLogAndSend);
|
||||
logger.error(exceptionToLogAndSend, () -> "Failed to send async reply: " + result.toString());
|
||||
sendErrorMessage(this.requestMessage, exceptionToLogAndSend);
|
||||
}
|
||||
}
|
||||
@@ -139,9 +139,7 @@ public class AsyncAmqpOutboundGateway extends AbstractAmqpOutboundEndpoint {
|
||||
new ReplyRequiredException(this.requestMessage, "Timeout on async request/reply", ex);
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reply not required and async timeout for " + this.requestMessage);
|
||||
}
|
||||
logger.debug(() -> "Reply not required and async timeout for " + this.requestMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -36,9 +36,7 @@ import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.amqp.core.MessageDeliveryMode;
|
||||
@@ -56,6 +54,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint;
|
||||
import org.springframework.integration.amqp.support.AmqpHeaderMapper;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
@@ -70,8 +69,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.rabbitmq.client.AMQP.BasicProperties;
|
||||
@@ -83,10 +81,10 @@ import com.rabbitmq.client.Channel;
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class AmqpOutboundChannelAdapterParserTests {
|
||||
|
||||
@@ -326,19 +324,19 @@ public class AmqpOutboundChannelAdapterParserTests {
|
||||
doThrow(toBeThrown).when(connectionFactory).createConnection();
|
||||
when(amqpTemplate.getConnectionFactory()).thenReturn(connectionFactory);
|
||||
AmqpOutboundEndpoint handler = new AmqpOutboundEndpoint(amqpTemplate);
|
||||
Log logger = spy(TestUtils.getPropertyValue(handler, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(handler, "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(handler).setPropertyValue("logger", logger);
|
||||
doNothing().when(logger).error("Failed to eagerly establish the connection.", toBeThrown);
|
||||
doNothing().when(logger).error(toBeThrown, "Failed to eagerly establish the connection.");
|
||||
ApplicationContext context = mock(ApplicationContext.class);
|
||||
handler.setApplicationContext(context);
|
||||
handler.setBeanFactory(context);
|
||||
handler.afterPropertiesSet();
|
||||
handler.start();
|
||||
handler.stop();
|
||||
verify(logger, never()).error(anyString(), any(RuntimeException.class));
|
||||
verify(logger, never()).error(any(RuntimeException.class), anyString());
|
||||
handler.setLazyConnect(false);
|
||||
handler.start();
|
||||
verify(logger).error("Failed to eagerly establish the connection.", toBeThrown);
|
||||
verify(logger).error(toBeThrown, "Failed to eagerly establish the connection.");
|
||||
handler.stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -506,9 +506,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
Assert.state(correlationKey != null,
|
||||
"Null correlation not allowed. Maybe the CorrelationStrategy is failing?");
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Handling message with correlationKey [" + correlationKey + "]: " + message);
|
||||
}
|
||||
this.logger.debug(() -> "Handling message with correlationKey [" + correlationKey + "]: " + message);
|
||||
|
||||
UUID groupIdUuid = UUIDConverter.getUUID(correlationKey);
|
||||
Lock lock = this.lockRegistry.obtain(groupIdUuid.toString());
|
||||
@@ -540,9 +538,8 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
}
|
||||
|
||||
if (!messageGroup.isComplete() && messageGroup.canAdd(message)) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
this.logger.trace("Adding message to group [ " + messageGroup + "]");
|
||||
}
|
||||
MessageGroup messageGroupToLog = messageGroup;
|
||||
this.logger.trace(() -> "Adding message to group [ " + messageGroupToLog + "]");
|
||||
messageGroup = store(correlationKey, message);
|
||||
|
||||
if (this.releaseStrategy.canRelease(messageGroup)) {
|
||||
@@ -575,9 +572,9 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
ScheduledFuture<?> scheduledFuture = this.expireGroupScheduledFutures.remove(groupIdUuid);
|
||||
if (scheduledFuture != null) {
|
||||
boolean canceled = scheduledFuture.cancel(mayInterruptIfRunning);
|
||||
if (canceled && this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Cancel 'ScheduledFuture' for MessageGroup with Correlation Key [ "
|
||||
+ correlationKey + "].");
|
||||
if (canceled) {
|
||||
this.logger.debug(() ->
|
||||
"Cancel 'ScheduledFuture' for MessageGroup with Correlation Key [ " + correlationKey + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -607,9 +604,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
groupNow.getLastModified()
|
||||
<= (System.currentTimeMillis() - this.minimumTimeoutForEmptyGroups);
|
||||
if (removeGroup) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Removing empty group: " + groupUuid);
|
||||
}
|
||||
this.logger.debug(() -> "Removing empty group: " + groupUuid);
|
||||
remove(messageGroup);
|
||||
}
|
||||
}
|
||||
@@ -619,18 +614,14 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Thread was interrupted while trying to obtain lock."
|
||||
+ "Rescheduling empty MessageGroup [ " + groupId + "] for removal.");
|
||||
}
|
||||
this.logger.debug(() -> "Thread was interrupted while trying to obtain lock."
|
||||
+ "Rescheduling empty MessageGroup [ " + groupId + "] for removal.");
|
||||
removeEmptyGroupAfterTimeout(messageGroup, timeout);
|
||||
}
|
||||
|
||||
}, new Date(System.currentTimeMillis() + timeout));
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Schedule empty MessageGroup [ " + groupId + "] for removal.");
|
||||
}
|
||||
this.logger.debug(() -> "Schedule empty MessageGroup [ " + groupId + "] for removal.");
|
||||
this.expireGroupScheduledFutures.put(groupUuid, scheduledFuture);
|
||||
}
|
||||
|
||||
@@ -651,18 +642,17 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
try {
|
||||
processForceRelease(groupId, timestamp, lastModified);
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
catch (MessageDeliveryException ex) {
|
||||
if (AbstractCorrelatingMessageHandler.this.logger.isWarnEnabled()) {
|
||||
AbstractCorrelatingMessageHandler.this.logger.warn("The MessageGroup ["
|
||||
+ groupId + "] is rescheduled by the reason of:", e);
|
||||
AbstractCorrelatingMessageHandler.this.logger.warn(ex,
|
||||
() -> "The MessageGroup [" + groupId
|
||||
+ "] is rescheduled by the reason of:");
|
||||
}
|
||||
scheduleGroupToForceComplete(groupId);
|
||||
}
|
||||
}, new Date(System.currentTimeMillis() + groupTimeout));
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Schedule MessageGroup [ " + messageGroup + "] to 'forceComplete'.");
|
||||
}
|
||||
this.logger.debug(() -> "Schedule MessageGroup [ " + messageGroup + "] to 'forceComplete'.");
|
||||
this.expireGroupScheduledFutures.put(UUIDConverter.getUUID(groupId), scheduledFuture);
|
||||
}
|
||||
else {
|
||||
@@ -774,26 +764,22 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
*/
|
||||
removeGroup =
|
||||
lastModifiedNow <= (System.currentTimeMillis() - this.minimumTimeoutForEmptyGroups);
|
||||
if (removeGroup && this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Removing empty group: " + correlationKey);
|
||||
if (removeGroup) {
|
||||
this.logger.debug(() -> "Removing empty group: " + correlationKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeGroup = false;
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Group expiry candidate (" + correlationKey +
|
||||
") has changed - it may be reconsidered for a future expiration");
|
||||
}
|
||||
this.logger.debug(() -> "Group expiry candidate (" + correlationKey +
|
||||
") has changed - it may be reconsidered for a future expiration");
|
||||
}
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
removeGroup = false;
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Group expiry candidate (" + correlationKey +
|
||||
") has been affected by MessageDeliveryException - " +
|
||||
"it may be reconsidered for a future expiration one more time");
|
||||
}
|
||||
this.logger.debug(() -> "Group expiry candidate (" + correlationKey +
|
||||
") has been affected by MessageDeliveryException - " +
|
||||
"it may be reconsidered for a future expiration one more time");
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
@@ -832,22 +818,16 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
}
|
||||
|
||||
protected void expireGroup(Object correlationKey, MessageGroup group, Lock lock) {
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("Expiring MessageGroup with correlationKey[" + correlationKey + "]");
|
||||
}
|
||||
this.logger.info(() -> "Expiring MessageGroup with correlationKey[" + correlationKey + "]");
|
||||
if (this.sendPartialResultOnExpiry) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Prematurely releasing partially complete group with key ["
|
||||
+ correlationKey + "] to: " + getOutputChannel());
|
||||
}
|
||||
this.logger.debug(() -> "Prematurely releasing partially complete group with key ["
|
||||
+ correlationKey + "] to: " + getOutputChannel());
|
||||
completeGroup(correlationKey, group, lock);
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Discarding messages of partially complete group with key ["
|
||||
+ correlationKey + "] to: "
|
||||
+ (this.discardChannelName != null ? this.discardChannelName : this.discardChannel));
|
||||
}
|
||||
this.logger.debug(() -> "Discarding messages of partially complete group with key ["
|
||||
+ correlationKey + "] to: "
|
||||
+ (this.discardChannelName != null ? this.discardChannelName : this.discardChannel));
|
||||
if (this.releaseLockBeforeSend) {
|
||||
lock.unlock();
|
||||
}
|
||||
@@ -876,9 +856,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
Collection<Message<?>> partialSequence = null;
|
||||
Object result;
|
||||
try {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Completing group with correlationKey [" + correlationKey + "]");
|
||||
}
|
||||
this.logger.debug(() -> "Completing group with correlationKey [" + correlationKey + "]");
|
||||
|
||||
result = this.outputProcessor.processMessageGroup(group);
|
||||
if (result instanceof Collection<?>) {
|
||||
@@ -894,13 +872,13 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
else if (!(result instanceof Message<?>)) {
|
||||
messageBuilder =
|
||||
getMessageBuilderFactory()
|
||||
.withPayload(result)
|
||||
.copyHeaders(message.getHeaders());
|
||||
.withPayload(result)
|
||||
.copyHeaders(message.getHeaders());
|
||||
}
|
||||
else if (compareSequences((Message<?>) result, message)) {
|
||||
messageBuilder =
|
||||
getMessageBuilderFactory()
|
||||
.fromMessage((Message<?>) result);
|
||||
.fromMessage((Message<?>) result);
|
||||
}
|
||||
result = messageBuilder != null ? messageBuilder.popSequenceDetails() : result;
|
||||
}
|
||||
@@ -923,7 +901,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageP
|
||||
|
||||
protected void verifyResultCollectionConsistsOfMessages(Collection<?> elements) {
|
||||
Class<?> commonElementType = CollectionUtils.findCommonElementType(elements);
|
||||
Assert.isAssignable(Message.class, commonElementType,
|
||||
Assert.isAssignable(Message.class, commonElementType, () ->
|
||||
"The expected collection of Messages contains non-Message element: " + commonElementType);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ public abstract class AbstractExecutorChannel extends AbstractSubscribableChanne
|
||||
this.delegate.getMessageHandler(), ex);
|
||||
}
|
||||
catch (Throwable ex2) { //NOSONAR
|
||||
logger.error("Exception from afterMessageHandled in " + interceptor, ex2);
|
||||
logger.error(ex2, () -> "Exception from afterMessageHandled in " + interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.IntegrationPattern;
|
||||
import org.springframework.integration.IntegrationPatternType;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
@@ -68,7 +67,7 @@ import org.springframework.util.StringUtils;
|
||||
public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
implements MessageChannel, TrackableComponent, InterceptableChannel, IntegrationManagement, IntegrationPattern {
|
||||
|
||||
protected final ChannelInterceptorList interceptors = new ChannelInterceptorList(logger); // NOSONAR
|
||||
protected final ChannelInterceptorList interceptors = new ChannelInterceptorList(this.logger); // NOSONAR
|
||||
|
||||
private final Comparator<Object> orderComparator = new OrderComparator();
|
||||
|
||||
@@ -152,7 +151,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
*/
|
||||
@Override
|
||||
public void setInterceptors(List<ChannelInterceptor> interceptors) {
|
||||
Collections.sort(interceptors, this.orderComparator);
|
||||
interceptors.sort(this.orderComparator);
|
||||
this.interceptors.set(interceptors);
|
||||
}
|
||||
|
||||
@@ -270,7 +269,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
*/
|
||||
@Override
|
||||
public boolean send(Message<?> message) {
|
||||
return this.send(message, -1);
|
||||
return send(message, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,7 +300,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
SampleFacade sample = null;
|
||||
try {
|
||||
message = convertPayloadIfNecessary(message);
|
||||
boolean debugEnabled = this.loggingEnabled && logger.isDebugEnabled();
|
||||
boolean debugEnabled = this.loggingEnabled && this.logger.isDebugEnabled();
|
||||
if (debugEnabled) {
|
||||
logger.debug("preSend on channel '" + this + "', message: " + message);
|
||||
}
|
||||
@@ -338,7 +337,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
interceptorList.afterSendCompletion(message, this, sent, ex, interceptorStack);
|
||||
}
|
||||
throw IntegrationUtils.wrapInDeliveryExceptionIfNecessary(message,
|
||||
() -> "failed to send Message to channel '" + this.getComponentName() + "'", ex);
|
||||
() -> "failed to send Message to channel '" + getComponentName() + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +393,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new MessageDeliveryException(message, "Channel '" + this.getComponentName() +
|
||||
throw new MessageDeliveryException(message, "Channel '" + getComponentName() +
|
||||
"' expected one of the following data types [" +
|
||||
StringUtils.arrayToCommaDelimitedString(this.datatypes) +
|
||||
"], but received [" + message.getPayload().getClass() + "]");
|
||||
@@ -429,11 +428,11 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
|
||||
protected final List<ChannelInterceptor> interceptors = new CopyOnWriteArrayList<>(); // NOSONAR
|
||||
|
||||
private final Log logger;
|
||||
private final LogAccessor logger;
|
||||
|
||||
private int size;
|
||||
|
||||
public ChannelInterceptorList(Log logger) {
|
||||
public ChannelInterceptorList(LogAccessor logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@@ -469,10 +468,8 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
Message<?> previous = message;
|
||||
message = interceptor.preSend(message, channel);
|
||||
if (message == null) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug(interceptor.getClass().getSimpleName()
|
||||
+ " returned null from preSend, i.e. precluding the send.");
|
||||
}
|
||||
this.logger.debug(() -> interceptor.getClass().getSimpleName()
|
||||
+ " returned null from preSend, i.e. precluding the send.");
|
||||
afterSendCompletion(previous, channel, false, null, interceptorStack);
|
||||
return null;
|
||||
}
|
||||
@@ -499,7 +496,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
interceptor.afterSendCompletion(message, channel, sent, ex);
|
||||
}
|
||||
catch (Exception ex2) {
|
||||
this.logger.error("Exception from afterSendCompletion in " + interceptor, ex2);
|
||||
this.logger.error(ex2, () -> "Exception from afterSendCompletion in " + interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -535,14 +532,13 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
@Nullable Exception ex, @Nullable Deque<ChannelInterceptor> interceptorStack) {
|
||||
|
||||
if (interceptorStack != null) {
|
||||
for (Iterator<ChannelInterceptor> iterator = interceptorStack.descendingIterator(); iterator
|
||||
.hasNext(); ) {
|
||||
ChannelInterceptor interceptor = iterator.next();
|
||||
for (Iterator<ChannelInterceptor> iter = interceptorStack.descendingIterator(); iter.hasNext(); ) {
|
||||
ChannelInterceptor interceptor = iter.next();
|
||||
try {
|
||||
interceptor.afterReceiveCompletion(message, channel, ex);
|
||||
}
|
||||
catch (Exception ex2) {
|
||||
this.logger.error("Exception from afterReceiveCompletion in " + interceptor, ex2);
|
||||
this.logger.error(ex2, () -> "Exception from afterReceiveCompletion in " + interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class FluxMessageChannel extends AbstractMessageChannel
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn("Error during processing event: " + message, ex);
|
||||
logger.warn(ex, () -> "Error during processing event: " + message);
|
||||
}
|
||||
})
|
||||
.subscribe());
|
||||
|
||||
@@ -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.
|
||||
@@ -19,9 +19,6 @@ package org.springframework.integration.context;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -34,6 +31,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
@@ -77,7 +75,7 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
/**
|
||||
* Logger that is available to subclasses
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass()); // NOSONAR protected
|
||||
protected final LogAccessor logger = new LogAccessor(getClass()); // NOSONAR protected
|
||||
|
||||
private final ConversionService defaultConversionService = DefaultConversionService.getSharedInstance();
|
||||
|
||||
@@ -264,8 +262,8 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
public ConversionService getConversionService() {
|
||||
if (this.conversionService == null && this.beanFactory != null) {
|
||||
this.conversionService = IntegrationUtils.getConversionService(this.beanFactory);
|
||||
if (this.conversionService == null && this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Unable to attempt conversion of Message payload types. Component '" +
|
||||
if (this.conversionService == null) {
|
||||
this.logger.debug(() -> "Unable to attempt conversion of Message payload types. Component '" +
|
||||
getComponentName() + "' has no explicit ConversionService reference, " +
|
||||
"and there is no 'integrationConversionService' bean within the context.");
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ public abstract class MessageProducerSupport extends AbstractEndpoint implements
|
||||
sendMessage(message);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("Error sending a message: " + message, ex);
|
||||
logger.error(ex, () -> "Error sending a message: " + message);
|
||||
}
|
||||
})
|
||||
.subscribe();
|
||||
|
||||
@@ -184,11 +184,9 @@ public class PollingConsumer extends AbstractPollingEndpoint implements Integrat
|
||||
if (interceptor instanceof ExecutorChannelInterceptor) {
|
||||
ExecutorChannelInterceptor executorInterceptor = (ExecutorChannelInterceptor) interceptor;
|
||||
theMessage = executorInterceptor.beforeHandle(theMessage, this.inputChannel, this.handler);
|
||||
if (message == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(executorInterceptor.getClass().getSimpleName()
|
||||
+ " returned null from beforeHandle, i.e. precluding the send.");
|
||||
}
|
||||
if (theMessage == null) {
|
||||
logger.debug(() -> executorInterceptor.getClass().getSimpleName()
|
||||
+ " returned null from beforeHandle, i.e. precluding the send.");
|
||||
triggerAfterMessageHandled(null, null, interceptorStack);
|
||||
return null;
|
||||
}
|
||||
@@ -200,6 +198,7 @@ public class PollingConsumer extends AbstractPollingEndpoint implements Integrat
|
||||
|
||||
private void triggerAfterMessageHandled(Message<?> message, Exception ex,
|
||||
Deque<ExecutorChannelInterceptor> interceptorStack) {
|
||||
|
||||
Iterator<ExecutorChannelInterceptor> iterator = interceptorStack.descendingIterator();
|
||||
while (iterator.hasNext()) {
|
||||
ExecutorChannelInterceptor interceptor = iterator.next();
|
||||
@@ -207,7 +206,7 @@ public class PollingConsumer extends AbstractPollingEndpoint implements Integrat
|
||||
interceptor.afterMessageHandled(message, this.inputChannel, this.handler, ex);
|
||||
}
|
||||
catch (Throwable ex2) { //NOSONAR
|
||||
logger.error("Exception from afterMessageHandled in " + interceptor, ex2);
|
||||
logger.error(ex2, () -> "Exception from afterMessageHandled in " + interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,8 +481,8 @@ public abstract class AbstractMessageProducingHandler extends AbstractMessageHan
|
||||
result = new MessageHandlingException(requestMessage, ex);
|
||||
}
|
||||
if (errorChannel == null) {
|
||||
logger.error("Async exception received and no 'errorChannel' header exists and no default "
|
||||
+ "'errorChannel' found", result);
|
||||
logger.error(result,
|
||||
"Async exception received and no 'errorChannel' header exists and no default 'errorChannel' found");
|
||||
}
|
||||
else {
|
||||
try {
|
||||
@@ -492,7 +492,7 @@ public abstract class AbstractMessageProducingHandler extends AbstractMessageHan
|
||||
Exception exceptionToLog =
|
||||
IntegrationUtils.wrapInHandlingExceptionIfNecessary(requestMessage,
|
||||
() -> "failed to send error message in the [" + this + ']', e);
|
||||
logger.error("Failed to send async reply", exceptionToLog);
|
||||
logger.error(exceptionToLog, "Failed to send async reply");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,7 +538,7 @@ public abstract class AbstractMessageProducingHandler extends AbstractMessageHan
|
||||
exceptionToLogAndSend = new MessagingException(replyMessage, exceptionToLogAndSend);
|
||||
}
|
||||
}
|
||||
logger.error("Failed to send async reply: " + result.toString(), exceptionToLogAndSend);
|
||||
logger.error(exceptionToLogAndSend, () -> "Failed to send async reply: " + result.toString());
|
||||
onFailure(exceptionToLogAndSend);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
* Copyright 2019-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.
|
||||
@@ -49,8 +49,8 @@ public abstract class AbstractReactiveMessageHandler extends MessageHandlerSuppo
|
||||
messageToUse = message;
|
||||
}
|
||||
return handleMessageInternal(messageToUse)
|
||||
.doOnError(e -> this.logger.error(
|
||||
"An error occurred in message handler [" + this + "] on message [" + messageToUse + "]", e));
|
||||
.doOnError((ex) -> this.logger.error(ex, () ->
|
||||
"An error occurred in message handler [" + this + "] on message [" + messageToUse + "]"));
|
||||
}
|
||||
|
||||
protected abstract Mono<Void> handleMessageInternal(Message<?> message);
|
||||
|
||||
@@ -298,8 +298,8 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
else {
|
||||
Assert.isInstanceOf(MessageStore.class, this.messageStore);
|
||||
}
|
||||
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
|
||||
this.releaseHandler = this.createReleaseMessageTask();
|
||||
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
|
||||
this.releaseHandler = createReleaseMessageTask();
|
||||
}
|
||||
|
||||
private MessageHandler createReleaseMessageTask() {
|
||||
@@ -343,7 +343,9 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
}
|
||||
|
||||
// no delay
|
||||
return delayed ? ((DelayedMessageWrapper) requestMessage.getPayload()).getOriginal() : requestMessage;
|
||||
return delayed
|
||||
? ((DelayedMessageWrapper) requestMessage.getPayload()).getOriginal()
|
||||
: requestMessage;
|
||||
}
|
||||
|
||||
private long determineDelayForMessage(Message<?> message) {
|
||||
@@ -365,15 +367,18 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
Object delayValue = null;
|
||||
try {
|
||||
delayValue = this.delayExpression.getValue(this.evaluationContext,
|
||||
delayedMessageWrapper != null ? delayedMessageWrapper.getOriginal() : message);
|
||||
delayedMessageWrapper != null
|
||||
? delayedMessageWrapper.getOriginal()
|
||||
: message);
|
||||
}
|
||||
catch (EvaluationException e) {
|
||||
delayValueException = e;
|
||||
}
|
||||
if (delayValue instanceof Date) {
|
||||
long current = delayedMessageWrapper != null
|
||||
? delayedMessageWrapper.getRequestDate()
|
||||
: System.currentTimeMillis();
|
||||
long current =
|
||||
delayedMessageWrapper != null
|
||||
? delayedMessageWrapper.getRequestDate()
|
||||
: System.currentTimeMillis();
|
||||
delay = ((Date) delayValue).getTime() - current;
|
||||
}
|
||||
else if (delayValue != null) {
|
||||
@@ -392,22 +397,19 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
|
||||
private void handleDelayValueException(Exception delayValueException) {
|
||||
if (this.ignoreExpressionFailures) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to get delay value from 'delayExpression': " +
|
||||
delayValueException.getMessage() +
|
||||
". Will fall back to default delay: " + this.defaultDelay);
|
||||
}
|
||||
logger.debug(() -> "Failed to get delay value from 'delayExpression': " +
|
||||
delayValueException.getMessage() +
|
||||
". Will fall back to default delay: " + this.defaultDelay);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Error occurred during 'delay' value determination",
|
||||
delayValueException);
|
||||
throw new IllegalStateException("Error occurred during 'delay' value determination", delayValueException);
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseMessageAfterDelay(final Message<?> message, long delay) {
|
||||
Message<?> delayedMessage = message;
|
||||
|
||||
DelayedMessageWrapper messageWrapper = null;
|
||||
DelayedMessageWrapper messageWrapper;
|
||||
if (message.getPayload() instanceof DelayedMessageWrapper) {
|
||||
messageWrapper = (DelayedMessageWrapper) message.getPayload();
|
||||
}
|
||||
@@ -445,10 +447,8 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
Message<?> theMessage = ((MessageStore) this.messageStore).getMessage(messageId);
|
||||
|
||||
if (theMessage == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No message in the Message Store for id: " + messageId +
|
||||
". Likely another instance has already released it.");
|
||||
}
|
||||
logger.debug(() -> "No message in the Message Store for id: " + messageId +
|
||||
". Likely another instance has already released it.");
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
@@ -471,9 +471,7 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
message);
|
||||
try {
|
||||
if (!(getErrorChannel().send(errorMessage))) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Failed to send error message: " + errorMessage);
|
||||
}
|
||||
this.logger.debug(() -> "Failed to send error message: " + errorMessage);
|
||||
rescheduleForRetry(message, identity);
|
||||
}
|
||||
else {
|
||||
@@ -481,16 +479,12 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
}
|
||||
}
|
||||
catch (Exception e1) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
logger.debug("Error flow threw an exception for message: " + message, e1);
|
||||
}
|
||||
logger.debug(e1, () -> "Error flow threw an exception for message: " + message);
|
||||
rescheduleForRetry(message, identity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
logger.debug("Release flow threw an exception for message: " + message, e);
|
||||
}
|
||||
logger.debug(e, () -> "Release flow threw an exception for message: " + message);
|
||||
if (!rescheduleForRetry(message, identity)) {
|
||||
throw e; // there might be an error handler on the scheduler
|
||||
}
|
||||
@@ -500,7 +494,7 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
|
||||
private boolean rescheduleForRetry(Message<?> message, String identity) {
|
||||
if (this.deliveries.get(identity).incrementAndGet() >= this.maxAttempts) {
|
||||
this.logger.error("Discarding; maximum release attempts reached for: " + message);
|
||||
this.logger.error(() -> "Discarding; maximum release attempts reached for: " + message);
|
||||
this.deliveries.remove(identity);
|
||||
return false;
|
||||
}
|
||||
@@ -530,8 +524,8 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
}
|
||||
handleMessageInternal(message);
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug("No message in the Message Store to release: " + message +
|
||||
else {
|
||||
logger.debug(() -> "No message in the Message Store to release: " + message +
|
||||
". Likely another instance has already released it.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@ package org.springframework.integration.handler;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.dispatcher.AggregateMessageDeliveryException;
|
||||
@@ -65,7 +65,7 @@ public class LoggingHandler extends AbstractMessageHandler {
|
||||
|
||||
private boolean shouldLogFullMessageSet;
|
||||
|
||||
private Log messageLogger = this.logger;
|
||||
private LogAccessor messageLogger = this.logger;
|
||||
|
||||
/**
|
||||
* Create a LoggingHandler with the given log level (case-insensitive).
|
||||
@@ -146,7 +146,7 @@ public class LoggingHandler extends AbstractMessageHandler {
|
||||
|
||||
public void setLoggerName(String loggerName) {
|
||||
Assert.hasText(loggerName, "loggerName must not be empty");
|
||||
this.messageLogger = LogFactory.getLog(loggerName);
|
||||
this.messageLogger = new LogAccessor(loggerName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,38 +174,27 @@ public class LoggingHandler extends AbstractMessageHandler {
|
||||
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
|
||||
}
|
||||
|
||||
@Override // NOSONAR
|
||||
@Override
|
||||
protected void handleMessageInternal(Message<?> message) {
|
||||
Supplier<CharSequence> logMessage = () -> createLogMessage(message);
|
||||
switch (this.level) {
|
||||
case FATAL:
|
||||
if (this.messageLogger.isFatalEnabled()) {
|
||||
this.messageLogger.fatal(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.fatal(logMessage);
|
||||
break;
|
||||
case ERROR:
|
||||
if (this.messageLogger.isErrorEnabled()) {
|
||||
this.messageLogger.error(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.error(logMessage);
|
||||
break;
|
||||
case WARN:
|
||||
if (this.messageLogger.isWarnEnabled()) {
|
||||
this.messageLogger.warn(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.warn(logMessage);
|
||||
break;
|
||||
case INFO:
|
||||
if (this.messageLogger.isInfoEnabled()) {
|
||||
this.messageLogger.info(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.info(logMessage);
|
||||
break;
|
||||
case DEBUG:
|
||||
if (this.messageLogger.isDebugEnabled()) {
|
||||
this.messageLogger.debug(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.debug(logMessage);
|
||||
break;
|
||||
case TRACE:
|
||||
if (this.messageLogger.isTraceEnabled()) {
|
||||
this.messageLogger.trace(createLogMessage(message));
|
||||
}
|
||||
this.messageLogger.trace(logMessage);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Level '" + this.level + "' is not supported");
|
||||
@@ -213,11 +202,11 @@ public class LoggingHandler extends AbstractMessageHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object createLogMessage(Message<?> message) {
|
||||
private String createLogMessage(Message<?> message) {
|
||||
Object logMessage = this.expression.getValue(this.evaluationContext, message);
|
||||
return logMessage instanceof Throwable
|
||||
? createLogMessage((Throwable) logMessage)
|
||||
: logMessage;
|
||||
: Objects.toString(logMessage);
|
||||
}
|
||||
|
||||
private String createLogMessage(Throwable throwable) {
|
||||
|
||||
@@ -172,7 +172,6 @@ public class JsonToObjectTransformer extends AbstractTransformer implements Bean
|
||||
Object result;
|
||||
try {
|
||||
result = this.jsonObjectMapper.fromJson(message.getPayload(), valueType);
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
@@ -197,8 +196,8 @@ public class JsonToObjectTransformer extends AbstractTransformer implements Bean
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (ex.getCause() instanceof ClassNotFoundException) {
|
||||
logger.debug("Cannot build a ResolvableType from the request message '" + message +
|
||||
"' evaluating expression '" + this.valueTypeExpression.getExpressionString() + "'", ex);
|
||||
logger.debug(ex, () -> "Cannot build a ResolvableType from the request message '" + message +
|
||||
"' evaluating expression '" + this.valueTypeExpression.getExpressionString() + "'");
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -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.
|
||||
@@ -213,11 +213,11 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler imple
|
||||
this.messagingTemplate.send(channel, messageToSend);
|
||||
return true;
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
catch (MessagingException ex) {
|
||||
if (!this.ignoreSendFailures) {
|
||||
throw e;
|
||||
throw ex;
|
||||
}
|
||||
this.logger.debug("Send failure ignored", e);
|
||||
this.logger.debug(ex, "Send failure ignored");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -136,33 +136,27 @@ public class ExpressionEvaluatingTransactionSynchronizationProcessor extends Int
|
||||
Message<?> message = holder.getMessage();
|
||||
if (message != null) {
|
||||
if (expression != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Evaluating " + expressionType + " expression: '" + expression.getExpressionString()
|
||||
+ "' on " + message);
|
||||
}
|
||||
logger.debug(() -> "Evaluating " + expressionType + " expression: '" + expression.getExpressionString()
|
||||
+ "' on " + message);
|
||||
EvaluationContext evaluationContextToUse = prepareEvaluationContextToUse(holder);
|
||||
Object value = expression.getValue(evaluationContextToUse, message);
|
||||
if (value != null && messageChannel != null) {
|
||||
sendMessageForExpressionResult(value, message.getHeaders(), messageChannel, expressionType);
|
||||
}
|
||||
else {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Expression evaluation returned null");
|
||||
}
|
||||
logger.trace("Expression evaluation returned null");
|
||||
}
|
||||
}
|
||||
else if (messageChannel != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Sending received message to " + messageChannel + " as part of '" +
|
||||
expressionType + "' transaction synchronization");
|
||||
}
|
||||
logger.debug(() -> "Sending received message to " + messageChannel + " as part of '" +
|
||||
expressionType + "' transaction synchronization");
|
||||
try {
|
||||
// rollback will be initiated if any of the previous sync operations fail (e.g., beforeCommit)
|
||||
// this means that this method will be called without explicit configuration thus no channel
|
||||
sendMessage(messageChannel, message);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Failed to send " + message, e);
|
||||
catch (Exception ex) {
|
||||
logger.error(ex, () -> "Failed to send " + message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -172,12 +166,9 @@ public class ExpressionEvaluatingTransactionSynchronizationProcessor extends Int
|
||||
private void sendMessageForExpressionResult(Object value, Map<String, ?> headers,
|
||||
MessageChannel messageChannel, String expressionType) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Sending expression result message to " + messageChannel + " " +
|
||||
"as part of '" + expressionType + "' transaction synchronization");
|
||||
}
|
||||
Message<?> spelResultMessage = null;
|
||||
try {
|
||||
logger.debug(() -> "Sending expression result message to " + messageChannel + " " +
|
||||
"as part of '" + expressionType + "' transaction synchronization");
|
||||
Message<?> spelResultMessage;
|
||||
if (value instanceof Message<?>) {
|
||||
spelResultMessage = (Message<?>) value;
|
||||
}
|
||||
@@ -188,11 +179,11 @@ public class ExpressionEvaluatingTransactionSynchronizationProcessor extends Int
|
||||
.copyHeaders(headers)
|
||||
.build();
|
||||
}
|
||||
|
||||
try {
|
||||
sendMessage(messageChannel, spelResultMessage);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Failed to send " + expressionType + " evaluation result " + spelResultMessage, e);
|
||||
catch (Exception ex) {
|
||||
logger.error(ex, () -> "Failed to send " + expressionType + " evaluation result " + spelResultMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,9 +86,7 @@ public class SyslogToMapTransformer extends AbstractPayloadTransformer<Object, M
|
||||
parseMatcherToMap(payload, matcher, map);
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not decode: " + payload);
|
||||
}
|
||||
logger.debug(() -> "Could not decode: " + payload);
|
||||
map.put(UNDECODED, payload);
|
||||
}
|
||||
return map;
|
||||
@@ -111,10 +109,8 @@ public class SyslogToMapTransformer extends AbstractPayloadTransformer<Object, M
|
||||
}
|
||||
map.put(MESSAGE, matcher.group(5)); // NOSONAR
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not decode: " + payload, e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.debug(ex, () -> "Could not decode: " + payload);
|
||||
map.clear();
|
||||
map.put(UNDECODED, payload);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -28,12 +28,13 @@ import org.springframework.messaging.Message;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ExpressionEvaluatingHeaderValueMessageProcessor<T> extends AbstractHeaderValueMessageProcessor<T>
|
||||
implements BeanFactoryAware {
|
||||
|
||||
private static final ExpressionParser expressionParser = new SpelExpressionParser(new SpelParserConfiguration(
|
||||
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser(new SpelParserConfiguration(
|
||||
true, true));
|
||||
|
||||
private final ExpressionEvaluatingMessageProcessor<T> targetProcessor;
|
||||
@@ -42,7 +43,6 @@ public class ExpressionEvaluatingHeaderValueMessageProcessor<T> extends Abstract
|
||||
* Create a header value processor for the given Expression and the
|
||||
* expected type of the expression evaluation result. The expectedType
|
||||
* may be null if unknown.
|
||||
*
|
||||
* @param expression the {@link Expression} to evaluate.
|
||||
* @param expectedType the type for return value of {@code expression} evaluation result.
|
||||
*/
|
||||
@@ -54,12 +54,11 @@ public class ExpressionEvaluatingHeaderValueMessageProcessor<T> extends Abstract
|
||||
* Create a header value processor for the given expression string and
|
||||
* the expected type of the expression evaluation result. The
|
||||
* expectedType may be null if unknown.
|
||||
*
|
||||
* @param expressionString the {@link java.lang.String} expression presentation to evaluate.
|
||||
* @param expectedType the type for return value of {@code expression} evaluation result.
|
||||
*/
|
||||
public ExpressionEvaluatingHeaderValueMessageProcessor(String expressionString, Class<T> expectedType) {
|
||||
Expression expression = expressionParser.parseExpression(expressionString);
|
||||
Expression expression = EXPRESSION_PARSER.parseExpression(expressionString);
|
||||
this.targetProcessor = new ExpressionEvaluatingMessageProcessor<T>(expression, expectedType);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
package org.springframework.integration.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
@@ -47,7 +45,7 @@ import org.springframework.messaging.Message;
|
||||
*/
|
||||
public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, InitializingBean {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass()); // NOSONAR final
|
||||
protected final LogAccessor logger = new LogAccessor(this.getClass()); // NOSONAR final
|
||||
|
||||
protected static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
||||
|
||||
@@ -129,7 +127,7 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, I
|
||||
return evaluateExpression(expression, (Object) message, expectedType);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.debug("SpEL Expression evaluation failed with Exception.", ex);
|
||||
this.logger.debug(ex, "SpEL Expression evaluation failed with Exception.");
|
||||
Throwable cause = null;
|
||||
if (ex instanceof EvaluationException) { // NOSONAR
|
||||
cause = ex.getCause();
|
||||
|
||||
@@ -96,7 +96,7 @@ public class BeanFactoryTypeConverter implements TypeConverter, BeanFactoryAware
|
||||
return canConvert(sourceType, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override // NOSONAR
|
||||
public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
// Echoes org.springframework.expression.common.ExpressionUtils.convertTypedValue()
|
||||
if ((targetType.getType() == Void.class || targetType.getType() == Void.TYPE) && value == null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-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.
|
||||
@@ -31,9 +31,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
@@ -41,6 +39,7 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.annotation.Poller;
|
||||
import org.springframework.integration.annotation.Publisher;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
@@ -58,8 +57,7 @@ import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
|
||||
/**
|
||||
@@ -69,8 +67,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class BarrierMessageHandlerTests {
|
||||
|
||||
@@ -173,7 +170,7 @@ public class BarrierMessageHandlerTests {
|
||||
Map<?, ?> suspensions = TestUtils.getPropertyValue(handler, "suspensions", Map.class);
|
||||
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(suspensions.size()).as("suspension not removed").isEqualTo(0);
|
||||
Log logger = spy(TestUtils.getPropertyValue(handler, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(handler, "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(handler).setPropertyValue("logger", logger);
|
||||
final Message<String> triggerMessage = MessageBuilder.withPayload("bar").setCorrelationId("foo").build();
|
||||
handler.trigger(triggerMessage);
|
||||
|
||||
@@ -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.
|
||||
@@ -28,12 +28,12 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
|
||||
import org.springframework.integration.dispatcher.UnicastingDispatcher;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
@@ -56,7 +56,7 @@ class DirectChannelTests {
|
||||
@Test
|
||||
void testSend() {
|
||||
DirectChannel channel = new DirectChannel();
|
||||
Log logger = spy(TestUtils.getPropertyValue(channel, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(channel, "logger", LogAccessor.class));
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
new DirectFieldAccessor(channel).setPropertyValue("logger", logger);
|
||||
ThreadNameExtractingTestTarget target = new ThreadNameExtractingTestTarget();
|
||||
|
||||
@@ -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.
|
||||
@@ -27,16 +27,17 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
*/
|
||||
public class P2pChannelTests {
|
||||
@@ -53,7 +54,7 @@ public class P2pChannelTests {
|
||||
* @param channel
|
||||
*/
|
||||
private void verifySubscriptions(final AbstractSubscribableChannel channel) {
|
||||
final Log logger = mock(Log.class);
|
||||
final LogAccessor logger = mock(LogAccessor.class);
|
||||
when(logger.isInfoEnabled()).thenReturn(true);
|
||||
final List<String> logs = new ArrayList<>();
|
||||
doAnswer(invocation -> {
|
||||
@@ -96,7 +97,7 @@ public class P2pChannelTests {
|
||||
final ExecutorChannel channel = new ExecutorChannel(mock(Executor.class));
|
||||
channel.setBeanName("executorChannel");
|
||||
|
||||
final Log logger = mock(Log.class);
|
||||
final LogAccessor logger = mock(LogAccessor.class);
|
||||
when(logger.isInfoEnabled()).thenReturn(true);
|
||||
ReflectionUtils.doWithFields(AbstractMessageChannel.class, field -> {
|
||||
if ("logger".equals(field.getName())) {
|
||||
@@ -114,7 +115,7 @@ public class P2pChannelTests {
|
||||
final PublishSubscribeChannel channel = new PublishSubscribeChannel();
|
||||
channel.setBeanName("pubSubChannel");
|
||||
|
||||
final Log logger = mock(Log.class);
|
||||
final LogAccessor logger = mock(LogAccessor.class);
|
||||
when(logger.isInfoEnabled()).thenReturn(true);
|
||||
ReflectionUtils.doWithFields(AbstractMessageChannel.class, field -> {
|
||||
if ("logger".equals(field.getName())) {
|
||||
|
||||
@@ -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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@@ -25,12 +26,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -38,6 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.MessageRejectedException;
|
||||
@@ -60,8 +60,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -72,8 +71,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
public class ChainParserTests {
|
||||
|
||||
@Autowired
|
||||
@@ -296,13 +294,13 @@ public class ChainParserTests {
|
||||
|
||||
@Test //INT-2275, INT-2958
|
||||
public void chainWithLoggingChannelAdapter() {
|
||||
Log logger = mock(Log.class);
|
||||
final AtomicReference<String> log = new AtomicReference<>();
|
||||
LogAccessor logger = mock(LogAccessor.class);
|
||||
final AtomicReference<Supplier<? extends CharSequence>> log = new AtomicReference<>();
|
||||
when(logger.isWarnEnabled()).thenReturn(true);
|
||||
doAnswer(invocation -> {
|
||||
log.set(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(logger).warn(any());
|
||||
}).when(logger).warn(any(Supplier.class));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<MessageHandler> handlers = TestUtils.getPropertyValue(this.logChain, "handlers", List.class);
|
||||
@@ -311,24 +309,20 @@ public class ChainParserTests {
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(handler);
|
||||
dfa.setPropertyValue("messageLogger", logger);
|
||||
|
||||
this.loggingChannelAdapterChannel.send(MessageBuilder.withPayload(new byte[] { 116, 101, 115, 116 }).build());
|
||||
this.loggingChannelAdapterChannel.send(MessageBuilder.withPayload(new byte[]{ 116, 101, 115, 116 }).build());
|
||||
assertThat(log.get()).isNotNull();
|
||||
assertThat(log.get()).isEqualTo("TEST");
|
||||
assertThat(log.get().get()).isEqualTo("TEST");
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class) //INT-2275
|
||||
@Test
|
||||
public void invalidNestedChainWithLoggingChannelAdapter() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("invalidNestedChainWithOutboundChannelAdapter-context.xml",
|
||||
this.getClass()).close();
|
||||
fail("BeanCreationException is expected!");
|
||||
}
|
||||
catch (BeansException e) {
|
||||
assertThat(e.getCause().getClass()).isEqualTo(IllegalArgumentException.class);
|
||||
assertThat(e.getMessage()).contains("output channel was provided");
|
||||
assertThat(e.getMessage()).contains("does not implement the MessageProducer");
|
||||
throw e;
|
||||
}
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("invalidNestedChainWithOutboundChannelAdapter-context.xml",
|
||||
getClass()))
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("output channel was provided")
|
||||
.withMessageContaining("does not implement the MessageProducer");
|
||||
}
|
||||
|
||||
@Test //INT-2605
|
||||
|
||||
@@ -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.
|
||||
@@ -37,11 +37,12 @@ import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.MessagePublishingErrorHandler;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -172,7 +173,7 @@ public class SourcePollingChannelAdapterFactoryBeanTests {
|
||||
pollingChannelAdapter.setBeanFactory(mock(BeanFactory.class));
|
||||
pollingChannelAdapter.afterPropertiesSet();
|
||||
|
||||
Log adapterLogger = TestUtils.getPropertyValue(pollingChannelAdapter, "logger", Log.class);
|
||||
LogAccessor adapterLogger = TestUtils.getPropertyValue(pollingChannelAdapter, "logger", LogAccessor.class);
|
||||
adapterLogger = spy(adapterLogger);
|
||||
when(adapterLogger.isDebugEnabled()).thenReturn(true);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2019 the original author or authors.
|
||||
* Copyright 2017-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.
|
||||
@@ -30,10 +30,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
@@ -42,6 +41,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.expression.FunctionExpression;
|
||||
@@ -53,14 +53,14 @@ import org.springframework.integration.util.MessagingAnnotationUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 4.3.8
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringJUnitConfig
|
||||
public class CustomMessagingAnnotationTests {
|
||||
|
||||
@Autowired(required = false)
|
||||
@@ -74,7 +74,7 @@ public class CustomMessagingAnnotationTests {
|
||||
public void testLogAnnotation() {
|
||||
assertThat(this.loggingHandler).isNotNull();
|
||||
|
||||
Log log = spy(TestUtils.getPropertyValue(this.loggingHandler, "messageLogger", Log.class));
|
||||
LogAccessor log = spy(TestUtils.getPropertyValue(this.loggingHandler, "messageLogger", LogAccessor.class));
|
||||
|
||||
given(log.isWarnEnabled())
|
||||
.willReturn(true);
|
||||
@@ -86,12 +86,13 @@ public class CustomMessagingAnnotationTests {
|
||||
.setHeader("bar", "baz")
|
||||
.build());
|
||||
|
||||
ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<Supplier<? extends CharSequence>> argumentCaptor = ArgumentCaptor.forClass(Supplier.class);
|
||||
|
||||
verify(log)
|
||||
.warn(argumentCaptor.capture());
|
||||
|
||||
assertThat(argumentCaptor.getValue()).isEqualTo("foo for baz");
|
||||
assertThat(argumentCaptor.getValue().get()).isEqualTo("foo for baz");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
@@ -40,6 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -274,7 +274,7 @@ public class GatewayParserTests {
|
||||
@Test
|
||||
public void testCustomCompletableNoAsyncAttemptAsync() throws Exception {
|
||||
Object gateway = context.getBean("&customCompletableAttemptAsync");
|
||||
Log logger = spy(TestUtils.getPropertyValue(gateway, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(gateway, "logger", LogAccessor.class));
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
new DirectFieldAccessor(gateway).setPropertyValue("logger", logger);
|
||||
QueueChannel requestChannel = (QueueChannel) context.getBean("requestChannel");
|
||||
@@ -423,7 +423,7 @@ public class GatewayParserTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
try {
|
||||
Future<?> result = super.submit(task);
|
||||
|
||||
@@ -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.
|
||||
@@ -19,8 +19,7 @@ package org.springframework.integration.config.xml;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -31,7 +30,7 @@ import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.expression.FunctionExpression;
|
||||
import org.springframework.integration.handler.LoggingHandler;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -40,7 +39,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringJUnitConfig
|
||||
public class LoggingChannelAdapterParserTests {
|
||||
|
||||
@Autowired
|
||||
@@ -55,7 +54,7 @@ public class LoggingChannelAdapterParserTests {
|
||||
@Test
|
||||
public void verifyConfig() {
|
||||
LoggingHandler loggingHandler = TestUtils.getPropertyValue(loggerConsumer, "handler", LoggingHandler.class);
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "messageLogger.logger.name"))
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "messageLogger.log.logger.name"))
|
||||
.isEqualTo("org.springframework.integration.test.logger");
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "order")).isEqualTo(1);
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "level")).isEqualTo(LoggingHandler.Level.WARN);
|
||||
@@ -66,7 +65,7 @@ public class LoggingChannelAdapterParserTests {
|
||||
public void verifyExpressionAndOtherDefaultConfig() {
|
||||
LoggingHandler loggingHandler =
|
||||
TestUtils.getPropertyValue(loggerWithExpression, "handler", LoggingHandler.class);
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "messageLogger.logger.name"))
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "messageLogger.log.logger.name"))
|
||||
.isEqualTo("org.springframework.integration.handler.LoggingHandler");
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "order")).isEqualTo(Ordered.LOWEST_PRECEDENCE);
|
||||
assertThat(TestUtils.getPropertyValue(loggingHandler, "level")).isEqualTo(LoggingHandler.Level.INFO);
|
||||
|
||||
@@ -39,7 +39,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
@@ -64,6 +63,7 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.expression.EnvironmentAccessor;
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
@@ -313,7 +313,7 @@ public class EnableIntegrationTests {
|
||||
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isFalse();
|
||||
|
||||
assertThat(this.annotationTestService.isRunning()).isTrue();
|
||||
Log logger = spy(TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "logger", LogAccessor.class));
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
final CountDownLatch pollerInterruptedLatch = new CountDownLatch(1);
|
||||
doAnswer(invocation -> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2016-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.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.integration.handler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -29,12 +28,13 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
@@ -73,7 +73,7 @@ public class AsyncHandlerTests {
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
this.handler = new AbstractReplyProducingMessageHandler() {
|
||||
@@ -107,17 +107,18 @@ public class AsyncHandlerTests {
|
||||
this.handler.setOutputChannel(this.output);
|
||||
this.handler.setBeanFactory(mock(BeanFactory.class));
|
||||
this.latch = new CountDownLatch(1);
|
||||
Log logger = spy(TestUtils.getPropertyValue(this.handler, "logger", Log.class));
|
||||
new DirectFieldAccessor(this.handler).setPropertyValue("logger", logger);
|
||||
LogAccessor logAccessor = TestUtils.getPropertyValue(this.handler, "logger", LogAccessor.class);
|
||||
Log log = spy(logAccessor.getLog());
|
||||
new DirectFieldAccessor(logAccessor).setPropertyValue("log", log);
|
||||
doAnswer(invocation -> {
|
||||
failedCallbackMessage = invocation.getArgument(0);
|
||||
failedCallbackMessage = invocation.getArgument(0).toString();
|
||||
failedCallbackException = invocation.getArgument(1);
|
||||
exceptionLatch.countDown();
|
||||
return null;
|
||||
}).when(logger).error(anyString(), any(Throwable.class));
|
||||
}).when(log).error(any(), any(Throwable.class));
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
this.executor.shutdownNow();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.handler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -25,32 +26,36 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.handler.LoggingHandler.Level;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.condition.LogLevels;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Andriy Kryvtsun
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@LogLevels(categories = "test.logging.handler")
|
||||
public class LoggingHandlerTests {
|
||||
|
||||
@Autowired
|
||||
@@ -88,51 +93,49 @@ public class LoggingHandlerTests {
|
||||
@Test
|
||||
public void testDontEvaluateIfNotEnabled() {
|
||||
LoggingHandler loggingHandler = new LoggingHandler("INFO");
|
||||
loggingHandler.setLoggerName("test.logging.handler");
|
||||
loggingHandler.setBeanFactory(mock(BeanFactory.class));
|
||||
loggingHandler.afterPropertiesSet();
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(loggingHandler);
|
||||
Log log = (Log) accessor.getPropertyValue("messageLogger");
|
||||
log = spy(log);
|
||||
accessor.setPropertyValue("messageLogger", log);
|
||||
Expression expression = (Expression) accessor.getPropertyValue("expression");
|
||||
expression = spy(expression);
|
||||
accessor.setPropertyValue("expression", expression);
|
||||
when(log.isInfoEnabled()).thenReturn(false);
|
||||
LogAccessor logAccessor = TestUtils.getPropertyValue(loggingHandler, "messageLogger", LogAccessor.class);
|
||||
Log log = spy(logAccessor.getLog());
|
||||
when(log.isInfoEnabled()).thenReturn(false, true);
|
||||
new DirectFieldAccessor(logAccessor).setPropertyValue("log", log);
|
||||
Expression expression = spy(TestUtils.getPropertyValue(loggingHandler, "expression", Expression.class));
|
||||
loggingHandler.setLogExpression(expression);
|
||||
loggingHandler.handleMessage(new GenericMessage<>("foo"));
|
||||
verify(expression, never()).getValue(Mockito.any(EvaluationContext.class), Mockito.any(Message.class));
|
||||
|
||||
when(log.isInfoEnabled()).thenReturn(true);
|
||||
verify(expression, never()).getValue(any(EvaluationContext.class), any(Message.class));
|
||||
loggingHandler.handleMessage(new GenericMessage<>("foo"));
|
||||
verify(expression, times(1)).getValue(Mockito.any(EvaluationContext.class), Mockito.any(Message.class));
|
||||
verify(expression, times(1)).getValue(any(EvaluationContext.class), any(Message.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testChangeLevel() {
|
||||
LoggingHandler loggingHandler = new LoggingHandler(Level.INFO);
|
||||
loggingHandler.setBeanFactory(mock(BeanFactory.class));
|
||||
loggingHandler.afterPropertiesSet();
|
||||
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(loggingHandler);
|
||||
Log log = (Log) accessor.getPropertyValue("messageLogger");
|
||||
LogAccessor log = (LogAccessor) accessor.getPropertyValue("messageLogger");
|
||||
log = spy(log);
|
||||
accessor.setPropertyValue("messageLogger", log);
|
||||
when(log.isInfoEnabled()).thenReturn(true);
|
||||
loggingHandler.handleMessage(new GenericMessage<>("foo"));
|
||||
verify(log, times(1)).info(Mockito.anyString());
|
||||
verify(log, never()).warn(Mockito.anyString());
|
||||
verify(log, times(1)).info(any(Supplier.class));
|
||||
verify(log, never()).warn(any(Supplier.class));
|
||||
|
||||
loggingHandler.setLevel(Level.WARN);
|
||||
loggingHandler.handleMessage(new GenericMessage<>("foo"));
|
||||
verify(log, times(1)).info(Mockito.anyString());
|
||||
verify(log, times(1)).warn(Mockito.anyString());
|
||||
verify(log, times(1)).info(any(Supplier.class));
|
||||
verify(log, times(1)).warn(any(Supplier.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsageWithoutSpringInitialization() {
|
||||
LoggingHandler loggingHandler = new LoggingHandler("ERROR");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(loggingHandler);
|
||||
Log log = (Log) accessor.getPropertyValue("messageLogger");
|
||||
LogAccessor log = (LogAccessor) accessor.getPropertyValue("messageLogger");
|
||||
log = spy(log);
|
||||
accessor.setPropertyValue("messageLogger", log);
|
||||
|
||||
@@ -141,7 +144,9 @@ public class LoggingHandlerTests {
|
||||
|
||||
loggingHandler.handleMessage(message);
|
||||
|
||||
verify(log).error(testPayload);
|
||||
verify(log)
|
||||
.error(ArgumentMatchers.<Supplier<? extends CharSequence>>argThat(logMessage ->
|
||||
logMessage.get().equals(testPayload)));
|
||||
}
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.handler.advice;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -39,16 +40,14 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.endpoint.PollingConsumer;
|
||||
import org.springframework.integration.filter.MessageFilter;
|
||||
@@ -70,8 +69,7 @@ import org.springframework.retry.support.DefaultRetryState;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
@@ -79,8 +77,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class AdvisedMessageHandlerTests {
|
||||
|
||||
@@ -836,7 +833,7 @@ public class AdvisedMessageHandlerTests {
|
||||
Method method = AbstractReplyProducingMessageHandler.class.getDeclaredMethod("handleRequestMessage",
|
||||
Message.class);
|
||||
when(methodInvocation.getMethod()).thenReturn(method);
|
||||
when(methodInvocation.getArguments()).thenReturn(new Object[] { new GenericMessage<>("foo") });
|
||||
when(methodInvocation.getArguments()).thenReturn(new Object[]{ new GenericMessage<>("foo") });
|
||||
try {
|
||||
doAnswer(invocation -> {
|
||||
throw theThrowable;
|
||||
@@ -903,14 +900,13 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(consumer, "pollingTask", Callable.class);
|
||||
assertThat(AopUtils.isAopProxy(pollingTask)).isTrue();
|
||||
Log logger = TestUtils.getPropertyValue(advice, "logger", Log.class);
|
||||
logger = spy(logger);
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(advice, "logger", LogAccessor.class));
|
||||
when(logger.isWarnEnabled()).thenReturn(Boolean.TRUE);
|
||||
final AtomicReference<String> logMessage = new AtomicReference<>();
|
||||
doAnswer(invocation -> {
|
||||
logMessage.set(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(logger).warn(Mockito.anyString());
|
||||
}).when(logger).warn(anyString());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(advice);
|
||||
accessor.setPropertyValue("logger", logger);
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@@ -29,6 +30,7 @@ import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
|
||||
@@ -66,6 +68,7 @@ public class JsonToObjectTransformerParserTests {
|
||||
private JsonObjectMapper<?, ?> jsonObjectMapper;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testDefaultObjectMapper() {
|
||||
Object jsonToObjectTransformer =
|
||||
TestUtils.getPropertyValue(this.defaultJacksonMapperTransformer, "transformer");
|
||||
@@ -73,7 +76,7 @@ public class JsonToObjectTransformerParserTests {
|
||||
.isEqualTo(Jackson2JsonObjectMapper.class);
|
||||
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(jsonToObjectTransformer);
|
||||
Log logger = (Log) spy(dfa.getPropertyValue("logger"));
|
||||
LogAccessor logger = (LogAccessor) spy(dfa.getPropertyValue("logger"));
|
||||
dfa.setPropertyValue("logger", logger);
|
||||
|
||||
String jsonString =
|
||||
@@ -92,9 +95,9 @@ public class JsonToObjectTransformerParserTests {
|
||||
assertThat(person.getAge()).isEqualTo(42);
|
||||
assertThat(person.getAddress().toString()).isEqualTo("123 Main Street");
|
||||
|
||||
ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
|
||||
verify(logger).debug(stringArgumentCaptor.capture(), any(Exception.class));
|
||||
String logMessage = stringArgumentCaptor.getValue();
|
||||
ArgumentCaptor<Supplier<String>> argumentCaptor = ArgumentCaptor.forClass(Supplier.class);
|
||||
verify(logger).debug(any(Exception.class), argumentCaptor.capture());
|
||||
String logMessage = argumentCaptor.getValue().get();
|
||||
|
||||
assertThat(logMessage).startsWith("Cannot build a ResolvableType from the request message");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 the original author or authors.
|
||||
* Copyright 2019-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.
|
||||
@@ -21,7 +21,6 @@ import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@@ -29,6 +28,7 @@ import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
@@ -55,19 +55,19 @@ public class AvroTests {
|
||||
@LogLevels(classes = DirectChannel.class, categories = "bar", level = "DEBUG")
|
||||
void testTransformers(@Autowired Config config) {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
Log spied = spy(TestUtils.getPropertyValue(config.in1(), "logger", Log.class));
|
||||
LogAccessor spied = spy(TestUtils.getPropertyValue(config.in1(), "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(config.in1()).setPropertyValue("logger", spied);
|
||||
config.in1().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow1");
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(spied, atLeastOnce()).debug(captor.capture());
|
||||
@@ -80,15 +80,15 @@ public class AvroTests {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
config.in2().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow2");
|
||||
}
|
||||
|
||||
@@ -97,15 +97,15 @@ public class AvroTests {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
config.in3().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow3");
|
||||
}
|
||||
|
||||
@@ -114,15 +114,15 @@ public class AvroTests {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
config.in4().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow4");
|
||||
}
|
||||
|
||||
@@ -131,15 +131,15 @@ public class AvroTests {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
config.in5().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isNotEqualTo(test)
|
||||
.isInstanceOf(AvroTestClass2.class);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow5");
|
||||
}
|
||||
|
||||
@@ -148,15 +148,15 @@ public class AvroTests {
|
||||
AvroTestClass1 test = new AvroTestClass1("baz", "fiz");
|
||||
config.in6().send(new GenericMessage<>(test));
|
||||
assertThat(config.tapped().receive(0))
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isInstanceOf(byte[].class);
|
||||
Message<?> received = config.out().receive(0);
|
||||
assertThat(received)
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
.isNotNull()
|
||||
.extracting(msg -> msg.getPayload())
|
||||
.isEqualTo(test)
|
||||
.isNotSameAs(test);
|
||||
assertThat(received.getHeaders().get("flow")).isEqualTo("flow6");
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ public class AvroTests {
|
||||
.wireTap(tapped())
|
||||
.transform(new SimpleFromAvroTransformer(AvroTestClass1.class)
|
||||
.typeExpression("'avroTest' == headers[avro_type] ? '"
|
||||
+ AvroTestClass2.class.getName() + "' : null"))
|
||||
+ AvroTestClass2.class.getName() + "' : null"))
|
||||
.enrichHeaders(h -> h.header("flow", "flow5"))
|
||||
.channel(out())
|
||||
.get();
|
||||
@@ -232,7 +232,7 @@ public class AvroTests {
|
||||
.wireTap(tapped())
|
||||
.transform(new SimpleFromAvroTransformer(AvroTestClass1.class)
|
||||
.typeExpression("'avroTest' == headers[avro_type] ? '"
|
||||
+ AvroTestClass2.class.getName() + "' : null"))
|
||||
+ AvroTestClass2.class.getName() + "' : null"))
|
||||
.enrichHeaders(h -> h.header("flow", "flow6"))
|
||||
.channel(out())
|
||||
.get();
|
||||
|
||||
@@ -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.
|
||||
@@ -134,7 +134,7 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
|
||||
*/
|
||||
public void setPreserveWireFeed(boolean preserveWireFeed) {
|
||||
Assert.isTrue(!this.syndFeedInputSet,
|
||||
"'preserveWireFeed' must be configured on the provided [" + this.syndFeedInput + "]");
|
||||
() -> "'preserveWireFeed' must be configured on the provided [" + this.syndFeedInput + "]");
|
||||
this.syndFeedInput.setPreserveWireFeed(preserveWireFeed);
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
|
||||
protected SyndEntry doReceive() {
|
||||
Assert.isTrue(this.initialized,
|
||||
"'FeedEntryReaderMessageSource' must be initialized before it can produce Messages.");
|
||||
SyndEntry nextEntry = null;
|
||||
SyndEntry nextEntry;
|
||||
synchronized (this.monitor) {
|
||||
nextEntry = getNextEntry();
|
||||
if (nextEntry == null) {
|
||||
@@ -223,13 +223,9 @@ public class FeedEntryMessageSource extends AbstractMessageSource<SyndEntry> {
|
||||
? new XmlReader(this.feedUrl)
|
||||
: new XmlReader(this.feedResource.getInputStream());
|
||||
SyndFeed feed = this.syndFeedInput.build(reader);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Retrieved feed for [" + this + "]");
|
||||
}
|
||||
logger.debug(() -> "Retrieved feed for [" + this + "]");
|
||||
if (feed == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No feeds updated for [" + this + "], returning null");
|
||||
}
|
||||
logger.debug(() -> "No feeds updated for [" + this + "], returning null");
|
||||
}
|
||||
return feed;
|
||||
}
|
||||
|
||||
@@ -145,8 +145,7 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
*/
|
||||
public FileReadingMessageSource(int internalQueueCapacity) {
|
||||
this(null);
|
||||
Assert.isTrue(internalQueueCapacity > 0,
|
||||
"Cannot create a queue with non positive capacity");
|
||||
Assert.isTrue(internalQueueCapacity > 0, "Cannot create a queue with non positive capacity");
|
||||
this.scanner = new HeadDirectoryScanner(internalQueueCapacity);
|
||||
}
|
||||
|
||||
@@ -383,9 +382,7 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
Set<File> freshFiles = new LinkedHashSet<>(filteredFiles);
|
||||
if (!freshFiles.isEmpty()) {
|
||||
this.toBeReceived.addAll(freshFiles);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added to queue: " + freshFiles);
|
||||
}
|
||||
logger.debug(() -> "Added to queue: " + freshFiles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,9 +391,7 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
* @param failedMessage the {@link Message} that failed
|
||||
*/
|
||||
public void onFailure(Message<File> failedMessage) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to send: " + failedMessage);
|
||||
}
|
||||
logger.warn(() -> "Failed to send: " + failedMessage);
|
||||
this.toBeReceived.offer(failedMessage.getPayload());
|
||||
}
|
||||
|
||||
@@ -440,8 +435,8 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
try {
|
||||
this.watcher = FileSystems.getDefault().newWatchService();
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Failed to create watcher for " + FileReadingMessageSource.this.directory, e);
|
||||
catch (IOException ex) {
|
||||
logger.error(ex, () -> "Failed to create watcher for " + FileReadingMessageSource.this.directory);
|
||||
}
|
||||
|
||||
this.kinds = new WatchEvent.Kind<?>[FileReadingMessageSource.this.watchEvents.length];
|
||||
@@ -462,8 +457,8 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
this.watcher = null;
|
||||
this.pathKeys.clear();
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Failed to close watcher for " + FileReadingMessageSource.this.directory, e);
|
||||
catch (IOException ex) {
|
||||
logger.error(ex, () -> "Failed to close watcher for " + FileReadingMessageSource.this.directory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +469,7 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
|
||||
@Override
|
||||
protected File[] listEligibleFiles(File directory) {
|
||||
Assert.state(this.watcher != null, "The WatchService has'nt been started");
|
||||
Assert.state(this.watcher != null, "The WatchService hasn't been started");
|
||||
|
||||
Set<File> files = new LinkedHashSet<>();
|
||||
|
||||
@@ -513,17 +508,15 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
private void processFilesFromNormalEvent(Set<File> files, File parentDir, WatchEvent<?> event) {
|
||||
Path item = (Path) event.context();
|
||||
File file = new File(parentDir, item.toFile().getName());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Watch event [" + event.kind() + "] for file [" + file + "]");
|
||||
}
|
||||
logger.debug(() -> "Watch event [" + event.kind() + "] for file [" + file + "]");
|
||||
|
||||
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
if (getFilter() instanceof ResettableFileListFilter) {
|
||||
((ResettableFileListFilter<File>) getFilter()).remove(file);
|
||||
}
|
||||
boolean fileRemoved = files.remove(file);
|
||||
if (fileRemoved && logger.isDebugEnabled()) {
|
||||
logger.debug("The file [" + file +
|
||||
if (fileRemoved) {
|
||||
logger.debug(() -> "The file [" + file +
|
||||
"] has been removed from the queue because of DELETE event.");
|
||||
}
|
||||
}
|
||||
@@ -538,19 +531,15 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("A file [" + file + "] for the event [" + event.kind() +
|
||||
"] doesn't exist. Ignored.");
|
||||
}
|
||||
logger.debug(() -> "A file [" + file + "] for the event [" + event.kind() +
|
||||
"] doesn't exist. Ignored.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processFilesFromOverflowEvent(Set<File> files, WatchEvent<?> event) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Watch event [" + StandardWatchEventKinds.OVERFLOW +
|
||||
"] with context [" + event.context() + "]");
|
||||
}
|
||||
logger.debug(() -> "Watch event [" + StandardWatchEventKinds.OVERFLOW +
|
||||
"] with context [" + event.context() + "]");
|
||||
|
||||
for (WatchKey watchKey : this.pathKeys.values()) {
|
||||
watchKey.cancel();
|
||||
@@ -589,17 +578,15 @@ public class FileReadingMessageSource extends AbstractMessageSource<File>
|
||||
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Failed to walk directory: " + directory.toString(), e);
|
||||
catch (IOException ex) {
|
||||
logger.error(ex, () -> "Failed to walk directory: " + directory.toString());
|
||||
}
|
||||
return walkedFiles;
|
||||
}
|
||||
|
||||
private void registerWatch(Path dir) throws IOException {
|
||||
if (!this.pathKeys.containsKey(dir)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("registering: " + dir + " for file events");
|
||||
}
|
||||
logger.debug(() -> "registering: " + dir + " for file events");
|
||||
WatchKey watchKey = dir.register(this.watcher, this.kinds);
|
||||
this.pathKeys.putIfAbsent(dir, watchKey);
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
|
||||
if (Command.MGET.equals(this.command)) {
|
||||
Assert.isTrue(!(this.options.contains(Option.SUBDIRS)),
|
||||
"Cannot use " + Option.SUBDIRS.toString() + " when using 'mget' use " +
|
||||
() -> "Cannot use " + Option.SUBDIRS.toString() + " when using 'mget' use " +
|
||||
Option.RECURSIVE.toString() + " to obtain files in subdirectories");
|
||||
}
|
||||
|
||||
@@ -544,9 +544,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
if (!localDirectory.exists()) {
|
||||
try {
|
||||
if (this.autoCreateLocalDirectory) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The '" + localDirectory + "' directory doesn't exist; Will create.");
|
||||
}
|
||||
logger.debug(() -> "The '" + localDirectory + "' directory doesn't exist; Will create.");
|
||||
if (!localDirectory.mkdirs()) {
|
||||
throw new IOException("Failed to make local directory: " + localDirectory);
|
||||
}
|
||||
@@ -646,7 +644,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
String remoteFilePath = obtainRemoteFilePath(requestMessage);
|
||||
String remoteFilename = getRemoteFilename(remoteFilePath);
|
||||
String remoteDir = getRemoteDirectory(remoteFilePath, remoteFilename);
|
||||
Session<F> session = null;
|
||||
Session<F> session;
|
||||
Object payload;
|
||||
if (this.options.contains(Option.STREAM)) {
|
||||
session = this.remoteFileTemplate.getSessionFactory().getSession();
|
||||
@@ -767,7 +765,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
if (lastSeparator > 0) {
|
||||
String remoteFileDirectory = remoteFileNewPath.substring(0, lastSeparator + 1);
|
||||
RemoteFileUtils.makeDirectories(remoteFileDirectory, session,
|
||||
this.remoteFileTemplate.getRemoteFileSeparator(), this.logger);
|
||||
this.remoteFileTemplate.getRemoteFileSeparator(), this.logger.getLog());
|
||||
}
|
||||
session.rename(remoteFilePath, remoteFileNewPath);
|
||||
return true;
|
||||
@@ -840,8 +838,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
}
|
||||
else {
|
||||
File localDir = file;
|
||||
return this.remoteFileTemplate.invoke(t ->
|
||||
mPut(requestMessage, t.getSession(), localDir));
|
||||
return this.remoteFileTemplate.invoke(t -> mPut(requestMessage, t.getSession(), localDir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,8 +866,9 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
if (path != null) {
|
||||
replies.add(path);
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug("File " + filteredFile.getAbsolutePath() + " removed before transfer; ignoring");
|
||||
else {
|
||||
logger.debug(() ->
|
||||
"File " + filteredFile.getAbsolutePath() + " removed before transfer; ignoring");
|
||||
}
|
||||
}
|
||||
else if (this.options.contains(Option.RECURSIVE)) {
|
||||
@@ -1033,7 +1031,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
}
|
||||
fileInfo = files[0];
|
||||
}
|
||||
File localFile =
|
||||
final File localFile =
|
||||
new File(generateLocalDirectory(message, remoteDir), generateLocalFileName(message, remoteFilename));
|
||||
FileExistsMode existsMode = this.fileExistsMode;
|
||||
boolean appending = FileExistsMode.APPEND.equals(existsMode);
|
||||
@@ -1051,8 +1049,8 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
else {
|
||||
outputStream = new BufferedOutputStream(new FileOutputStream(tempFile));
|
||||
}
|
||||
if (replacing && !localFile.delete() && this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Failed to delete " + localFile);
|
||||
if (replacing && !localFile.delete()) {
|
||||
this.logger.warn(() -> "Failed to delete " + localFile);
|
||||
}
|
||||
try {
|
||||
session.read(remoteFilePath, outputStream);
|
||||
@@ -1062,8 +1060,8 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
and the file can't be deleted without closing streams before.
|
||||
*/
|
||||
outputStream.close();
|
||||
if (!tempFile.delete() && this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Failed to delete tempFile " + tempFile);
|
||||
if (!tempFile.delete()) {
|
||||
this.logger.warn(() -> "Failed to delete tempFile " + tempFile);
|
||||
}
|
||||
|
||||
if (e instanceof RuntimeException) {
|
||||
@@ -1086,8 +1084,8 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
}
|
||||
if ((this.options.contains(Option.PRESERVE_TIMESTAMP)
|
||||
|| FileExistsMode.REPLACE_IF_MODIFIED.equals(existsMode))
|
||||
&& (!localFile.setLastModified(getModified(fileInfo)) && this.logger.isWarnEnabled())) {
|
||||
logger.warn("Failed to set lastModified on " + localFile);
|
||||
&& (!localFile.setLastModified(getModified(fileInfo)))) {
|
||||
logger.warn(() -> "Failed to set lastModified on " + localFile);
|
||||
}
|
||||
if (this.options.contains(Option.DELETE)) {
|
||||
boolean result = session.remove(remoteFilePath);
|
||||
@@ -1100,11 +1098,9 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
}
|
||||
}
|
||||
else if (FileExistsMode.REPLACE_IF_MODIFIED.equals(existsMode)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Local file '" + localFile + "' has the same modified timestamp, ignored");
|
||||
}
|
||||
logger.debug(() -> "Local file '" + localFile + "' has the same modified timestamp, ignored");
|
||||
if (this.command.equals(Command.MGET)) {
|
||||
localFile = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (!FileExistsMode.IGNORE.equals(existsMode)) {
|
||||
@@ -1112,11 +1108,9 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
"Error handling message in the [" + this + "]. Local file " + localFile + " already exists");
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Existing file skipped: " + localFile);
|
||||
}
|
||||
logger.debug(() -> "Existing file skipped: " + localFile);
|
||||
if (this.command.equals(Command.MGET)) {
|
||||
localFile = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return localFile;
|
||||
@@ -1126,7 +1120,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
String remoteFilename) throws IOException {
|
||||
|
||||
if (this.options.contains(Option.RECURSIVE)) {
|
||||
if (logger.isWarnEnabled() && !("*".equals(remoteFilename))) {
|
||||
if (!("*".equals(remoteFilename))) {
|
||||
logger.warn("File name pattern must be '*' when using recursion");
|
||||
}
|
||||
this.options.remove(Option.NAME_ONLY);
|
||||
@@ -1260,7 +1254,7 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
File localDir = ExpressionUtils.expressionToFile(this.localDirectoryExpression, evaluationContext, message,
|
||||
"Local Directory");
|
||||
if (!localDir.exists()) {
|
||||
Assert.isTrue(localDir.mkdirs(), "Failed to make local directory: " + localDir);
|
||||
Assert.isTrue(localDir.mkdirs(), () -> "Failed to make local directory: " + localDir);
|
||||
}
|
||||
return localDir;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.integration.endpoint.AbstractFetchLimitingMessageSource;
|
||||
import org.springframework.integration.file.DefaultDirectoryScanner;
|
||||
@@ -179,11 +180,9 @@ public abstract class AbstractInboundFileSynchronizingMessageSource<F>
|
||||
try {
|
||||
if (!this.localDirectory.exists()) {
|
||||
if (this.autoCreateLocalDirectory) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The '" + this.localDirectory + "' directory doesn't exist; Will create.");
|
||||
}
|
||||
if (!this.localDirectory.mkdirs() && this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Failed to create directories for " + this.localDirectory);
|
||||
logger.debug(() -> "The '" + this.localDirectory + "' directory doesn't exist; Will create.");
|
||||
if (!this.localDirectory.mkdirs()) {
|
||||
this.logger.warn(() -> "Failed to create directories for " + this.localDirectory);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -192,8 +191,9 @@ public abstract class AbstractInboundFileSynchronizingMessageSource<F>
|
||||
}
|
||||
this.fileSource.setDirectory(this.localDirectory);
|
||||
initFiltersAndScanner();
|
||||
if (this.getBeanFactory() != null) {
|
||||
this.fileSource.setBeanFactory(getBeanFactory());
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
if (beanFactory != null) {
|
||||
this.fileSource.setBeanFactory(beanFactory);
|
||||
}
|
||||
this.fileSource.afterPropertiesSet();
|
||||
this.synchronizer.afterPropertiesSet();
|
||||
@@ -241,8 +241,8 @@ public abstract class AbstractInboundFileSynchronizingMessageSource<F>
|
||||
this.fileSource.stop();
|
||||
this.synchronizer.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Error closing synchronizer", e);
|
||||
catch (IOException ex) {
|
||||
logger.error(ex, "Error closing synchronizer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,21 +43,21 @@ import org.springframework.util.Assert;
|
||||
public abstract class FileTailingMessageProducerSupport extends MessageProducerSupport
|
||||
implements ApplicationEventPublisherAware {
|
||||
|
||||
private volatile File file;
|
||||
|
||||
private volatile ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private volatile TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
|
||||
private volatile long tailAttemptsDelay = 5000;
|
||||
|
||||
private final AtomicLong lastNoMessageAlert = new AtomicLong();
|
||||
|
||||
private File file;
|
||||
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
|
||||
private long tailAttemptsDelay = 5000;
|
||||
|
||||
private long idleEventInterval = 0;
|
||||
|
||||
private volatile long lastProduce = System.currentTimeMillis();
|
||||
|
||||
private ScheduledFuture<?> idleEventScheduledFuture;
|
||||
private volatile ScheduledFuture<?> idleEventScheduledFuture;
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
|
||||
@@ -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.
|
||||
@@ -33,36 +33,33 @@ import org.springframework.util.Assert;
|
||||
* @author Gary Russell
|
||||
* @author Gavin Gray
|
||||
* @author Ali Shahbour
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public class OSDelegatingFileTailingMessageProducer extends FileTailingMessageProducerSupport
|
||||
implements SchedulingAwareRunnable {
|
||||
|
||||
private volatile Process nativeTailProcess;
|
||||
private boolean enableStatusReader = true;
|
||||
|
||||
private volatile String options = "-F -n 0";
|
||||
private String options = "-F -n 0";
|
||||
|
||||
private volatile String command = "ADAPTER_NOT_INITIALIZED";
|
||||
|
||||
private volatile boolean enableStatusReader = true;
|
||||
private volatile Process nativeTailProcess;
|
||||
|
||||
private volatile BufferedReader stdOutReader;
|
||||
|
||||
public void setOptions(String options) {
|
||||
if (options == null) {
|
||||
this.options = "";
|
||||
}
|
||||
else {
|
||||
this.options = options;
|
||||
}
|
||||
this.options = options == null ? "" : options;
|
||||
}
|
||||
|
||||
/**
|
||||
* If false, thread for capturing stderr will not be started
|
||||
* and stderr output will be ignored
|
||||
* @param enableStatusReader true or false
|
||||
* @since 4.3.6
|
||||
* @since 4.3.6
|
||||
*/
|
||||
public void setEnableStatusReader(boolean enableStatusReader) {
|
||||
this.enableStatusReader = enableStatusReader;
|
||||
@@ -84,16 +81,16 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
Assert.notNull(getFile(), "File cannot be null");
|
||||
super.onInit();
|
||||
Assert.notNull(getFile(), "File cannot be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() {
|
||||
super.doStart();
|
||||
destroyProcess();
|
||||
this.command = "tail " + this.options + " " + this.getFile().getAbsolutePath();
|
||||
this.getTaskExecutor().execute(this::runExec);
|
||||
this.command = "tail " + this.options + " " + getFile().getAbsolutePath();
|
||||
getTaskExecutor().execute(this::runExec);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,34 +139,26 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
||||
this.getTaskExecutor().execute(() -> {
|
||||
Process process = OSDelegatingFileTailingMessageProducer.this.nativeTailProcess;
|
||||
if (process == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Process destroyed before starting process monitor");
|
||||
}
|
||||
logger.debug("Process destroyed before starting process monitor");
|
||||
return;
|
||||
}
|
||||
|
||||
int result = Integer.MIN_VALUE;
|
||||
int result;
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Monitoring process " + process);
|
||||
}
|
||||
logger.debug(() -> "Monitoring process " + process);
|
||||
result = process.waitFor();
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("tail process terminated with value " + result);
|
||||
}
|
||||
logger.info(() -> "tail process terminated with value " + result);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.error("Interrupted - stopping adapter", e);
|
||||
logger.error(ex, "Interrupted - stopping adapter");
|
||||
stop();
|
||||
}
|
||||
finally {
|
||||
destroyProcess();
|
||||
}
|
||||
if (isRunning()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Restarting tail process in " + getMissingFileDelay() + " milliseconds");
|
||||
}
|
||||
logger.info(() -> "Restarting tail process in " + getMissingFileDelay() + " milliseconds");
|
||||
getTaskScheduler()
|
||||
.schedule(this::runExec, new Date(System.currentTimeMillis() + getMissingFileDelay()));
|
||||
}
|
||||
@@ -183,41 +172,32 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
||||
private void startStatusReader() {
|
||||
Process process = this.nativeTailProcess;
|
||||
if (process == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Process destroyed before starting stderr reader");
|
||||
}
|
||||
logger.debug("Process destroyed before starting stderr reader");
|
||||
return;
|
||||
}
|
||||
this.getTaskExecutor().execute(() -> {
|
||||
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String statusMessage;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading stderr");
|
||||
}
|
||||
try {
|
||||
while ((statusMessage = errorReader.readLine()) != null) {
|
||||
publish(statusMessage);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(statusMessage);
|
||||
getTaskExecutor()
|
||||
.execute(() -> {
|
||||
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String statusMessage;
|
||||
logger.debug("Reading stderr");
|
||||
try {
|
||||
while ((statusMessage = errorReader.readLine()) != null) {
|
||||
publish(statusMessage);
|
||||
logger.trace(statusMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e1) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Exception on tail error reader", e1);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
errorReader.close();
|
||||
}
|
||||
catch (IOException e2) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Exception while closing stderr", e2);
|
||||
catch (IOException e1) {
|
||||
logger.debug(e1, "Exception on tail error reader");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
finally {
|
||||
try {
|
||||
errorReader.close();
|
||||
}
|
||||
catch (IOException e2) {
|
||||
logger.debug(e2, "Exception while closing stderr");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,26 +207,20 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
||||
public void run() {
|
||||
String line;
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading stdout");
|
||||
}
|
||||
logger.debug("Reading stdout");
|
||||
while ((line = this.stdOutReader.readLine()) != null) {
|
||||
this.send(line);
|
||||
send(line);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Exception on tail reader", e);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.debug(ex, "Exception on tail reader");
|
||||
try {
|
||||
this.stdOutReader.close();
|
||||
}
|
||||
catch (IOException e1) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Exception while closing stdout", e);
|
||||
}
|
||||
logger.debug(e1, "Exception while closing stdout");
|
||||
}
|
||||
this.destroyProcess();
|
||||
destroyProcess();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -47,7 +47,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -56,6 +55,7 @@ import org.junit.jupiter.api.io.TempDir;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -526,7 +526,7 @@ public class FileWritingMessageHandlerTests {
|
||||
assertThat(called.get()).isTrue();
|
||||
|
||||
handler.stop();
|
||||
Log logger = spy(TestUtils.getPropertyValue(handler, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(handler, "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(handler).setPropertyValue("logger", logger);
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
final AtomicInteger flushes = new AtomicInteger();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
@@ -113,10 +113,11 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
||||
for (Map.Entry<String, String> entry : parameterExpressions.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String expression = entry.getValue();
|
||||
Expression[] expressions = new Expression[] {
|
||||
EXPRESSION_PARSER.parseExpression(expression),
|
||||
EXPRESSION_PARSER.parseExpression("#root.![" + expression + "]")
|
||||
};
|
||||
Expression[] expressions =
|
||||
{
|
||||
EXPRESSION_PARSER.parseExpression(expression),
|
||||
EXPRESSION_PARSER.parseExpression("#root.![" + expression + "]")
|
||||
};
|
||||
paramExpressions.put(key, expressions);
|
||||
}
|
||||
this.parameterExpressions.putAll(paramExpressions);
|
||||
@@ -196,10 +197,11 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
||||
}
|
||||
|
||||
if (!this.parameterExpressions.containsKey(paramName)) {
|
||||
Expression[] expressions = new Expression[] {
|
||||
EXPRESSION_PARSER.parseExpression(paramName),
|
||||
EXPRESSION_PARSER.parseExpression("#root.![" + paramName + "]")
|
||||
};
|
||||
Expression[] expressions =
|
||||
{
|
||||
EXPRESSION_PARSER.parseExpression(paramName),
|
||||
EXPRESSION_PARSER.parseExpression("#root.![" + paramName + "]")
|
||||
};
|
||||
ExpressionEvaluatingSqlParameterSourceFactory.this.parameterExpressions.put(paramName, expressions);
|
||||
this.parameterExpressions.put(paramName, expressions);
|
||||
}
|
||||
@@ -217,9 +219,7 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
||||
if (this.cache || calledFromHasValue) {
|
||||
this.values.put(paramName, value);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Resolved expression " + expression + " to " + value);
|
||||
}
|
||||
logger.debug(() -> "Resolved expression " + expression + " to " + value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -231,10 +231,8 @@ public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpre
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (ExpressionException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not evaluate expression", e);
|
||||
}
|
||||
catch (ExpressionException ex) {
|
||||
logger.debug(ex, "Could not evaluate expression");
|
||||
if (this.cache) {
|
||||
this.values.put(paramName, ERROR);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -171,14 +171,12 @@ public class JdbcOutboundGateway extends AbstractReplyProducingMessageHandler {
|
||||
if (this.poller != null) {
|
||||
SqlParameterSource sqlQueryParameterSource =
|
||||
this.sqlParameterSourceFactory.createParameterSource(requestMessage);
|
||||
if (this.keysGenerated) {
|
||||
if (!list.isEmpty()) {
|
||||
if (list.size() == 1) {
|
||||
sqlQueryParameterSource = this.sqlParameterSourceFactory.createParameterSource(list.get(0));
|
||||
}
|
||||
else {
|
||||
sqlQueryParameterSource = this.sqlParameterSourceFactory.createParameterSource(list);
|
||||
}
|
||||
if (this.keysGenerated && !list.isEmpty()) {
|
||||
if (list.size() == 1) {
|
||||
sqlQueryParameterSource = this.sqlParameterSourceFactory.createParameterSource(list.get(0));
|
||||
}
|
||||
else {
|
||||
sqlQueryParameterSource = this.sqlParameterSourceFactory.createParameterSource(list);
|
||||
}
|
||||
}
|
||||
list = this.poller.doPoll(sqlQueryParameterSource);
|
||||
|
||||
@@ -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.
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import org.springframework.integration.handler.AbstractMessageHandler;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
/**
|
||||
@@ -45,6 +46,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class StoredProcMessageHandler extends AbstractMessageHandler {
|
||||
@@ -52,11 +55,8 @@ public class StoredProcMessageHandler extends AbstractMessageHandler {
|
||||
private final StoredProcExecutor executor;
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor passing in the {@link StoredProcExecutor}.
|
||||
*
|
||||
* @param storedProcExecutor Must not be null.
|
||||
*
|
||||
*/
|
||||
public StoredProcMessageHandler(StoredProcExecutor storedProcExecutor) {
|
||||
Assert.notNull(storedProcExecutor, "storedProcExecutor must not be null.");
|
||||
@@ -72,22 +72,15 @@ public class StoredProcMessageHandler extends AbstractMessageHandler {
|
||||
/**
|
||||
* Executes the Stored procedure, delegates to executeStoredProcedure(...).
|
||||
* Any return values from the Stored procedure are ignored.
|
||||
*
|
||||
* Return values are logged at debug level, though.
|
||||
*/
|
||||
@Override
|
||||
protected void handleMessageInternal(Message<?> message) {
|
||||
|
||||
Map<String, Object> resultMap = this.executor.executeStoredProcedure(message);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
if (resultMap != null && !resultMap.isEmpty()) {
|
||||
logger.debug(String.format("The StoredProcMessageHandler ignores return "
|
||||
+ "values, but the called Stored Procedure '%s' returned data: '%s'",
|
||||
this.executor.getStoredProcedureName(), resultMap));
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(resultMap)) {
|
||||
logger.debug(() -> String.format("The StoredProcMessageHandler ignores return "
|
||||
+ "values, but the called Stored Procedure '%s' returned data: '%s'",
|
||||
this.executor.getStoredProcedureName(), resultMap));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,10 +30,8 @@ import java.util.function.Supplier;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.core.serializer.Deserializer;
|
||||
import org.springframework.core.serializer.Serializer;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
@@ -88,7 +86,7 @@ import org.springframework.util.StringUtils;
|
||||
@ManagedResource
|
||||
public class JdbcChannelMessageStore implements PriorityCapableChannelMessageStore, InitializingBean {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JdbcChannelMessageStore.class);
|
||||
private static final LogAccessor LOGGER = new LogAccessor(JdbcChannelMessageStore.class);
|
||||
|
||||
/**
|
||||
* Default region property, used to partition the message store. For example,
|
||||
@@ -188,7 +186,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* A converter for deserializing byte arrays to messages.
|
||||
* @param deserializer the deserializer to set
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void setDeserializer(Deserializer<? extends Message<?>> deserializer) {
|
||||
this.deserializer = new AllowListDeserializingConverter((Deserializer) deserializer);
|
||||
}
|
||||
@@ -386,8 +384,8 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
this.messageRowMapper = new MessageRowMapper(this.deserializer, this.lobHandler);
|
||||
}
|
||||
|
||||
if (this.jdbcTemplate.getFetchSize() != 1 && logger.isWarnEnabled()) {
|
||||
logger.warn("The jdbcTemplate's fetch size is not 1. This may cause FIFO issues with Oracle databases.");
|
||||
if (this.jdbcTemplate.getFetchSize() != 1 && LOGGER.isWarnEnabled()) {
|
||||
LOGGER.warn("The jdbcTemplate's fetch size is not 1. This may cause FIFO issues with Oracle databases.");
|
||||
}
|
||||
|
||||
if (this.preparedStatementSetter == null) {
|
||||
@@ -413,10 +411,9 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
this.priorityEnabled));
|
||||
}
|
||||
catch (@SuppressWarnings("unused") DuplicateKeyException e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
String messageId = getKey(message.getHeaders().getId());
|
||||
logger.debug("The Message with id [" + messageId + "] already exists.\nIgnoring INSERT...");
|
||||
}
|
||||
LOGGER.debug(() ->
|
||||
"The Message with id [" + getKey(message.getHeaders().getId()) + "] already exists.\n" +
|
||||
"Ignoring INSERT...");
|
||||
}
|
||||
return getMessageGroup(groupId);
|
||||
}
|
||||
@@ -483,9 +480,9 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
@Override
|
||||
public void removeMessageGroup(Object groupId) {
|
||||
this.jdbcTemplate.update(
|
||||
this.getQuery(Query.DELETE_GROUP,
|
||||
getQuery(Query.DELETE_GROUP,
|
||||
() -> this.channelMessageStoreQueryProvider.getDeleteMessageGroupQuery()),
|
||||
this.getKey(groupId), this.region);
|
||||
getKey(groupId), this.region);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -494,16 +491,11 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
*/
|
||||
@Override
|
||||
public Message<?> pollMessageFromGroup(Object groupId) {
|
||||
|
||||
final String key = getKey(groupId);
|
||||
final Message<?> polledMessage = this.doPollForMessage(key);
|
||||
|
||||
if (polledMessage != null) {
|
||||
if (!this.doRemoveMessageFromGroup(groupId, polledMessage)) {
|
||||
return null;
|
||||
}
|
||||
String key = getKey(groupId);
|
||||
Message<?> polledMessage = doPollForMessage(key);
|
||||
if (polledMessage != null && !doRemoveMessageFromGroup(groupId, polledMessage)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return polledMessage;
|
||||
}
|
||||
|
||||
@@ -515,9 +507,8 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* @return a message; could be null if query produced no Messages
|
||||
*/
|
||||
protected Message<?> doPollForMessage(String groupIdKey) {
|
||||
|
||||
final NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.jdbcTemplate);
|
||||
final MapSqlParameterSource parameters = new MapSqlParameterSource();
|
||||
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.jdbcTemplate);
|
||||
MapSqlParameterSource parameters = new MapSqlParameterSource();
|
||||
|
||||
parameters.addValue("region", this.region);
|
||||
parameters.addValue("group_key", groupIdKey);
|
||||
@@ -568,10 +559,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
this.idCacheWriteLock.lock();
|
||||
try {
|
||||
boolean added = this.idCache.add(messageId);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Polled message with id '%s' added: '%s'.", messageId, added));
|
||||
}
|
||||
LOGGER.debug(() -> String.format("Polled message with id '%s' added: '%s'.", messageId, added));
|
||||
}
|
||||
finally {
|
||||
this.idCacheWriteLock.unlock();
|
||||
@@ -584,21 +572,19 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
}
|
||||
|
||||
private boolean doRemoveMessageFromGroup(Object groupId, Message<?> messageToRemove) {
|
||||
final UUID id = messageToRemove.getHeaders().getId();
|
||||
|
||||
UUID id = messageToRemove.getHeaders().getId();
|
||||
int updated = this.jdbcTemplate.update(
|
||||
getQuery(Query.DELETE_MESSAGE, () -> this.channelMessageStoreQueryProvider.getDeleteMessageQuery()),
|
||||
new Object[]{getKey(id), getKey(groupId), this.region},
|
||||
new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR});
|
||||
new Object[]{ getKey(id), getKey(groupId), this.region },
|
||||
new int[]{ Types.VARCHAR, Types.VARCHAR, Types.VARCHAR });
|
||||
|
||||
boolean result = updated != 0;
|
||||
if (result) {
|
||||
logger.debug(String.format("Message with id '%s' was deleted.", id));
|
||||
LOGGER.debug(() -> String.format("Message with id '%s' was deleted.", id));
|
||||
}
|
||||
else {
|
||||
logger.warn(String.format("Message with id '%s' was not deleted.", id));
|
||||
LOGGER.warn(() -> String.format("Message with id '%s' was not deleted.", id));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -612,9 +598,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* @param messageId The message identifier.
|
||||
*/
|
||||
public void removeFromIdCache(String messageId) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Removing Message Id: " + messageId);
|
||||
}
|
||||
LOGGER.debug(() -> "Removing Message Id: " + messageId);
|
||||
this.idCacheWriteLock.lock();
|
||||
try {
|
||||
this.idCache.remove(messageId);
|
||||
|
||||
@@ -25,13 +25,11 @@ import javax.jms.JMSException;
|
||||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.core.MessagingTemplate;
|
||||
import org.springframework.integration.gateway.MessagingGatewaySupport;
|
||||
import org.springframework.integration.support.DefaultMessageBuilderFactory;
|
||||
@@ -66,7 +64,7 @@ public class ChannelPublishingJmsMessageListener
|
||||
implements SessionAwareMessageListener<javax.jms.Message>, InitializingBean,
|
||||
TrackableComponent, BeanFactoryAware {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); // NOSONAR final
|
||||
protected final LogAccessor logger = new LogAccessor(getClass()); // NOSONAR final
|
||||
|
||||
private final GatewayDelegate gatewayDelegate = new GatewayDelegate();
|
||||
|
||||
@@ -315,13 +313,14 @@ public class ChannelPublishingJmsMessageListener
|
||||
public void onMessage(javax.jms.Message jmsMessage, Session session) throws JMSException {
|
||||
Message<?> requestMessage;
|
||||
try {
|
||||
Object result = jmsMessage;
|
||||
final Object result;
|
||||
if (this.extractRequestPayload) {
|
||||
result = this.messageConverter.fromMessage(jmsMessage);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("converted JMS Message [" + jmsMessage + "] to integration Message payload ["
|
||||
+ result + "]");
|
||||
}
|
||||
this.logger.debug(() -> "converted JMS Message [" + jmsMessage + "] to integration Message payload ["
|
||||
+ result + "]");
|
||||
}
|
||||
else {
|
||||
result = jmsMessage;
|
||||
}
|
||||
|
||||
Map<String, Object> headers = this.headerMapper.toHeaders(jmsMessage);
|
||||
@@ -349,14 +348,15 @@ public class ChannelPublishingJmsMessageListener
|
||||
Message<?> replyMessage = this.gatewayDelegate.sendAndReceiveMessage(requestMessage);
|
||||
if (replyMessage != null) {
|
||||
Destination destination = getReplyDestination(jmsMessage, session);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Reply destination: " + destination);
|
||||
}
|
||||
this.logger.debug(() -> "Reply destination: " + destination);
|
||||
// convert SI Message to JMS Message
|
||||
Object replyResult = replyMessage;
|
||||
final Object replyResult;
|
||||
if (this.extractReplyPayload) {
|
||||
replyResult = replyMessage.getPayload();
|
||||
}
|
||||
else {
|
||||
replyResult = replyMessage;
|
||||
}
|
||||
try {
|
||||
javax.jms.Message jmsReply = this.messageConverter.toMessage(replyResult, session);
|
||||
// map SI Message Headers to JMS Message Properties/Headers
|
||||
@@ -364,9 +364,9 @@ public class ChannelPublishingJmsMessageListener
|
||||
copyCorrelationIdFromRequestToReply(jmsMessage, jmsReply);
|
||||
sendReply(jmsReply, destination, session);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
this.logger.error("Failed to generate JMS Reply Message from: " + replyResult, e);
|
||||
throw e;
|
||||
catch (RuntimeException ex) {
|
||||
this.logger.error(ex, () -> "Failed to generate JMS Reply Message from: " + replyResult);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -404,8 +404,8 @@ public class ChannelPublishingJmsMessageListener
|
||||
if (value != null) {
|
||||
replyMessage.setStringProperty(this.correlationKey, value);
|
||||
}
|
||||
else if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("No property value available on request Message for correlationKey '"
|
||||
else {
|
||||
this.logger.warn(() -> "No property value available on request Message for correlationKey '"
|
||||
+ this.correlationKey + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -24,64 +24,64 @@ package org.springframework.integration.jms;
|
||||
*/
|
||||
abstract class DynamicJmsTemplateProperties {
|
||||
|
||||
private static final ThreadLocal<Integer> priorityHolder = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Integer> PRIORITY_HOLDER = new ThreadLocal<>();
|
||||
|
||||
private static final ThreadLocal<Long> receiveTimeoutHolder = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Long> RECEIVE_TIMEOUT_HOLDER = new ThreadLocal<>();
|
||||
|
||||
private static final ThreadLocal<Integer> deliverModeHolder = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Integer> DELIVER_MODE_HOLDER = new ThreadLocal<>();
|
||||
|
||||
private static final ThreadLocal<Long> timeToLiveHolder = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Long> TIME_TO_LIVE_HOLDER = new ThreadLocal<>();
|
||||
|
||||
|
||||
private DynamicJmsTemplateProperties() {
|
||||
}
|
||||
|
||||
public static Integer getPriority() {
|
||||
return priorityHolder.get();
|
||||
return PRIORITY_HOLDER.get();
|
||||
}
|
||||
|
||||
public static void setPriority(Integer priority) {
|
||||
priorityHolder.set(priority);
|
||||
PRIORITY_HOLDER.set(priority);
|
||||
}
|
||||
|
||||
public static void clearPriority() {
|
||||
priorityHolder.remove();
|
||||
PRIORITY_HOLDER.remove();
|
||||
}
|
||||
|
||||
public static Long getReceiveTimeout() {
|
||||
return receiveTimeoutHolder.get();
|
||||
return RECEIVE_TIMEOUT_HOLDER.get();
|
||||
}
|
||||
|
||||
public static void setReceiveTimeout(Long receiveTimeout) {
|
||||
receiveTimeoutHolder.set(receiveTimeout);
|
||||
RECEIVE_TIMEOUT_HOLDER.set(receiveTimeout);
|
||||
}
|
||||
|
||||
public static void clearReceiveTimeout() {
|
||||
receiveTimeoutHolder.remove();
|
||||
RECEIVE_TIMEOUT_HOLDER.remove();
|
||||
}
|
||||
|
||||
public static Integer getDeliveryMode() {
|
||||
return deliverModeHolder.get();
|
||||
return DELIVER_MODE_HOLDER.get();
|
||||
}
|
||||
|
||||
public static void setDeliveryMode(Integer deliveryMode) {
|
||||
deliverModeHolder.set(deliveryMode);
|
||||
DELIVER_MODE_HOLDER.set(deliveryMode);
|
||||
}
|
||||
|
||||
public static void clearDeliveryMode() {
|
||||
deliverModeHolder.remove();
|
||||
DELIVER_MODE_HOLDER.remove();
|
||||
}
|
||||
|
||||
public static Long getTimeToLive() {
|
||||
return timeToLiveHolder.get();
|
||||
return TIME_TO_LIVE_HOLDER.get();
|
||||
}
|
||||
|
||||
public static void setTimeToLive(Long timeToLive) {
|
||||
timeToLiveHolder.set(timeToLive);
|
||||
TIME_TO_LIVE_HOLDER.set(timeToLive);
|
||||
}
|
||||
|
||||
public static void clearTimeToLive() {
|
||||
timeToLiveHolder.remove();
|
||||
TIME_TO_LIVE_HOLDER.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -730,9 +730,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
synchronized (this.lifeCycleMonitor) {
|
||||
this.lastSend = System.currentTimeMillis();
|
||||
if (!this.replyContainer.isRunning()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(getComponentName() + ": Starting reply container.");
|
||||
}
|
||||
logger.debug(() -> getComponentName() + ": Starting reply container.");
|
||||
this.replyContainer.start();
|
||||
this.idleTask = getTaskScheduler().scheduleAtFixedRate(new IdleContainerStopper(),
|
||||
this.idleReplyContainerTimeout / 2);
|
||||
@@ -764,13 +762,14 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
|
||||
private AbstractIntegrationMessageBuilder<?> buildReply(javax.jms.Message jmsReply) throws JMSException {
|
||||
Object result = jmsReply;
|
||||
Object result;
|
||||
if (this.extractReplyPayload) {
|
||||
result = this.messageConverter.fromMessage(jmsReply);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("converted JMS Message [" + jmsReply + "] to integration Message payload [" + result +
|
||||
"]");
|
||||
}
|
||||
logger.debug(() ->
|
||||
"converted JMS Message [" + jmsReply + "] to integration Message payload [" + result + "]");
|
||||
}
|
||||
else {
|
||||
result = jmsReply;
|
||||
}
|
||||
Map<String, Object> jmsReplyHeaders = this.headerMapper.toHeaders(jmsReply);
|
||||
|
||||
@@ -805,9 +804,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
|
||||
jmsRequest.setJMSReplyTo(replyTo);
|
||||
connection.start();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ReplyTo: " + replyTo);
|
||||
}
|
||||
logger.debug(() -> "ReplyTo: " + replyTo);
|
||||
|
||||
Integer priority = StaticMessageHeaderAccessor.getPriority(requestMessage);
|
||||
if (priority == null) {
|
||||
@@ -847,7 +844,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
Session session = null;
|
||||
Destination replyTo = null;
|
||||
try {
|
||||
session = this.createSession(connection);
|
||||
session = createSession(connection);
|
||||
|
||||
// convert to JMS Message
|
||||
Object objectToSend = requestMessage;
|
||||
@@ -859,12 +856,11 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
// map headers
|
||||
this.headerMapper.fromHeaders(requestMessage.getHeaders(), jmsRequest);
|
||||
|
||||
replyTo = determineReplyDestination(requestMessage, session);
|
||||
jmsRequest.setJMSReplyTo(replyTo);
|
||||
Destination theReplyTo = determineReplyDestination(requestMessage, session);
|
||||
jmsRequest.setJMSReplyTo(theReplyTo);
|
||||
connection.start();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ReplyTo: " + replyTo);
|
||||
}
|
||||
logger.debug(() -> "ReplyTo: " + theReplyTo);
|
||||
replyTo = theReplyTo;
|
||||
|
||||
Integer priority = StaticMessageHeaderAccessor.getPriority(requestMessage);
|
||||
if (priority == null) {
|
||||
@@ -888,7 +884,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
finally {
|
||||
JmsUtils.closeSession(session);
|
||||
this.deleteDestinationIfTemporary(replyTo);
|
||||
deleteDestinationIfTemporary(replyTo);
|
||||
ConnectionFactoryUtils.releaseConnection(connection, this.connectionFactory, true);
|
||||
}
|
||||
}
|
||||
@@ -920,7 +916,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
messageSelector = "JMSCorrelationID = '" + jmsRequest.getJMSCorrelationID() + "'";
|
||||
}
|
||||
|
||||
this.sendRequestMessage(jmsRequest, messageProducer, priority);
|
||||
sendRequestMessage(jmsRequest, messageProducer, priority);
|
||||
return retryableReceiveReply(session, replyTo, messageSelector);
|
||||
}
|
||||
finally {
|
||||
@@ -939,8 +935,8 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
try {
|
||||
messageProducer = session.createProducer(reqDestination);
|
||||
messageConsumer = session.createConsumer(replyTo);
|
||||
this.sendRequestMessage(jmsRequest, messageProducer, priority);
|
||||
return this.receiveReplyMessage(messageConsumer);
|
||||
sendRequestMessage(jmsRequest, messageProducer, priority);
|
||||
return receiveReplyMessage(messageConsumer);
|
||||
}
|
||||
finally {
|
||||
JmsUtils.closeMessageProducer(messageProducer);
|
||||
@@ -1015,9 +1011,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
catch (JMSException e) { // NOSONAR - exception as flow control
|
||||
exception = e;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Connection lost waiting for reply, retrying: " + e.getMessage());
|
||||
}
|
||||
logger.debug(() -> "Connection lost waiting for reply, retrying: " + e.getMessage());
|
||||
do {
|
||||
try {
|
||||
consumerConnection = createConnection();
|
||||
@@ -1026,9 +1020,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
catch (JMSException ee) { // NOSONAR - exception as flow control
|
||||
exception = ee;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not reconnect, retrying: " + ee.getMessage());
|
||||
}
|
||||
logger.debug(() -> "Could not reconnect, retrying: " + ee.getMessage());
|
||||
try {
|
||||
Thread.sleep(1000); // NOSONAR
|
||||
}
|
||||
@@ -1078,9 +1070,8 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
jmsRequest.setJMSCorrelationID(null);
|
||||
}
|
||||
LinkedBlockingQueue<javax.jms.Message> replyQueue = null;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(this.getComponentName() + " Sending message with correlationId " + correlation);
|
||||
}
|
||||
String correlationToLog = correlation;
|
||||
logger.debug(() -> getComponentName() + " Sending message with correlationId " + correlationToLog);
|
||||
SettableListenableFuture<AbstractIntegrationMessageBuilder<?>> future = null;
|
||||
boolean async = isAsync();
|
||||
if (!async) {
|
||||
@@ -1121,10 +1112,8 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
this.sendRequestMessage(jmsRequest, messageProducer, priority);
|
||||
|
||||
correlation = jmsRequest.getJMSMessageID();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(getComponentName() + " Sent message with correlationId " + correlation);
|
||||
}
|
||||
String correlationToLog = correlation;
|
||||
logger.debug(() -> getComponentName() + " Sent message with correlationId " + correlationToLog);
|
||||
this.replies.put(correlation, replyQueue);
|
||||
|
||||
/*
|
||||
@@ -1133,9 +1122,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
synchronized (this.earlyOrLateReplies) {
|
||||
TimedReply timedReply = this.earlyOrLateReplies.remove(correlation);
|
||||
if (timedReply != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found early reply with correlationId " + correlation);
|
||||
}
|
||||
logger.debug(() -> "Found early reply with correlationId " + correlationToLog);
|
||||
replyQueue.add(timedReply.getReply());
|
||||
}
|
||||
}
|
||||
@@ -1162,20 +1149,20 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
try {
|
||||
reply = replyQueue.poll(this.receiveTimeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
logger.error("Interrupted while awaiting reply; treated as a timeout", e);
|
||||
catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.error(ex, "Interrupted while awaiting reply; treated as a timeout");
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (reply == null) {
|
||||
logger.debug(getComponentName() + " Timed out waiting for reply with CorrelationId "
|
||||
+ correlationId);
|
||||
javax.jms.Message replyToLog = reply;
|
||||
logger.debug(() -> {
|
||||
if (replyToLog == null) {
|
||||
return getComponentName() + " Timed out waiting for reply with CorrelationId " + correlationId;
|
||||
}
|
||||
else {
|
||||
logger.debug(getComponentName() + " Obtained reply with CorrelationId " + correlationId);
|
||||
return getComponentName() + " Obtained reply with CorrelationId " + correlationId;
|
||||
}
|
||||
}
|
||||
});
|
||||
return reply;
|
||||
}
|
||||
|
||||
@@ -1197,13 +1184,11 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
future.setException(new JmsTimeoutException("No reply in " + this.receiveTimeout + " ms"));
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reply expired and reply not required for " + correlationId);
|
||||
}
|
||||
logger.debug(() -> "Reply expired and reply not required for " + correlationId);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Exception while expiring future", e);
|
||||
catch (Exception ex) {
|
||||
logger.error(ex, "Exception while expiring future");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1265,9 +1250,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
public void onMessage(javax.jms.Message message) {
|
||||
String correlation = null;
|
||||
try {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(getComponentName() + " Received " + message);
|
||||
}
|
||||
logger.trace(() -> getComponentName() + " Received " + message);
|
||||
if (this.correlationKey == null ||
|
||||
this.correlationKey.equals("JMSCorrelationID") ||
|
||||
this.correlationKey.equals("JMSCorrelationID*")) {
|
||||
@@ -1284,10 +1267,9 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
onMessageSync(message, correlation);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to consume reply with correlationId " + correlation, e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
String correlationToLog = correlation;
|
||||
logger.warn(ex, () -> "Failed to consume reply with correlationId " + correlationToLog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1298,7 +1280,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
future.set(buildReply(message));
|
||||
}
|
||||
else {
|
||||
logger.warn("Late reply for " + correlationId);
|
||||
logger.warn(() -> "Late reply for " + correlationId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1318,24 +1300,18 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
synchronized (this.earlyOrLateReplies) {
|
||||
queue = this.replies.get(correlationId);
|
||||
if (queue == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reply for correlationId " + correlationId + " received early or late");
|
||||
}
|
||||
logger.debug(() -> "Reply for correlationId " + correlationId + " received early or late");
|
||||
this.earlyOrLateReplies.put(correlationId, new TimedReply(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (queue != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Received reply with correlationId " + correlationId);
|
||||
}
|
||||
logger.debug(() -> "Received reply with correlationId " + correlationId);
|
||||
queue.add(message);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to consume reply with correlationId " + correlationId, e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn(() -> "Failed to consume reply with correlationId " + correlationId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1466,9 +1442,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
while (lateReplyIterator.hasNext()) {
|
||||
Entry<String, TimedReply> entry = lateReplyIterator.next();
|
||||
if (entry.getValue().getTimeStamp() < expired) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Removing late reply for correlationId " + entry.getKey());
|
||||
}
|
||||
logger.debug(() -> "Removing late reply for correlationId " + entry.getKey());
|
||||
lateReplyIterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -1494,9 +1468,7 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler
|
||||
&& JmsOutboundGateway.this.replies.size() == 0 &&
|
||||
JmsOutboundGateway.this.replyContainer.isRunning()) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(getComponentName() + ": Stopping idle reply container.");
|
||||
}
|
||||
logger.debug(() -> getComponentName() + ": Stopping idle reply container.");
|
||||
JmsOutboundGateway.this.replyContainer.stop();
|
||||
JmsOutboundGateway.this.idleTask.cancel(false);
|
||||
JmsOutboundGateway.this.idleTask = null;
|
||||
|
||||
@@ -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.
|
||||
@@ -104,7 +104,7 @@ public class JmsChannelParser extends AbstractChannelParser {
|
||||
if (!("auto".equals(cache) || "consumer".equals(cache))) {
|
||||
parserContext.getReaderContext().warning(
|
||||
"'cache' attribute not actively supported for listener container of type \"simple\". " +
|
||||
"Effective runtime behavior will be equivalent to \"consumer\" / \"auto\".", element);
|
||||
"Effective runtime behavior will be equivalent to \"consumer\" / \"auto\".", element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -123,10 +123,8 @@ public class JmsChannelParser extends AbstractChannelParser {
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "concurrency");
|
||||
|
||||
String prefetch = element.getAttribute("prefetch");
|
||||
if (StringUtils.hasText(prefetch)) {
|
||||
if (containerType.startsWith("default")) {
|
||||
builder.addPropertyValue("maxMessagesPerTask", Integer.valueOf(prefetch));
|
||||
}
|
||||
if (StringUtils.hasText(prefetch) && containerType.startsWith("default")) {
|
||||
builder.addPropertyValue("maxMessagesPerTask", Integer.valueOf(prefetch));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.jms;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
@@ -27,11 +28,11 @@ import javax.jms.InvalidDestinationException;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -46,13 +47,14 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class ChannelPublishingJmsMessageListenerTests {
|
||||
|
||||
private final Session session = new StubSession("test");
|
||||
|
||||
|
||||
@Test(expected = InvalidDestinationException.class)
|
||||
@Test
|
||||
public void noReplyToAndNoDefault() throws JMSException {
|
||||
final QueueChannel requestChannel = new QueueChannel();
|
||||
startBackgroundReplier(requestChannel);
|
||||
@@ -63,15 +65,16 @@ public class ChannelPublishingJmsMessageListenerTests {
|
||||
javax.jms.Message jmsMessage = session.createTextMessage("test");
|
||||
listener.setBeanFactory(mock(BeanFactory.class));
|
||||
listener.afterPropertiesSet();
|
||||
listener.onMessage(jmsMessage, session);
|
||||
assertThatExceptionOfType(InvalidDestinationException.class)
|
||||
.isThrownBy(() -> listener.onMessage(jmsMessage, session));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadConversion() throws Exception {
|
||||
final QueueChannel requestChannel = new QueueChannel();
|
||||
ChannelPublishingJmsMessageListener listener = new ChannelPublishingJmsMessageListener();
|
||||
Log logger = spy(TestUtils.getPropertyValue(listener, "logger", Log.class));
|
||||
doNothing().when(logger).error(anyString(), any(Throwable.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(listener, "logger", LogAccessor.class));
|
||||
doNothing().when(logger).error(any(Throwable.class), anyString());
|
||||
new DirectFieldAccessor(listener).setPropertyValue("logger", logger);
|
||||
listener.setRequestChannel(requestChannel);
|
||||
QueueChannel errorChannel = new QueueChannel();
|
||||
@@ -80,7 +83,7 @@ public class ChannelPublishingJmsMessageListenerTests {
|
||||
listener.setMessageConverter(new TestMessageConverter() {
|
||||
|
||||
@Override
|
||||
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
|
||||
public Object fromMessage(javax.jms.Message message) throws MessageConversionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -97,7 +100,7 @@ public class ChannelPublishingJmsMessageListenerTests {
|
||||
private void startBackgroundReplier(final PollableChannel channel) {
|
||||
new SimpleAsyncTaskExecutor().execute(() -> {
|
||||
Message<?> request = channel.receive(50000);
|
||||
Message<?> reply = new GenericMessage<String>(((String) request.getPayload()).toUpperCase());
|
||||
Message<?> reply = new GenericMessage<>(((String) request.getPayload()).toUpperCase());
|
||||
((MessageChannel) request.getHeaders().getReplyChannel()).send(reply, 5000);
|
||||
});
|
||||
}
|
||||
@@ -105,13 +108,12 @@ public class ChannelPublishingJmsMessageListenerTests {
|
||||
private static class TestMessageConverter implements MessageConverter {
|
||||
|
||||
@Override
|
||||
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
|
||||
public Object fromMessage(javax.jms.Message message) throws MessageConversionException {
|
||||
return "test-from";
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.jms.Message toMessage(Object object, Session session)
|
||||
throws JMSException, MessageConversionException {
|
||||
public javax.jms.Message toMessage(Object object, Session session) throws MessageConversionException {
|
||||
return new StubTextMessage("test-to");
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -110,9 +110,7 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
*/
|
||||
@Override
|
||||
public void handleNotification(Notification notification, Object handback) {
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("received notification: " + notification + ", and handback: " + handback);
|
||||
}
|
||||
this.logger.info(() -> "received notification: " + notification + ", and handback: " + handback);
|
||||
AbstractIntegrationMessageBuilder<?> builder = getMessageBuilderFactory().withPayload(notification);
|
||||
if (handback != null) {
|
||||
builder.setHeader(JmxHeaders.NOTIFICATION_HANDBACK, handback);
|
||||
@@ -152,7 +150,7 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
try {
|
||||
Collection<ObjectName> objectNames = this.retrieveMBeanNames();
|
||||
if (objectNames.size() < 1) {
|
||||
this.logger.error("No MBeans found matching ObjectName pattern(s): " +
|
||||
this.logger.error(() -> "No MBeans found matching ObjectName pattern(s): " +
|
||||
Arrays.toString(this.mBeanObjectNames));
|
||||
}
|
||||
for (ObjectName objectName : objectNames) {
|
||||
@@ -179,14 +177,14 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
try {
|
||||
this.server.removeNotificationListener(objectName, this, this.filter, this.handback);
|
||||
}
|
||||
catch (InstanceNotFoundException e) {
|
||||
this.logger.error("Failed to find MBean instance.", e);
|
||||
catch (InstanceNotFoundException ex) {
|
||||
this.logger.error(ex, "Failed to find MBean instance.");
|
||||
}
|
||||
catch (ListenerNotFoundException e) {
|
||||
this.logger.error("Failed to find NotificationListener.", e);
|
||||
catch (ListenerNotFoundException ex) {
|
||||
this.logger.error(ex, "Failed to find NotificationListener.");
|
||||
}
|
||||
catch (IOException e) {
|
||||
this.logger.error("IOException on MBeanServerConnection.", e);
|
||||
catch (IOException ex) {
|
||||
this.logger.error(ex, "IOException on MBeanServerConnection.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,13 +200,11 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException("IOException on MBeanServerConnection.", e);
|
||||
}
|
||||
if (mBeanInfos.size() == 0 && this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("No MBeans found matching pattern: " + pattern);
|
||||
if (mBeanInfos.size() == 0) {
|
||||
this.logger.debug(() -> "No MBeans found matching pattern: " + pattern);
|
||||
}
|
||||
for (ObjectInstance instance : mBeanInfos) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Found MBean: " + instance.getObjectName().toString());
|
||||
}
|
||||
this.logger.debug(() -> "Found MBean: " + instance.getObjectName().toString());
|
||||
objectNames.add(instance.getObjectName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -21,14 +21,13 @@ import static org.mockito.BDDMockito.willReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
|
||||
import org.springframework.integration.jmx.JmxHeaders;
|
||||
import org.springframework.integration.jmx.OperationInvokingMessageHandler;
|
||||
@@ -38,7 +37,7 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -48,7 +47,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class OperationInvokingChannelAdapterParserTests {
|
||||
|
||||
@@ -80,7 +79,7 @@ public class OperationInvokingChannelAdapterParserTests {
|
||||
|
||||
private static int adviceCalled;
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void resetLists() {
|
||||
testBean.messages.clear();
|
||||
}
|
||||
@@ -98,7 +97,9 @@ public class OperationInvokingChannelAdapterParserTests {
|
||||
|
||||
@Test
|
||||
public void testOutboundAdapterWithNonNullReturn() {
|
||||
Log logger = spy(TestUtils.getPropertyValue(this.operationWithNonNullReturnHandler, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(this.operationWithNonNullReturnHandler, "logger",
|
||||
|
||||
LogAccessor.class));
|
||||
|
||||
willReturn(true)
|
||||
.given(logger)
|
||||
@@ -132,9 +133,9 @@ public class OperationInvokingChannelAdapterParserTests {
|
||||
|
||||
@Test
|
||||
public void testOperationWithinChainWithNonNullReturn() {
|
||||
Log logger =
|
||||
LogAccessor logger =
|
||||
spy(TestUtils.getPropertyValue(this.operationWithinChainWithNonNullReturnHandler, "logger",
|
||||
Log.class));
|
||||
LogAccessor.class));
|
||||
|
||||
willReturn(true)
|
||||
.given(logger)
|
||||
|
||||
@@ -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.
|
||||
@@ -18,8 +18,6 @@ package org.springframework.integration.jpa.config.xml;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -27,6 +25,7 @@ import org.springframework.beans.factory.config.TypedStringValue;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.jpa.core.JpaExecutor;
|
||||
import org.springframework.integration.jpa.support.JpaParameter;
|
||||
@@ -35,28 +34,23 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
|
||||
/**
|
||||
* Contains various utility methods for parsing JPA Adapter specific namesspace
|
||||
* Contains various utility methods for parsing JPA Adapter specific namespace
|
||||
* elements and generation the respective {@link BeanDefinition}s.
|
||||
*
|
||||
* @author Amol Nayak
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
public final class JpaParserUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JpaParserUtils.class);
|
||||
|
||||
/** Prevent instantiation. */
|
||||
private JpaParserUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
private static final LogAccessor LOGGER = new LogAccessor(JpaParserUtils.class);
|
||||
|
||||
/**
|
||||
* Create a new {@link BeanDefinitionBuilder} for the class {@link JpaExecutor}.
|
||||
* Initialize the wrapped {@link JpaExecutor} with common properties.
|
||||
*
|
||||
* @param element Must not be null
|
||||
* @param parserContext Must not be null
|
||||
* @return The BeanDefinitionBuilder for the JpaExecutor
|
||||
@@ -109,7 +103,7 @@ public final class JpaParserUtils {
|
||||
"'entity-manager-factory' or 'jpa-operations' must be be set.", source);
|
||||
}
|
||||
|
||||
final ManagedList<BeanDefinition> jpaParameterList = JpaParserUtils.getJpaParameterBeanDefinitions(element, parserContext);
|
||||
final ManagedList<BeanDefinition> jpaParameterList = getJpaParameterBeanDefinitions(element, parserContext);
|
||||
|
||||
if (!jpaParameterList.isEmpty()) {
|
||||
jpaExecutorBuilder.addPropertyValue("jpaParameters", jpaParameterList);
|
||||
@@ -127,22 +121,21 @@ public final class JpaParserUtils {
|
||||
/**
|
||||
* Create a new {@link BeanDefinitionBuilder} for the class {@link JpaExecutor}
|
||||
* that is specific for JPA Outbound Gateways.
|
||||
*
|
||||
* Initializes the wrapped {@link JpaExecutor} with common properties.
|
||||
* Delegates to {@link JpaParserUtils#getJpaExecutorBuilder(Element, ParserContext)}
|
||||
*
|
||||
* @param gatewayElement Must not be null
|
||||
* @param parserContext Must not be null
|
||||
*
|
||||
* @return The BeanDefinitionBuilder for the JpaExecutor
|
||||
*/
|
||||
public static BeanDefinitionBuilder getOutboundGatewayJpaExecutorBuilder(final Element gatewayElement,
|
||||
final ParserContext parserContext) {
|
||||
|
||||
final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getJpaExecutorBuilder(gatewayElement, parserContext);
|
||||
final BeanDefinitionBuilder jpaExecutorBuilder = getJpaExecutorBuilder(gatewayElement, parserContext);
|
||||
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "parameter-source-factory");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "use-payload-as-parameter-source");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement,
|
||||
"parameter-source-factory");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement,
|
||||
"use-payload-as-parameter-source");
|
||||
|
||||
return jpaExecutorBuilder;
|
||||
|
||||
@@ -151,10 +144,8 @@ public final class JpaParserUtils {
|
||||
/**
|
||||
* Create a {@link ManagedList} of {@link BeanDefinition}s containing parsed
|
||||
* JPA Parameters.
|
||||
*
|
||||
* @param jpaComponent Must not be null
|
||||
* @param parserContext Must not be null
|
||||
*
|
||||
* @return {@link ManagedList} of {@link BeanDefinition}s
|
||||
*/
|
||||
public static ManagedList<BeanDefinition> getJpaParameterBeanDefinitions(
|
||||
@@ -163,14 +154,13 @@ public final class JpaParserUtils {
|
||||
Assert.notNull(jpaComponent, "The provided element must not be null.");
|
||||
Assert.notNull(parserContext, "The provided parserContext must not be null.");
|
||||
|
||||
final ManagedList<BeanDefinition> parameterList = new ManagedList<BeanDefinition>();
|
||||
final ManagedList<BeanDefinition> parameterList = new ManagedList<>();
|
||||
|
||||
final List<Element> parameterChildElements = DomUtils
|
||||
.getChildElementsByTagName(jpaComponent, "parameter");
|
||||
|
||||
for (Element childElement : parameterChildElements) {
|
||||
|
||||
final BeanDefinitionBuilder parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaParameter.class);
|
||||
BeanDefinitionBuilder parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaParameter.class);
|
||||
|
||||
String name = childElement.getAttribute("name");
|
||||
String expression = childElement.getAttribute("expression");
|
||||
@@ -186,24 +176,14 @@ public final class JpaParserUtils {
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(value)) {
|
||||
|
||||
if (!StringUtils.hasText(type)) {
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String
|
||||
.format("Type attribute not set for parameter '%s'. Defaulting to "
|
||||
+ "'java.lang.String'.", value));
|
||||
}
|
||||
|
||||
parameterBuilder.addPropertyValue("value",
|
||||
new TypedStringValue(value, String.class));
|
||||
|
||||
LOGGER.info(() -> String.format("Type attribute not set for parameter '%s'. Defaulting to "
|
||||
+ "'java.lang.String'.", value));
|
||||
parameterBuilder.addPropertyValue("value", new TypedStringValue(value, String.class));
|
||||
}
|
||||
else {
|
||||
parameterBuilder.addPropertyValue("value",
|
||||
new TypedStringValue(value, type));
|
||||
parameterBuilder.addPropertyValue("value", new TypedStringValue(value, type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
parameterList.add(parameterBuilder.getBeanDefinition());
|
||||
@@ -213,4 +193,7 @@ public final class JpaParserUtils {
|
||||
|
||||
}
|
||||
|
||||
private JpaParserUtils() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,14 +20,13 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.jpa.support.JpaUtils;
|
||||
import org.springframework.integration.jpa.support.parametersource.ParameterSource;
|
||||
import org.springframework.integration.jpa.support.parametersource.PositionSupportingParameterSource;
|
||||
@@ -37,7 +36,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Class similar to JPA template limited to the operations required for the JPA adapters/gateway
|
||||
* not using JpaTemplate as the class is deprecated since Spring 3.1
|
||||
* not using JpaTemplate as the class is deprecated since Spring 3.1.
|
||||
*
|
||||
* @author Amol Nayak
|
||||
* @author Gunnar Hillert
|
||||
@@ -47,7 +46,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DefaultJpaOperations.class);
|
||||
private static final LogAccessor LOGGER = new LogAccessor(DefaultJpaOperations.class);
|
||||
|
||||
@Override
|
||||
public void delete(Object entity) {
|
||||
@@ -57,11 +56,8 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
|
||||
@Override
|
||||
public void deleteInBatch(Iterable<?> entities) {
|
||||
|
||||
Assert.notNull(entities, "entities must not be null.");
|
||||
|
||||
Iterator<?> iterator = entities.iterator();
|
||||
|
||||
if (!iterator.hasNext()) {
|
||||
return;
|
||||
}
|
||||
@@ -80,7 +76,7 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
}
|
||||
|
||||
EntityManager entityManager = getEntityManager();
|
||||
final String entityName = JpaUtils.getEntityName(entityManager, entityClass);
|
||||
final String entityName = JpaUtils.getEntityName(entityManager, entityClass);
|
||||
final String queryString = JpaUtils.getQueryString(JpaUtils.DELETE_ALL_QUERY_STRING, entityName);
|
||||
|
||||
JpaUtils.applyAndBind(queryString, entities, entityManager)
|
||||
@@ -89,7 +85,7 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String updateQuery, ParameterSource source) {
|
||||
public int executeUpdate(String updateQuery, ParameterSource source) {
|
||||
Query query = getEntityManager().createQuery(updateQuery);
|
||||
setParametersIfRequired(updateQuery, source, query);
|
||||
return query.executeUpdate();
|
||||
@@ -156,7 +152,7 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<?> getResultListForNativeQuery(String selectQuery, Class<?> entityClass,
|
||||
public List<?> getResultListForNativeQuery(String selectQuery, @Nullable Class<?> entityClass,
|
||||
ParameterSource parameterSource, int firstResult, int maxNumberOfResults) {
|
||||
|
||||
final Query query;
|
||||
@@ -182,7 +178,7 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
|
||||
@Override
|
||||
public List<?> getResultListForQuery(String query, ParameterSource source) {
|
||||
return getResultListForQuery(query, source, 0, 0);
|
||||
return getResultListForQuery(query, source, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,15 +261,15 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterable<Object> entities = (Iterable<Object>) entity;
|
||||
|
||||
int savedEntities = 0;
|
||||
int nullEntities = 0;
|
||||
AtomicInteger savedEntities = new AtomicInteger();
|
||||
AtomicInteger nullEntities = new AtomicInteger();
|
||||
|
||||
List<Object> mergedEntities = new ArrayList<Object>();
|
||||
List<Object> mergedEntities = new ArrayList<>();
|
||||
|
||||
EntityManager entityManager = getEntityManager();
|
||||
for (Object iteratedEntity : entities) {
|
||||
if (iteratedEntity == null) {
|
||||
nullEntities++;
|
||||
nullEntities.incrementAndGet();
|
||||
}
|
||||
else {
|
||||
if (isMerge) {
|
||||
@@ -282,8 +278,8 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
else {
|
||||
entityManager.persist(iteratedEntity);
|
||||
}
|
||||
savedEntities++;
|
||||
if (flushSize > 0 && savedEntities % flushSize == 0) {
|
||||
savedEntities.incrementAndGet();
|
||||
if (flushSize > 0 && savedEntities.get() % flushSize == 0) {
|
||||
entityManager.flush();
|
||||
if (clearOnFlush) {
|
||||
entityManager.clear();
|
||||
@@ -292,10 +288,8 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("%s %s entities. %s NULL entities were ignored.",
|
||||
isMerge ? "Merged" : "Persisted", savedEntities, nullEntities));
|
||||
}
|
||||
LOGGER.debug(() -> String.format("%s %s entities. %s NULL entities were ignored.",
|
||||
isMerge ? "Merged" : "Persisted", savedEntities.get(), nullEntities));
|
||||
|
||||
if (isMerge) {
|
||||
result = mergedEntities;
|
||||
@@ -308,13 +302,13 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
* use the {@link ParameterSource} to find their values and set them.
|
||||
*
|
||||
*/
|
||||
private void setParametersIfRequired(String queryString, ParameterSource source, Query query) {
|
||||
private void setParametersIfRequired(String queryString, @Nullable ParameterSource source, Query query) {
|
||||
Set<Parameter<?>> parameters = query.getParameters();
|
||||
|
||||
if (parameters != null && !parameters.isEmpty()) {
|
||||
if (source != null) {
|
||||
for (Parameter<?> param:parameters) {
|
||||
String paramName = param.getName();
|
||||
for (Parameter<?> param : parameters) {
|
||||
String paramName = param.getName();
|
||||
Integer position = param.getPosition();
|
||||
|
||||
final Object paramValue;
|
||||
@@ -340,7 +334,7 @@ public class DefaultJpaOperations extends AbstractJpaOperations {
|
||||
else {
|
||||
throw new JpaOperationFailedException(
|
||||
"This parameter does not contain a parameter name. " +
|
||||
"Additionally it is not a positional parameter, neither.", queryString);
|
||||
"Additionally it is not a positional parameter, neither.", queryString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.integration.jpa.core;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.integration.jpa.support.parametersource.ParameterSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* The Interface containing all the JpaOperations those will be executed by
|
||||
@@ -27,6 +28,8 @@ import org.springframework.integration.jpa.support.parametersource.ParameterSour
|
||||
* @author Amol Nayak
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
@@ -47,7 +50,6 @@ public interface JpaOperations {
|
||||
/**
|
||||
* Executes the given update statement and uses the given parameter source to
|
||||
* set the required query parameters.
|
||||
*
|
||||
* @param updateQuery Must Not be empty.
|
||||
* @param source Must Not be null.
|
||||
* @return The number of entities updated
|
||||
@@ -74,7 +76,6 @@ public interface JpaOperations {
|
||||
|
||||
/**
|
||||
* Find an Entity of given type with the given primary key type.
|
||||
*
|
||||
* @param <T> The type to return.
|
||||
* @param entityType The type.
|
||||
* @param id The object identifier.
|
||||
@@ -109,13 +110,14 @@ public interface JpaOperations {
|
||||
*
|
||||
* @param selectQuery The select query.
|
||||
* @param entityClass The entity class.
|
||||
* @param jpaQLParameterSource The paramter source.
|
||||
* @param jpaQLParameterSource The parameter source.
|
||||
* @param firstResult The index of the first result to return.
|
||||
* @param maxNumberOfResults The number of objects to return.
|
||||
* @return The list of found entities.
|
||||
*/
|
||||
List<?> getResultListForNativeQuery(String selectQuery,
|
||||
Class<?> entityClass, ParameterSource jpaQLParameterSource,
|
||||
@Nullable Class<?> entityClass,
|
||||
ParameterSource jpaQLParameterSource,
|
||||
int firstResult,
|
||||
int maxNumberOfResults);
|
||||
|
||||
@@ -129,7 +131,6 @@ public interface JpaOperations {
|
||||
|
||||
/**
|
||||
* Executes the provided query to return a list of results.
|
||||
*
|
||||
* @param query Must not be null or empty
|
||||
* @param firstResult The first result.
|
||||
* @param maxNumberOfResults Must be a non-negative value, any negative or zero will be ignored.
|
||||
@@ -140,7 +141,6 @@ public interface JpaOperations {
|
||||
|
||||
/**
|
||||
* Executes the provided query to return a single element
|
||||
*
|
||||
* @param query Must not be empty
|
||||
* @param source the Parameter source for this query to be executed, if none then set as null
|
||||
* @return Will always return a result. If no object was found in the database an exception is raised.
|
||||
@@ -154,7 +154,6 @@ public interface JpaOperations {
|
||||
* is treated as an entity and merged with the
|
||||
* {@link javax.persistence.EntityManager}. {@code Null}
|
||||
* values returned while iterating over the {@link Iterable} are ignored.
|
||||
*
|
||||
* @param entity Must not be null.
|
||||
* @return The merged managed instance of the entity.
|
||||
*/
|
||||
@@ -171,7 +170,6 @@ public interface JpaOperations {
|
||||
* provided object is {@link Iterable}.
|
||||
* {@code clearOnFlush}parameter specifies, if the {@link javax.persistence.EntityManager#clear()}
|
||||
* should be called after each {@link javax.persistence.EntityManager#flush()}.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @param flushSize The flush size.
|
||||
* @param clearOnFlush true to clear after flushing.
|
||||
@@ -186,9 +184,7 @@ public interface JpaOperations {
|
||||
* and persisted with the {@link javax.persistence.EntityManager}.
|
||||
* {@code Null} values returned
|
||||
* while iterating over the {@link Iterable} are ignored.
|
||||
*
|
||||
* @param entity Must not be null
|
||||
*
|
||||
*/
|
||||
void persist(Object entity);
|
||||
|
||||
@@ -203,7 +199,6 @@ public interface JpaOperations {
|
||||
* provided object is {@link Iterable}.
|
||||
* {@code clearOnFlush}parameter specifies, if the {@link javax.persistence.EntityManager#clear()}
|
||||
* should be called after each {@link javax.persistence.EntityManager#flush()}.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @param flushSize The flush size.
|
||||
* @param clearOnFlush true to clear after flushing.
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.kafka.core.KafkaOperations;
|
||||
import org.springframework.kafka.support.KafkaHeaders;
|
||||
@@ -38,8 +37,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class AbstractKafkaChannel extends AbstractMessageChannel {
|
||||
|
||||
protected final LogAccessor logger = new LogAccessor(super.logger); // NOSONAR final
|
||||
|
||||
private final KafkaOperations<?, ?> template;
|
||||
|
||||
protected final String topic; // NOSONAR final
|
||||
@@ -74,8 +71,8 @@ public abstract class AbstractKafkaChannel extends AbstractMessageChannel {
|
||||
protected boolean doSend(Message<?> message, long timeout) {
|
||||
try {
|
||||
this.template.send(MessageBuilder.fromMessage(message)
|
||||
.setHeader(KafkaHeaders.TOPIC, this.topic)
|
||||
.build())
|
||||
.setHeader(KafkaHeaders.TOPIC, this.topic)
|
||||
.build())
|
||||
.get(timeout < 0 ? Long.MAX_VALUE : timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (@SuppressWarnings("unused") InterruptedException e) {
|
||||
|
||||
@@ -348,11 +348,9 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
throw new IllegalArgumentException("Custom consumer factory is not configured with '"
|
||||
+ ConsumerConfig.MAX_POLL_RECORDS_CONFIG + " = 1'");
|
||||
}
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("'" + ConsumerConfig.MAX_POLL_RECORDS_CONFIG
|
||||
+ "' has been forced from " + (maxPoll == null ? "unspecified" : maxPoll)
|
||||
+ " to 1, to avoid having to seek after each record");
|
||||
}
|
||||
this.logger.warn(() -> ConsumerConfig.MAX_POLL_RECORDS_CONFIG
|
||||
+ "' has been forced from " + (maxPoll == null ? "unspecified" : maxPoll)
|
||||
+ " to 1, to avoid having to seek after each record");
|
||||
Map<String, Object> configs = new HashMap<>(suppliedConsumerFactory.getConfigurationProperties());
|
||||
configs.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 1);
|
||||
DefaultKafkaConsumerFactory<K, V> fixedConsumerFactory = new DefaultKafkaConsumerFactory<>(configs);
|
||||
@@ -450,7 +448,7 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
this.consumer.subscribe(topicPattern, rebalanceCallback);
|
||||
}
|
||||
else if (partitions != null) {
|
||||
assignAndSeekPartitionts(partitions);
|
||||
assignAndSeekPartitions(partitions);
|
||||
}
|
||||
else {
|
||||
this.consumer.subscribe(Arrays.asList(this.consumerProperties.getTopics()), // NOSONAR
|
||||
@@ -459,7 +457,7 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
}
|
||||
}
|
||||
|
||||
private void assignAndSeekPartitionts(TopicPartitionOffset[] partitions) {
|
||||
private void assignAndSeekPartitions(TopicPartitionOffset[] partitions) {
|
||||
List<TopicPartition> topicPartitionsToAssign =
|
||||
Arrays.stream(partitions)
|
||||
.map(TopicPartitionOffset::getTopicPartition)
|
||||
@@ -478,7 +476,7 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
TopicPartition topicPartition = partition.getTopicPartition();
|
||||
Long offset = partition.getOffset();
|
||||
if (offset != null) {
|
||||
long newOffset = offset;
|
||||
long newOffset;
|
||||
|
||||
if (offset < 0) {
|
||||
if (!partition.isRelativeToCurrent()) {
|
||||
@@ -490,14 +488,17 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
else if (partition.isRelativeToCurrent()) {
|
||||
newOffset = this.consumer.position(topicPartition) + offset;
|
||||
}
|
||||
else {
|
||||
newOffset = offset;
|
||||
}
|
||||
|
||||
try {
|
||||
this.consumer.seek(topicPartition, newOffset);
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.logger.error("Failed to set initial offset for " + topicPartition
|
||||
catch (Exception ex) {
|
||||
this.logger.error(ex, () -> "Failed to set initial offset for " + topicPartition
|
||||
+ " at " + newOffset + ". Position is " + this.consumer
|
||||
.position(topicPartition), e);
|
||||
.position(topicPartition));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,8 +760,8 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
return i.getRecord().offset();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
if (rewound.size() > 0 && this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Rolled back " + ListenerUtils.recordToString(record, this.logOnlyMetadata)
|
||||
if (rewound.size() > 0) {
|
||||
this.logger.warn(() -> "Rolled back " + ListenerUtils.recordToString(record, this.logOnlyMetadata)
|
||||
+ " later in-flight offsets "
|
||||
+ rewound + " will also be re-fetched");
|
||||
}
|
||||
@@ -770,11 +771,9 @@ public class KafkaMessageSource<K, V> extends AbstractMessageSource<Object> impl
|
||||
|
||||
private void commitIfPossible(ConsumerRecord<K, V> record) { // NOSONAR
|
||||
if (this.ackInfo.isRolledBack()) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Cannot commit offset for "
|
||||
+ ListenerUtils.recordToString(record, this.logOnlyMetadata)
|
||||
+ "; an earlier offset was rolled back");
|
||||
}
|
||||
this.logger.warn(() -> "Cannot commit offset for "
|
||||
+ ListenerUtils.recordToString(record, this.logOnlyMetadata)
|
||||
+ "; an earlier offset was rolled back");
|
||||
}
|
||||
else {
|
||||
Set<KafkaAckInfo<K, V>> candidates = this.ackInfo.getOffsets().get(this.ackInfo.getTopicPartition());
|
||||
|
||||
@@ -69,6 +69,7 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.integration.IntegrationMessageHeaderAccessor;
|
||||
import org.springframework.integration.StaticMessageHeaderAccessor;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallback;
|
||||
@@ -581,15 +582,15 @@ class MessageSourceTests {
|
||||
inOrder.verify(consumer).poll(any(Duration.class));
|
||||
inOrder.verify(consumer).seek(topicPartition, 0L); // rollback
|
||||
inOrder.verify(log1).isWarnEnabled();
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<LogMessage> captor = ArgumentCaptor.forClass(LogMessage.class);
|
||||
inOrder.verify(log1).warn(captor.capture());
|
||||
assertThat(captor.getValue())
|
||||
assertThat(captor.getValue().toString())
|
||||
.contains("Rolled back")
|
||||
.contains("later in-flight offsets [1] will also be re-fetched");
|
||||
inOrder.verify(log2).isWarnEnabled();
|
||||
captor = ArgumentCaptor.forClass(String.class);
|
||||
captor = ArgumentCaptor.forClass(LogMessage.class);
|
||||
inOrder.verify(log2).warn(captor.capture());
|
||||
assertThat(captor.getValue())
|
||||
assertThat(captor.getValue().toString())
|
||||
.contains("Cannot commit offset for ConsumerRecord")
|
||||
.contains("; an earlier offset was rolled back");
|
||||
inOrder.verify(consumer).poll(any(Duration.class));
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.springframework.integration.support.AbstractIntegrationMessageBuilder
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
/**
|
||||
* Base class for {@link MailReceiver} implementations.
|
||||
@@ -326,9 +327,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
}
|
||||
}
|
||||
if (!this.store.isConnected()) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("connecting to store [" + this.store.getURLName() + "]");
|
||||
}
|
||||
this.logger.debug(() -> "connecting to store [" + this.store.getURLName() + "]");
|
||||
this.store.connect();
|
||||
}
|
||||
}
|
||||
@@ -348,9 +347,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
if (this.folder.isOpen()) {
|
||||
return;
|
||||
}
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("opening folder [" + this.folder.getURLName() + "]");
|
||||
}
|
||||
URLName urlName = this.folder.getURLName();
|
||||
this.logger.debug(() -> "opening folder [" + urlName + "]");
|
||||
this.folder.open(this.folderOpenMode);
|
||||
}
|
||||
|
||||
@@ -401,27 +399,25 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
}
|
||||
|
||||
private MimeMessage[] searchAndFilterMessages() throws MessagingException {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("attempting to receive mail from folder [" + this.folder.getFullName() + "]");
|
||||
}
|
||||
this.logger.debug(() -> "attempting to receive mail from folder [" + this.folder.getFullName() + "]");
|
||||
Message[] messagesToProcess;
|
||||
Message[] messages = searchForNewMessages();
|
||||
if (this.maxFetchSize > 0 && messages.length > this.maxFetchSize) {
|
||||
Message[] reducedMessages = new Message[this.maxFetchSize];
|
||||
System.arraycopy(messages, 0, reducedMessages, 0, this.maxFetchSize);
|
||||
messages = reducedMessages;
|
||||
messagesToProcess = reducedMessages;
|
||||
}
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("found " + messages.length + " new messages");
|
||||
else {
|
||||
messagesToProcess = messages;
|
||||
}
|
||||
if (messages.length > 0) {
|
||||
this.logger.debug(() -> "found " + messagesToProcess.length + " new messages");
|
||||
if (messagesToProcess.length > 0) {
|
||||
fetchMessages(messages);
|
||||
}
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Received " + messages.length + " messages");
|
||||
}
|
||||
this.logger.debug(() -> "Received " + messagesToProcess.length + " messages");
|
||||
|
||||
MimeMessage[] filteredMessages = filterMessagesThruSelector(messages);
|
||||
MimeMessage[] filteredMessages = filterMessagesThruSelector(messagesToProcess);
|
||||
|
||||
postProcessFilteredMessages(filteredMessages);
|
||||
return filteredMessages;
|
||||
@@ -465,11 +461,13 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
}
|
||||
content = theMessage.getContent();
|
||||
if (content instanceof String) {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, "text/plain");
|
||||
String mailContentType = (String) headers.get(MailHeaders.CONTENT_TYPE);
|
||||
if (mailContentType != null && mailContentType.toLowerCase().startsWith("text")) {
|
||||
if (MimeTypeUtils.TEXT_PLAIN.getType().equals(mailContentType)) {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, mailContentType);
|
||||
}
|
||||
else {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN_VALUE);
|
||||
}
|
||||
}
|
||||
else if (content instanceof InputStream) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
@@ -494,7 +492,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
}
|
||||
|
||||
private Object byteArrayToContent(Map<String, Object> headers, ByteArrayOutputStream baos) {
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, "application/octet-stream");
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@@ -524,10 +522,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
for (Message message : filteredMessages) {
|
||||
if (!recentFlagSupported) {
|
||||
if (flags != null && flags.contains(Flags.Flag.USER)) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("USER flags are supported by this mail server. Flagging message with '"
|
||||
+ this.userFlag + "' user flag");
|
||||
}
|
||||
this.logger.debug(() -> "USER flags are supported by this mail server. Flagging message with '"
|
||||
+ this.userFlag + "' user flag");
|
||||
Flags siFlags = new Flags();
|
||||
siFlags.add(this.userFlag);
|
||||
message.setFlags(siFlags, true);
|
||||
@@ -556,10 +552,10 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
filteredMessages.add(message);
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Fetched email with subject '" + message.getSubject()
|
||||
+ "' will be discarded by the matching filter and will not be flagged as SEEN.");
|
||||
}
|
||||
String subject = message.getSubject();
|
||||
this.logger.debug(() ->
|
||||
"Fetched email with subject '" + subject
|
||||
+ "' will be discarded by the matching filter and will not be flagged as SEEN.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -660,9 +656,9 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
|
||||
try {
|
||||
complexContent = source.getContent();
|
||||
}
|
||||
catch (IOException e) {
|
||||
complexContent = "Unable to extract content; see logs: " + e.getMessage();
|
||||
AbstractMailReceiver.this.logger.error("Failed to extract content from " + source, e);
|
||||
catch (IOException ex) {
|
||||
complexContent = "Unable to extract content; see logs: " + ex.getMessage();
|
||||
AbstractMailReceiver.this.logger.error(ex, () -> "Failed to extract content from " + source);
|
||||
}
|
||||
this.content = complexContent;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -229,9 +229,7 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport implements Be
|
||||
this.applicationEventPublisher.publishEvent(new ImapIdleExceptionEvent(e));
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
logger.debug(() -> "No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,13 +246,11 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport implements Be
|
||||
ImapIdleChannelAdapter.this.idleTask.run();
|
||||
logger.debug("Task completed successfully. Re-scheduling it again right away.");
|
||||
}
|
||||
catch (Exception e) { //run again after a delay
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to execute IDLE task. Will attempt to resubmit in "
|
||||
+ ImapIdleChannelAdapter.this.reconnectDelay + " milliseconds.", e);
|
||||
}
|
||||
catch (Exception ex) { //run again after a delay
|
||||
logger.warn(ex, () -> "Failed to execute IDLE task. Will attempt to resubmit in "
|
||||
+ ImapIdleChannelAdapter.this.reconnectDelay + " milliseconds.");
|
||||
ImapIdleChannelAdapter.this.receivingTaskTrigger.delayNextExecution();
|
||||
publishException(e);
|
||||
publishException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,9 +272,7 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport implements Be
|
||||
Folder folder = ImapIdleChannelAdapter.this.mailReceiver.getFolder();
|
||||
if (folder != null && folder.isOpen() && isRunning()) {
|
||||
Object[] mailMessages = ImapIdleChannelAdapter.this.mailReceiver.receive();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("received " + mailMessages.length + " mail messages");
|
||||
}
|
||||
logger.debug(() -> "received " + mailMessages.length + " mail messages");
|
||||
for (Object mailMessage : mailMessages) {
|
||||
Runnable messageSendingTask = createMessageSendingTask(mailMessage);
|
||||
if (isRunning()) {
|
||||
@@ -287,14 +281,14 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport implements Be
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
logger.warn("error occurred in idle task", e);
|
||||
catch (MessagingException ex) {
|
||||
logger.warn(ex, "error occurred in idle task");
|
||||
if (ImapIdleChannelAdapter.this.shouldReconnectAutomatically) {
|
||||
throw new IllegalStateException("Failure in 'idle' task. Will resubmit.", e);
|
||||
throw new IllegalStateException("Failure in 'idle' task. Will resubmit.", ex);
|
||||
}
|
||||
else {
|
||||
throw new org.springframework.messaging.MessagingException(
|
||||
"Failure in 'idle' task. Will NOT resubmit.", e);
|
||||
"Failure in 'idle' task. Will NOT resubmit.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -141,7 +141,7 @@ public class ImapMailReceiver extends AbstractMailReceiver {
|
||||
this.isInternalScheduler = true;
|
||||
}
|
||||
Properties javaMailProperties = getJavaMailProperties();
|
||||
for (String name : new String[] { PROTOCOL, "imaps" }) {
|
||||
for (String name : new String[]{ PROTOCOL, "imaps" }) {
|
||||
String peek = "mail." + name + ".peek";
|
||||
if (javaMailProperties.getProperty(peek) == null) {
|
||||
javaMailProperties.setProperty(peek, "true");
|
||||
@@ -270,7 +270,7 @@ public class ImapMailReceiver extends AbstractMailReceiver {
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("Error during resetting idle state.", ex);
|
||||
logger.error(ex, "Error during resetting idle state.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,13 +345,11 @@ public class ImapMailReceiver extends AbstractMailReceiver {
|
||||
}
|
||||
|
||||
private SearchTerm applyTermsWhenNoRecentFlag(Folder folder, SearchTerm searchTerm) {
|
||||
NotTerm notFlagged = null;
|
||||
NotTerm notFlagged;
|
||||
if (folder.getPermanentFlags().contains(Flag.USER)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("This email server does not support RECENT flag, but it does support " +
|
||||
"USER flags which will be used to prevent duplicates during email fetch." +
|
||||
" This receiver instance uses flag: " + getUserFlag());
|
||||
}
|
||||
logger.debug(() -> "This email server does not support RECENT flag, but it does support " +
|
||||
"USER flags which will be used to prevent duplicates during email fetch." +
|
||||
" This receiver instance uses flag: " + getUserFlag());
|
||||
Flags siFlags = new Flags();
|
||||
siFlags.add(getUserFlag());
|
||||
notFlagged = new NotTerm(new FlagTerm(siFlags, true));
|
||||
|
||||
@@ -121,6 +121,7 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
*/
|
||||
public MqttPahoMessageDrivenChannelAdapter(String clientId, MqttPahoClientFactory clientFactory,
|
||||
String... topic) {
|
||||
|
||||
super(null, clientId, topic);
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
@@ -190,7 +191,7 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
String url = getUrl();
|
||||
if (url != null) {
|
||||
options = MqttUtils.cloneConnectOptions(options);
|
||||
options.setServerURIs(new String[] { url });
|
||||
options.setServerURIs(new String[]{ url });
|
||||
}
|
||||
}
|
||||
return options;
|
||||
@@ -203,8 +204,8 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
try {
|
||||
connectAndSubscribe();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Exception while connecting and subscribing, retrying", e);
|
||||
catch (Exception ex) {
|
||||
logger.error(ex, "Exception while connecting and subscribing, retrying");
|
||||
this.scheduleReconnect();
|
||||
}
|
||||
}
|
||||
@@ -222,14 +223,14 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
this.client.unsubscribe(getTopic());
|
||||
}
|
||||
}
|
||||
catch (MqttException e) {
|
||||
logger.error("Exception while unsubscribing", e);
|
||||
catch (MqttException ex) {
|
||||
logger.error(ex, "Exception while unsubscribing");
|
||||
}
|
||||
try {
|
||||
this.client.disconnectForcibly(this.disconnectCompletionTimeout);
|
||||
}
|
||||
catch (MqttException e) {
|
||||
logger.error("Exception while disconnecting", e);
|
||||
catch (MqttException ex) {
|
||||
logger.error(ex, "Exception while disconnecting");
|
||||
}
|
||||
|
||||
this.client.setCallback(null);
|
||||
@@ -237,8 +238,8 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
try {
|
||||
this.client.close();
|
||||
}
|
||||
catch (MqttException e) {
|
||||
logger.error("Exception while closing", e);
|
||||
catch (MqttException ex) {
|
||||
logger.error(ex, "Exception while closing");
|
||||
}
|
||||
this.connected = false;
|
||||
this.client = null;
|
||||
@@ -305,20 +306,18 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
this.client.subscribe(topics, grantedQos);
|
||||
for (int i = 0; i < requestedQos.length; i++) {
|
||||
if (grantedQos[i] != requestedQos[i]) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Granted QOS different to Requested QOS; topics: " + Arrays.toString(topics)
|
||||
+ " requested: " + Arrays.toString(requestedQos)
|
||||
+ " granted: " + Arrays.toString(grantedQos));
|
||||
}
|
||||
logger.warn(() -> "Granted QOS different to Requested QOS; topics: " + Arrays.toString(topics)
|
||||
+ " requested: " + Arrays.toString(requestedQos)
|
||||
+ " granted: " + Arrays.toString(grantedQos));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MqttException e) {
|
||||
catch (MqttException ex) {
|
||||
if (this.applicationEventPublisher != null) {
|
||||
this.applicationEventPublisher.publishEvent(new MqttConnectionFailedEvent(this, e));
|
||||
this.applicationEventPublisher.publishEvent(new MqttConnectionFailedEvent(this, ex));
|
||||
}
|
||||
logger.error("Error connecting or subscribing to " + Arrays.toString(topics), e);
|
||||
logger.error(ex, () -> "Error connecting or subscribing to " + Arrays.toString(topics));
|
||||
this.client.disconnectForcibly(this.disconnectCompletionTimeout);
|
||||
try {
|
||||
this.client.setCallback(null);
|
||||
@@ -328,7 +327,7 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
// NOSONAR
|
||||
}
|
||||
this.client = null;
|
||||
throw e;
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
this.topicLock.unlock();
|
||||
@@ -336,9 +335,7 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
if (this.client.isConnected()) {
|
||||
this.connected = true;
|
||||
String message = "Connected and subscribed to " + Arrays.toString(topics);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(message);
|
||||
}
|
||||
logger.debug(message);
|
||||
if (this.applicationEventPublisher != null) {
|
||||
this.applicationEventPublisher.publishEvent(new MqttSubscribedEvent(this, message));
|
||||
}
|
||||
@@ -357,9 +354,7 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
try {
|
||||
this.reconnectFuture = getTaskScheduler().schedule(() -> {
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Attempting reconnect");
|
||||
}
|
||||
logger.debug("Attempting reconnect");
|
||||
synchronized (MqttPahoMessageDrivenChannelAdapter.this) {
|
||||
if (!MqttPahoMessageDrivenChannelAdapter.this.connected) {
|
||||
connectAndSubscribe();
|
||||
@@ -367,21 +362,21 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MqttException e) {
|
||||
logger.error("Exception while connecting and subscribing", e);
|
||||
catch (MqttException ex) {
|
||||
logger.error(ex, "Exception while connecting and subscribing");
|
||||
scheduleReconnect();
|
||||
}
|
||||
}, new Date(System.currentTimeMillis() + this.recoveryInterval));
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Failed to schedule reconnect", e);
|
||||
catch (Exception ex) {
|
||||
logger.error(ex, "Failed to schedule reconnect");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void connectionLost(Throwable cause) {
|
||||
if (isRunning()) {
|
||||
this.logger.error("Lost connection: " + cause.getMessage() + "; retrying...");
|
||||
this.logger.error(() -> "Lost connection: " + cause.getMessage() + "; retrying...");
|
||||
this.connected = false;
|
||||
if (this.client != null) {
|
||||
try {
|
||||
@@ -411,9 +406,9 @@ public class MqttPahoMessageDrivenChannelAdapter extends AbstractMqttMessageDriv
|
||||
try {
|
||||
sendMessage(message);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
logger.error("Unhandled exception for " + message.toString(), e);
|
||||
throw e;
|
||||
catch (RuntimeException ex) {
|
||||
logger.error(ex, () -> "Unhandled exception for " + message.toString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ public class MqttPahoMessageHandler extends AbstractMqttMessageHandler
|
||||
String url = getUrl();
|
||||
if (url != null) {
|
||||
options = MqttUtils.cloneConnectOptions(options);
|
||||
options.setServerURIs(new String[] { url });
|
||||
options.setServerURIs(new String[]{ url });
|
||||
}
|
||||
}
|
||||
return options;
|
||||
@@ -194,8 +194,8 @@ public class MqttPahoMessageHandler extends AbstractMqttMessageHandler
|
||||
this.client = null;
|
||||
}
|
||||
}
|
||||
catch (MqttException e) {
|
||||
logger.error("Failed to disconnect", e);
|
||||
catch (MqttException ex) {
|
||||
logger.error(ex, "Failed to disconnect");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,11 @@ 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 javax.net.SocketFactory;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttClient;
|
||||
@@ -64,7 +64,8 @@ import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.MqttToken;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.internal.stubbing.answers.CallsRealMethods;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
@@ -74,6 +75,7 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.StaticMessageHeaderAccessor;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
@@ -403,7 +405,7 @@ public class MqttAdapterTests {
|
||||
final IMqttClient client = mock(IMqttClient.class);
|
||||
MqttPahoMessageDrivenChannelAdapter adapter = buildAdapterIn(client, null, ConsumerStopAction.UNSUBSCRIBE_NEVER);
|
||||
adapter.setRecoveryInterval(10);
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(adapter, "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("logger", logger);
|
||||
given(logger.isDebugEnabled()).willReturn(true);
|
||||
final AtomicInteger attemptingReconnectCount = new AtomicInteger();
|
||||
@@ -461,7 +463,7 @@ public class MqttAdapterTests {
|
||||
willReturn(alwaysComplete).given(aClient).connect(any(MqttConnectOptions.class), any(), any());
|
||||
|
||||
IMqttToken token = mock(IMqttToken.class);
|
||||
given(token.getGrantedQos()).willReturn(new int[] { 0x80 });
|
||||
given(token.getGrantedQos()).willReturn(new int[]{ 0x80 });
|
||||
willReturn(token).given(aClient).subscribe(any(String[].class), any(int[].class), isNull(), isNull(), any());
|
||||
|
||||
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter("foo", "bar", factory,
|
||||
@@ -473,11 +475,11 @@ public class MqttAdapterTests {
|
||||
}, m -> m.getName().equals("connectAndSubscribe"));
|
||||
assertThat(method.get()).isNotNull();
|
||||
Condition<InvocationTargetException> subscribeFailed = new Condition<>(ex ->
|
||||
((MqttException) ex.getCause()).getReasonCode() == MqttException.REASON_CODE_SUBSCRIBE_FAILED,
|
||||
"expected the reason code to be REASON_CODE_SUBSCRIBE_FAILED");
|
||||
((MqttException) ex.getCause()).getReasonCode() == MqttException.REASON_CODE_SUBSCRIBE_FAILED,
|
||||
"expected the reason code to be REASON_CODE_SUBSCRIBE_FAILED");
|
||||
assertThatExceptionOfType(InvocationTargetException.class).isThrownBy(() -> method.get().invoke(adapter))
|
||||
.withCauseInstanceOf(MqttException.class)
|
||||
.is(subscribeFailed);
|
||||
.withCauseInstanceOf(MqttException.class)
|
||||
.is(subscribeFailed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -510,7 +512,7 @@ public class MqttAdapterTests {
|
||||
willReturn(alwaysComplete).given(aClient).connect(any(MqttConnectOptions.class), any(), any());
|
||||
|
||||
IMqttToken token = mock(IMqttToken.class);
|
||||
given(token.getGrantedQos()).willReturn(new int[] { 2, 0 });
|
||||
given(token.getGrantedQos()).willReturn(new int[]{ 2, 0 });
|
||||
willReturn(token).given(aClient).subscribe(any(String[].class), any(int[].class), isNull(), isNull(), any());
|
||||
|
||||
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter("foo", "bar", factory,
|
||||
@@ -521,12 +523,15 @@ public class MqttAdapterTests {
|
||||
method.set(m);
|
||||
}, m -> m.getName().equals("connectAndSubscribe"));
|
||||
assertThat(method.get()).isNotNull();
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(adapter, "logger", LogAccessor.class));
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("logger", logger);
|
||||
given(logger.isWarnEnabled()).willReturn(true);
|
||||
method.get().invoke(adapter);
|
||||
verify(logger, atLeastOnce())
|
||||
.warn("Granted QOS different to Requested QOS; topics: [baz, fix] requested: [1, 1] granted: [2, 0]");
|
||||
.warn(ArgumentMatchers.<Supplier<? extends CharSequence>>argThat(logMessage ->
|
||||
logMessage.get()
|
||||
.equals("Granted QOS different to Requested QOS; topics: [baz, fix] " +
|
||||
"requested: [1, 1] granted: [2, 0]")));
|
||||
verify(client).setTimeToWait(30_000L);
|
||||
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("running", Boolean.TRUE);
|
||||
@@ -545,7 +550,7 @@ public class MqttAdapterTests {
|
||||
|
||||
};
|
||||
MqttConnectOptions connectOptions = new MqttConnectOptions();
|
||||
connectOptions.setServerURIs(new String[] { "tcp://localhost:1883" });
|
||||
connectOptions.setServerURIs(new String[]{ "tcp://localhost:1883" });
|
||||
if (cleanSession != null) {
|
||||
connectOptions.setCleanSession(cleanSession);
|
||||
}
|
||||
@@ -572,7 +577,7 @@ public class MqttAdapterTests {
|
||||
|
||||
};
|
||||
MqttConnectOptions connectOptions = new MqttConnectOptions();
|
||||
connectOptions.setServerURIs(new String[] { "tcp://localhost:1883" });
|
||||
connectOptions.setServerURIs(new String[]{ "tcp://localhost:1883" });
|
||||
factory.setConnectionOptions(connectOptions);
|
||||
MqttPahoMessageHandler adapter = new MqttPahoMessageHandler("client", factory);
|
||||
adapter.setDefaultTopic("foo");
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.integration.redis.inbound;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@@ -172,13 +174,14 @@ public class RedisQueueInboundGateway extends MessagingGatewaySupport
|
||||
private void handlePopException(Exception e) {
|
||||
this.listening = false;
|
||||
if (this.active) {
|
||||
logger.error("Failed to execute listening task. Will attempt to resubmit in " + this.recoveryInterval
|
||||
+ " milliseconds.", e);
|
||||
logger.error(e, () ->
|
||||
"Failed to execute listening task. Will attempt to resubmit in " + this.recoveryInterval
|
||||
+ " milliseconds.");
|
||||
publishException(e);
|
||||
sleepBeforeRecoveryAttempt();
|
||||
}
|
||||
else {
|
||||
logger.debug("Failed to execute listening task. " + e.getClass() + ": " + e.getMessage());
|
||||
logger.debug(() -> "Failed to execute listening task. " + e.getClass() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +219,6 @@ public class RedisQueueInboundGateway extends MessagingGatewaySupport
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void getRequestSendAndProduceReply(byte[] value, String uuid) {
|
||||
Message<Object> requestMessage;
|
||||
if (!this.active) {
|
||||
this.template.boundListOps(uuid).rightPush(value);
|
||||
byte[] serialized = StringRedisSerializer.UTF_8.serialize(uuid);
|
||||
@@ -225,12 +227,38 @@ public class RedisQueueInboundGateway extends MessagingGatewaySupport
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Message<Object> requestMessage = prepareRequestMessage(value);
|
||||
|
||||
if (requestMessage != null) {
|
||||
Message<?> replyMessage = sendAndReceiveMessage(requestMessage);
|
||||
if (replyMessage != null) {
|
||||
byte[] replyPayload = null;
|
||||
if (this.extractPayload) {
|
||||
replyPayload = extractReplyPayload(replyMessage);
|
||||
}
|
||||
else {
|
||||
if (this.serializer != null) {
|
||||
replyPayload = ((RedisSerializer<Object>) this.serializer).serialize(replyMessage);
|
||||
}
|
||||
}
|
||||
if (replyPayload != null) {
|
||||
this.template.boundListOps(uuid + QUEUE_NAME_SUFFIX).leftPush(replyPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private Message<Object> prepareRequestMessage(byte[] value) {
|
||||
Message<Object> requestMessage;
|
||||
if (this.extractPayload) {
|
||||
Object payload = value;
|
||||
if (this.serializer != null) {
|
||||
payload = this.serializer.deserialize(value);
|
||||
if (payload == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
requestMessage = getMessageBuilderFactory().withPayload(payload).build();
|
||||
@@ -239,28 +267,14 @@ public class RedisQueueInboundGateway extends MessagingGatewaySupport
|
||||
try {
|
||||
requestMessage = (Message<Object>) this.serializer.deserialize(value);
|
||||
if (requestMessage == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MessagingException("Deserialization of Message failed.", e);
|
||||
}
|
||||
}
|
||||
Message<?> replyMessage = sendAndReceiveMessage(requestMessage);
|
||||
if (replyMessage != null) {
|
||||
byte[] replyPayload = null;
|
||||
if (this.extractPayload) {
|
||||
replyPayload = extractReplyPayload(replyMessage);
|
||||
}
|
||||
else {
|
||||
if (this.serializer != null) {
|
||||
replyPayload = ((RedisSerializer<Object>) this.serializer).serialize(replyMessage);
|
||||
}
|
||||
}
|
||||
if (replyPayload != null) {
|
||||
this.template.boundListOps(uuid + QUEUE_NAME_SUFFIX).leftPush(replyPayload);
|
||||
}
|
||||
}
|
||||
return requestMessage;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -310,9 +324,7 @@ public class RedisQueueInboundGateway extends MessagingGatewaySupport
|
||||
this.applicationEventPublisher.publishEvent(new RedisExceptionEvent(this, e));
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
logger.debug(() -> "No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -241,16 +241,17 @@ public class RedisQueueMessageDrivenEndpoint extends MessageProducerSupport
|
||||
value = this.boundListOperations.leftPop(this.receiveTimeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception ex) {
|
||||
this.listening = false;
|
||||
if (this.active) {
|
||||
logger.error("Failed to execute listening task. Will attempt to resubmit in " + this.recoveryInterval
|
||||
+ " milliseconds.", e);
|
||||
publishException(e);
|
||||
logger.error(ex,
|
||||
"Failed to execute listening task. Will attempt to resubmit in " + this.recoveryInterval
|
||||
+ " milliseconds.");
|
||||
publishException(ex);
|
||||
sleepBeforeRecoveryAttempt();
|
||||
}
|
||||
else {
|
||||
logger.debug("Failed to execute listening task. " + e.getClass() + ": " + e.getMessage());
|
||||
logger.debug(() -> "Failed to execute listening task. " + ex.getClass() + ": " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
@@ -285,9 +286,7 @@ public class RedisQueueMessageDrivenEndpoint extends MessageProducerSupport
|
||||
this.applicationEventPublisher.publishEvent(new RedisExceptionEvent(this, e));
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
logger.debug(() -> "No application event publisher for exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
* Copyright 2014-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.
|
||||
@@ -44,9 +44,9 @@ public class RedisQueueOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
|
||||
private static final int TIMEOUT = 1000;
|
||||
|
||||
private static final IdGenerator defaultIdGenerator = new AlternativeJdkIdGenerator();
|
||||
private static final IdGenerator DEFAULT_ID_GENERATOR = new AlternativeJdkIdGenerator();
|
||||
|
||||
private static final RedisSerializer<String> stringSerializer = new StringRedisSerializer();
|
||||
private static final RedisSerializer<String> STRING_SERIALIZER = new StringRedisSerializer();
|
||||
|
||||
private final RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
|
||||
@@ -109,19 +109,17 @@ public class RedisQueueOutboundGateway extends AbstractReplyProducingMessageHand
|
||||
Object beforeSerialization = value;
|
||||
if (!(value instanceof byte[])) {
|
||||
if (value instanceof String && !this.serializerExplicitlySet) {
|
||||
value = stringSerializer.serialize((String) value);
|
||||
value = STRING_SERIALIZER.serialize((String) value);
|
||||
}
|
||||
else {
|
||||
value = ((RedisSerializer<Object>) this.serializer).serialize(value);
|
||||
}
|
||||
}
|
||||
if (value == null) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Serializer produced null for " + beforeSerialization);
|
||||
}
|
||||
this.logger.debug(() -> "Serializer produced null for " + beforeSerialization);
|
||||
return null;
|
||||
}
|
||||
String uuid = defaultIdGenerator.generateId().toString();
|
||||
String uuid = DEFAULT_ID_GENERATOR.generateId().toString();
|
||||
|
||||
byte[] uuidByte = uuid.getBytes();
|
||||
this.boundListOps.leftPush(uuidByte);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-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.
|
||||
@@ -200,8 +200,8 @@ public class StompInboundChannelAdapter extends MessageProducerSupport implement
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.warn("The exception during unsubscribing.", e);
|
||||
catch (Exception ex) {
|
||||
logger.warn(ex, "The exception during unsubscribing.");
|
||||
}
|
||||
this.subscriptions.clear();
|
||||
}
|
||||
@@ -300,7 +300,7 @@ public class StompInboundChannelAdapter extends MessageProducerSupport implement
|
||||
.send(errorChannel, new ErrorMessage(ex));
|
||||
}
|
||||
else {
|
||||
logger.error(exceptionMessage, exception);
|
||||
logger.error(exception, exceptionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ public class StompMessageHandler extends AbstractMessageHandler
|
||||
eventPublisher.publishEvent(event);
|
||||
}
|
||||
else {
|
||||
logger.error("The receipt [" + receiptable.getReceiptId() + "] is lost for [" +
|
||||
logger.error(() -> "The receipt [" + receiptable.getReceiptId() + "] is lost for [" +
|
||||
message + "] on destination [" + destination + "]");
|
||||
}
|
||||
});
|
||||
@@ -247,7 +247,7 @@ public class StompMessageHandler extends AbstractMessageHandler
|
||||
new StompExceptionEvent(StompMessageHandler.this, exception));
|
||||
}
|
||||
else {
|
||||
logger.error(exception);
|
||||
logger.getLog().error(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,8 @@ public class StompMessageHandler extends AbstractMessageHandler
|
||||
.copyHeaders(headers)
|
||||
.build();
|
||||
}
|
||||
logger.error("The exception for session [" + session + "] on message [" + failedMessage + "]", exception);
|
||||
logger.error(exception,
|
||||
() -> "The exception for session [" + session + "] on message [" + failedMessage + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2019 the original author or authors.
|
||||
* Copyright 2015-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.
|
||||
@@ -22,9 +22,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.integration.mapping.HeaderMapper;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -47,14 +45,14 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class StompHeaderMapper implements HeaderMapper<StompHeaders> {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(StompHeaderMapper.class);
|
||||
private static final LogAccessor LOGGER = new LogAccessor(StompHeaderMapper.class);
|
||||
|
||||
public static final String STOMP_INBOUND_HEADER_NAME_PATTERN = "STOMP_INBOUND_HEADERS";
|
||||
|
||||
public static final String STOMP_OUTBOUND_HEADER_NAME_PATTERN = "STOMP_OUTBOUND_HEADERS";
|
||||
|
||||
private static final String[] STOMP_INBOUND_HEADER_NAMES =
|
||||
new String[] {
|
||||
{
|
||||
StompHeaders.CONTENT_LENGTH,
|
||||
StompHeaders.CONTENT_TYPE,
|
||||
StompHeaders.MESSAGE_ID,
|
||||
@@ -65,7 +63,7 @@ public class StompHeaderMapper implements HeaderMapper<StompHeaders> {
|
||||
private static final List<String> STOMP_INBOUND_HEADER_NAMES_LIST = Arrays.asList(STOMP_INBOUND_HEADER_NAMES);
|
||||
|
||||
private static final String[] STOMP_OUTBOUND_HEADER_NAMES =
|
||||
new String[] {
|
||||
{
|
||||
StompHeaders.CONTENT_LENGTH,
|
||||
StompHeaders.CONTENT_TYPE,
|
||||
StompHeaders.DESTINATION,
|
||||
@@ -217,34 +215,28 @@ public class StompHeaderMapper implements HeaderMapper<StompHeaders> {
|
||||
if (patterns != null && patterns.length > 0) {
|
||||
for (String pattern : patterns) {
|
||||
if (PatternMatchUtils.simpleMatch(pattern, headerName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
}
|
||||
LOGGER.debug(() -> MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
return true;
|
||||
}
|
||||
else if (STOMP_INBOUND_HEADER_NAME_PATTERN.equals(pattern)
|
||||
&& STOMP_INBOUND_HEADER_NAMES_LIST.contains(headerName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
}
|
||||
|
||||
LOGGER.debug(() -> MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
return true;
|
||||
}
|
||||
else if (STOMP_OUTBOUND_HEADER_NAME_PATTERN.equals(pattern)
|
||||
&& (STOMP_OUTBOUND_HEADER_NAMES_LIST.contains(headerName)
|
||||
|| MessageHeaders.CONTENT_TYPE.equals(headerName))) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
}
|
||||
|
||||
LOGGER.debug(() -> MessageFormat.format("headerName=[{0}] WILL be mapped, matched pattern={1}",
|
||||
headerName, pattern));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MessageFormat.format("headerName=[{0}] WILL NOT be mapped", headerName));
|
||||
}
|
||||
LOGGER.debug(() -> MessageFormat.format("headerName=[{0}] WILL NOT be mapped", headerName));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -28,19 +28,20 @@ import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.ip.IpHeaders;
|
||||
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
|
||||
@@ -57,6 +58,8 @@ import org.springframework.messaging.PollableChannel;
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author David Liu
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
@@ -76,7 +79,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
UnicastReceivingChannelAdapter.class);
|
||||
TestingUtilities.waitListening(server, null);
|
||||
UdpSyslogReceivingChannelAdapter adapter = (UdpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE".getBytes("UTF-8");
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE".getBytes(StandardCharsets.UTF_8);
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length, new InetSocketAddress("localhost",
|
||||
server.getPort()));
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
@@ -110,7 +113,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
AbstractServerConnectionFactory.class);
|
||||
TestingUtilities.waitListening(server, null);
|
||||
TcpSyslogReceivingChannelAdapter adapter = (TcpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(adapter, "logger", LogAccessor.class));
|
||||
doReturn(true).when(logger).isDebugEnabled();
|
||||
final CountDownLatch sawLog = new CountDownLatch(1);
|
||||
doAnswer(invocation -> {
|
||||
@@ -121,8 +124,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
return null;
|
||||
}).when(logger).debug(anyString());
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("logger", logger);
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE\n".getBytes("UTF-8");
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE\n".getBytes(StandardCharsets.UTF_8);
|
||||
Socket socket = SocketFactory.getDefault().createSocket("localhost", server.getPort());
|
||||
socket.getOutputStream().write(buf);
|
||||
socket.close();
|
||||
@@ -152,8 +154,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
DefaultMessageConverter defaultMessageConverter = new DefaultMessageConverter();
|
||||
defaultMessageConverter.setAsMap(false);
|
||||
adapter.setConverter(defaultMessageConverter);
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE".getBytes("UTF-8");
|
||||
byte[] buf = "<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE".getBytes(StandardCharsets.UTF_8);
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length, new InetSocketAddress("localhost",
|
||||
adapter.getPort()));
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
@@ -162,7 +163,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
Message<?> message = outputChannel.receive(10000);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getHeaders().get("syslog_HOST")).isEqualTo("WEBERN");
|
||||
assertThat(new String((byte[]) message.getPayload(), "UTF-8"))
|
||||
assertThat(new String((byte[]) message.getPayload(), StandardCharsets.UTF_8))
|
||||
.isEqualTo("<157>JUL 26 22:08:35 WEBERN TESTING[70729]: TEST SYSLOG MESSAGE");
|
||||
assertThat(message.getHeaders().get(IpHeaders.IP_ADDRESS)).isNotNull();
|
||||
adapter.stop();
|
||||
@@ -190,7 +191,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
factory.start();
|
||||
TestingUtilities.waitListening(connectionFactory, null);
|
||||
TcpSyslogReceivingChannelAdapter adapter = (TcpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
LogAccessor logger = spy(TestUtils.getPropertyValue(adapter, "logger", LogAccessor.class));
|
||||
doReturn(true).when(logger).isDebugEnabled();
|
||||
final CountDownLatch sawLog = new CountDownLatch(1);
|
||||
doAnswer(invocation -> {
|
||||
@@ -201,11 +202,10 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
return null;
|
||||
}).when(logger).debug(anyString());
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("logger", logger);
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = ("253 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"]" +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance")
|
||||
.getBytes("UTF-8");
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
Socket socket = SocketFactory.getDefault().createSocket("localhost", connectionFactory.getPort());
|
||||
socket.getOutputStream().write(buf);
|
||||
socket.close();
|
||||
@@ -234,11 +234,10 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
UnicastReceivingChannelAdapter.class);
|
||||
TestingUtilities.waitListening(server, null);
|
||||
UdpSyslogReceivingChannelAdapter adapter = (UdpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = ("<14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"]" +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance")
|
||||
.getBytes("UTF-8");
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length, new InetSocketAddress("localhost",
|
||||
adapter.getPort()));
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2019 the original author or authors.
|
||||
* Copyright 2017-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,7 +42,7 @@ import org.springframework.integration.webflux.support.WebFluxContextUtils;
|
||||
*/
|
||||
public class WebFluxIntegrationConfigurationInitializer implements IntegrationConfigurationInitializer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WebFluxIntegrationConfigurationInitializer.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(WebFluxIntegrationConfigurationInitializer.class);
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
@@ -50,7 +50,7 @@ public class WebFluxIntegrationConfigurationInitializer implements IntegrationCo
|
||||
registerReactiveRequestMappingHandlerMappingIfNecessary((BeanDefinitionRegistry) beanFactory);
|
||||
}
|
||||
else {
|
||||
logger.warn("'IntegrationRequestMappingHandlerMapping' isn't registered because 'beanFactory'" +
|
||||
LOGGER.warn("'IntegrationRequestMappingHandlerMapping' isn't registered because 'beanFactory'" +
|
||||
" isn't an instance of `BeanDefinitionRegistry`.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
* Copyright 2014-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.
|
||||
@@ -138,13 +138,16 @@ public class WebSocketOutboundMessageHandler extends AbstractMessageHandler {
|
||||
|
||||
@Override
|
||||
protected void handleMessageInternal(Message<?> message) {
|
||||
String sessionId = null;
|
||||
String sessionId;
|
||||
if (!this.client) {
|
||||
sessionId = this.subProtocolHandlerRegistry.resolveSessionId(message);
|
||||
if (sessionId == null) {
|
||||
throw new IllegalArgumentException("The WebSocket 'sessionId' is required in the MessageHeaders");
|
||||
}
|
||||
}
|
||||
else {
|
||||
sessionId = null;
|
||||
}
|
||||
WebSocketSession session = this.webSocketContainer.getSession(sessionId);
|
||||
try {
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
|
||||
@@ -160,11 +163,11 @@ public class WebSocketOutboundMessageHandler extends AbstractMessageHandler {
|
||||
}
|
||||
catch (SessionLimitExceededException ex) {
|
||||
try {
|
||||
logger.error("Terminating session id '" + sessionId + "'", ex);
|
||||
logger.error(ex, () -> "Terminating session id '" + sessionId + "'");
|
||||
this.webSocketContainer.closeSession(session, ex.getStatus());
|
||||
}
|
||||
catch (Exception secondException) {
|
||||
logger.error("Exception terminating session id '" + sessionId + "'", secondException);
|
||||
logger.error(secondException, () -> "Exception terminating session id '" + sessionId + "'");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -96,7 +96,7 @@ public class WebServiceOutboundGatewayParser extends AbstractOutboundGatewayPars
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override // NOSONAR
|
||||
protected void postProcessGateway(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
|
||||
parseMarshallerAttribute(builder, element, parserContext);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2016-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.
|
||||
@@ -39,7 +39,9 @@ import org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter;
|
||||
*
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 4.3
|
||||
*
|
||||
* @see org.springframework.ws.config.annotation.EnableWs
|
||||
* @see org.springframework.ws.server.MessageDispatcher
|
||||
*/
|
||||
@@ -47,7 +49,7 @@ public class WsIntegrationConfigurationInitializer implements IntegrationConfigu
|
||||
|
||||
private static final String MESSAGE_ENDPOINT_ADAPTER_BEAN_NAME = "integrationWsMessageEndpointAdapter";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WsIntegrationConfigurationInitializer.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(WsIntegrationConfigurationInitializer.class);
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
@@ -61,7 +63,7 @@ public class WsIntegrationConfigurationInitializer implements IntegrationConfigu
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.warn("'IntegrationRequestMappingHandlerMapping' isn't registered because 'beanFactory'" +
|
||||
LOGGER.warn("'IntegrationRequestMappingHandlerMapping' isn't registered because 'beanFactory'" +
|
||||
" isn't an instance of `BeanDefinitionRegistry`.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.xmpp.inbound;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
@@ -31,7 +32,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.jivesoftware.smack.StanzaListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
@@ -39,7 +39,7 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.gcm.packet.GcmPacketExtension;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -49,6 +49,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
@@ -67,11 +68,10 @@ import org.springframework.messaging.support.ErrorMessage;
|
||||
*/
|
||||
public class ChatMessageListeningEndpointTests {
|
||||
|
||||
|
||||
@Test
|
||||
/*
|
||||
* Should add/remove StanzaListener when endpoint started/stopped
|
||||
*/
|
||||
@Test
|
||||
public void testLifecycle() {
|
||||
final Set<StanzaListener> packetListSet = new HashSet<>();
|
||||
XMPPConnection connection = mock(XMPPConnection.class);
|
||||
@@ -99,10 +99,11 @@ public class ChatMessageListeningEndpointTests {
|
||||
assertThat(packetListSet.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testNonInitializationFailure() {
|
||||
ChatMessageListeningEndpoint endpoint = new ChatMessageListeningEndpoint(mock(XMPPConnection.class));
|
||||
endpoint.start();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(endpoint::start);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -116,11 +117,12 @@ public class ChatMessageListeningEndpointTests {
|
||||
assertThat(TestUtils.getPropertyValue(endpoint, "xmppConnection")).isNotNull();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testNoXmppConnection() {
|
||||
ChatMessageListeningEndpoint endpoint = new ChatMessageListeningEndpoint();
|
||||
endpoint.setBeanFactory(mock(BeanFactory.class));
|
||||
endpoint.afterPropertiesSet();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(endpoint::afterPropertiesSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -181,7 +183,7 @@ public class ChatMessageListeningEndpointTests {
|
||||
assertThat(((Message) payload).getStanzaId()).isEqualTo(smackMessage.getStanzaId());
|
||||
assertThat(((Message) payload).getBody()).isEqualTo(smackMessage.getBody());
|
||||
|
||||
Log logger = Mockito.spy(TestUtils.getPropertyValue(endpoint, "logger", Log.class));
|
||||
LogAccessor logger = Mockito.spy(TestUtils.getPropertyValue(endpoint, "logger", LogAccessor.class));
|
||||
given(logger.isInfoEnabled()).willReturn(true);
|
||||
final CountDownLatch logLatch = new CountDownLatch(1);
|
||||
willAnswer(invocation -> {
|
||||
|
||||
@@ -150,7 +150,8 @@ public class ZeroMqChannel extends AbstractMessageChannel implements Subscribabl
|
||||
setConnectUrl("tcp://localhost:" + this.zeroMqProxy.getFrontendPort() +
|
||||
':' + this.zeroMqProxy.getBackendPort()))
|
||||
.doOnError((error) ->
|
||||
logger.error("The provided '" + this.zeroMqProxy + "' has not been started", error));
|
||||
logger.error(error,
|
||||
() -> "The provided '" + this.zeroMqProxy + "' has not been started"));
|
||||
}
|
||||
else {
|
||||
return Mono.empty();
|
||||
@@ -213,7 +214,8 @@ public class ZeroMqChannel extends AbstractMessageChannel implements Subscribabl
|
||||
})
|
||||
.publishOn(Schedulers.parallel())
|
||||
.map(this.messageMapper::toMessage)
|
||||
.doOnError((error) -> logger.error("Error processing ZeroMQ message in the " + this, error))
|
||||
.doOnError((error) -> logger.error(error,
|
||||
() -> "Error processing ZeroMQ message in the " + this))
|
||||
.repeatWhenEmpty((repeat) ->
|
||||
this.initialized
|
||||
? repeat.delayElements(this.consumeDelay)
|
||||
|
||||
@@ -270,7 +270,8 @@ public class ZeroMqMessageProducer extends MessageProducerSupport {
|
||||
})
|
||||
.publishOn(Schedulers.boundedElastic())
|
||||
.transform((msgMono) -> this.receiveRaw ? mapRaw(msgMono) : convertMessage(msgMono))
|
||||
.doOnError((error) -> logger.error("Error processing ZeroMQ message in the " + this, error))
|
||||
.doOnError((error) ->
|
||||
logger.error(error, () -> "Error processing ZeroMQ message in the " + this))
|
||||
.repeatWhenEmpty((repeat) ->
|
||||
this.active ? repeat.delayElements(this.consumeDelay) : repeat)
|
||||
.repeat(() -> this.active)
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.expression.ExpressionUtils;
|
||||
import org.springframework.integration.expression.SupplierExpression;
|
||||
import org.springframework.integration.handler.AbstractReactiveMessageHandler;
|
||||
import org.springframework.integration.mapping.ConvertingBytesMessageMapper;
|
||||
import org.springframework.integration.mapping.OutboundMessageMapper;
|
||||
@@ -73,7 +74,7 @@ public class ZeroMqMessageHandler extends AbstractReactiveMessageHandler {
|
||||
|
||||
private Consumer<ZMQ.Socket> socketConfigurer = (socket) -> { };
|
||||
|
||||
private Expression topicExpression = new LiteralExpression(null);
|
||||
private Expression topicExpression = new SupplierExpression<>(() -> null);
|
||||
|
||||
private EvaluationContext evaluationContext;
|
||||
|
||||
|
||||
@@ -210,11 +210,11 @@ public class ZookeeperMetadataStore implements ListenableMetadataStore, SmartLif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.updateMap.containsKey(key)) {
|
||||
// our version is more recent than the cache
|
||||
if (this.updateMap.get(key).getVersion() >= currentData.getStat().getVersion()) {
|
||||
return this.updateMap.get(key).getValue();
|
||||
}
|
||||
// our version is more recent than the cache
|
||||
if (this.updateMap.containsKey(key) &&
|
||||
this.updateMap.get(key).getVersion() >= currentData.getStat().getVersion()) {
|
||||
|
||||
return this.updateMap.get(key).getValue();
|
||||
}
|
||||
return IntegrationUtils.bytesToString(currentData.getData(), this.encoding);
|
||||
}
|
||||
@@ -352,20 +352,20 @@ public class ZookeeperMetadataStore implements ListenableMetadataStore, SmartLif
|
||||
IntegrationUtils.bytesToString(event.getData().getData(), ZookeeperMetadataStore.this.encoding);
|
||||
switch (event.getType()) {
|
||||
case CHILD_ADDED:
|
||||
if (ZookeeperMetadataStore.this.updateMap.containsKey(eventKey)) {
|
||||
if (event.getData().getStat().getVersion() >=
|
||||
ZookeeperMetadataStore.this.updateMap.get(eventKey).getVersion()) {
|
||||
ZookeeperMetadataStore.this.updateMap.remove(eventPath);
|
||||
}
|
||||
if (ZookeeperMetadataStore.this.updateMap.containsKey(eventKey) &&
|
||||
event.getData().getStat().getVersion() >=
|
||||
ZookeeperMetadataStore.this.updateMap.get(eventKey).getVersion()) {
|
||||
|
||||
ZookeeperMetadataStore.this.updateMap.remove(eventPath);
|
||||
}
|
||||
ZookeeperMetadataStore.this.listeners.forEach((listener) -> listener.onAdd(eventKey, value));
|
||||
break;
|
||||
case CHILD_UPDATED:
|
||||
if (ZookeeperMetadataStore.this.updateMap.containsKey(eventKey)) {
|
||||
if (event.getData().getStat().getVersion() >=
|
||||
ZookeeperMetadataStore.this.updateMap.get(eventKey).getVersion()) {
|
||||
ZookeeperMetadataStore.this.updateMap.remove(eventPath);
|
||||
}
|
||||
if (ZookeeperMetadataStore.this.updateMap.containsKey(eventKey) &&
|
||||
event.getData().getStat().getVersion() >=
|
||||
ZookeeperMetadataStore.this.updateMap.get(eventKey).getVersion()) {
|
||||
|
||||
ZookeeperMetadataStore.this.updateMap.remove(eventPath);
|
||||
}
|
||||
ZookeeperMetadataStore.this.listeners.forEach((listener) -> listener.onUpdate(eventKey, value));
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user