Use LogAccessor from SF

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

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();
}

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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.");
}

View File

@@ -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();

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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.");
}
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();

View File

@@ -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) {

View File

@@ -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);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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())) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);

View File

@@ -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 -> {

View File

@@ -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();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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 {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);

View File

@@ -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");
}

View File

@@ -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();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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");
}
}

View File

@@ -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) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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));
}
}

View File

@@ -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);

View File

@@ -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 + "'");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();
}
}

View File

@@ -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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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() {
}
}

View File

@@ -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);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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.

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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));

View File

@@ -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;
}
}

View File

@@ -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");
}
}

View File

@@ -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");

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();

View File

@@ -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`.");
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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`.");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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 -> {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;