Skip to content

Loading…

INT-2951 Add Context Id to Dispatcher has no Subs. #758

Closed
wants to merge 1 commit into from

3 participants

@garyrussell
Spring member

Provide the context id in the 'Dispatcher has no Subscribers'
message.

Ease debugging when more than one context in an application.

@ghillert ghillert commented on an outdated diff
.../integration/channel/AbstractSubscribableChannel.java
@@ -79,8 +90,10 @@ protected boolean doSend(Message<?> message, long timeout) {
catch (MessageDispatchingException e) {
String componentName = this.getComponentName();
componentName = StringUtils.hasText(componentName) ? componentName : "unknown";
- throw new MessageDeliveryException(message, e.getMessage()
- + " for channel " + componentName + ".", e);
+ String description = e.getMessage() + " for channel " + componentName +
+ (this.applicationContext == null ? "" : " in context " + this.applicationContext.getId()) +
@ghillert Spring member
ghillert added a note

Would it be possibly better to wrap the context id in single quotes to improve readability?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ghillert
Spring member

Except for my other comment looks good.

@garyrussell
Spring member

Thanks, Gunnar - I am withdrawing this for now because I have realized we need a common utility method to build the message - there is similar logic in the amqp and jms (and possibly other) channels.

@garyrussell garyrussell closed this
@garyrussell
Spring member

Reopened - refactored to a single support method - added subclass AbstractMessageChannelSupport (subclass of IntegrationObjectSupport).

@garyrussell garyrussell reopened this
@ghillert ghillert commented on an outdated diff
...ntegration/channel/AbstractMessageChannelSupport.java
((10 lines not shown))
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.channel;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.integration.context.IntegrationObjectSupport;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Gary Russell
@ghillert Spring member

Maybe add a quick JavaDoc comment here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ghillert ghillert commented on an outdated diff
...ntegration/channel/AbstractMessageChannelSupport.java
((30 lines not shown))
+ implements ApplicationContextAware {
+
+ private volatile ApplicationContext applicationContext;
+
+ private volatile String cachedChannelId;
+
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ public String getChannelId() {
+ if (this.cachedChannelId == null) {
+ String componentName = this.getComponentName();
+ componentName = StringUtils.hasText(componentName) ? componentName : "unknown";
+ this.cachedChannelId = "'" + componentName +
+ (this.applicationContext == null ? "" : "' in context '" + this.applicationContext.getId()) +
@ghillert Spring member

Super-minor - The getChannelId message is basically for logging purposes only, e.g. contains formatting with single-quotes etc.. At least add some JavaDoc to the method explaining what this method will return. Somebody may think "getChannelId" could be useful for non-logging purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ghillert
Spring member

Besides the minor comments - LGTM.

@garyrussell
Spring member

Gunnar - I decided to remove that intermediate AbstractMessageChannelSupport class and promote the method to IntegrationObjectSupport and renamed it to getExtendedComponentName(). (It may be useful for other components in future).

The only contentious (I think) issue is IOS now implements both BeanFactoryAware and ApplicationContextAware which looks a little odd to me. However removing BeanFactoryAware would mean changing a gazillion test cases that set the BeanFactory (nearly 300 compile errors).

But, I'm not really happy with it. Need @markfisher 's opinion.

@markfisher
Spring member

Sorry, I'm a bit late to the party, but I'm wondering if we should just provide getApplicationContextId() on IOS and then rather than calling getExtendedComponentName(), just do the prepend if that id is available. I know it's more work at that level, but it does keep the IOS more generically useful (maybe some future use-case will require knowing the id but not necessarily combining it with the component name).

@garyrussell
Spring member

Makes sense - but how do you feel about IOS implementing both BFA and ACA?

Also, I would really prefer to NOT prepend the id if it was 'automatically' generated but I don't see a clean way to do that. I suppose we could test for the id being ObjectUtils.identityToString(ac) and return null in that case, but it seems dirty to me. That said, the default id really doesn't add any value to the log messages - you will recall this whole thing came about because of the difficulty debugging with multiple child contexts containing the same channel name.

@markfisher
Spring member

I'm not sure about the BFA and ACA. On one hand, the original thinking was "simple as necessary"... the components could be loaded in a light BeanFactory without being in an ApplicationContext. However, practically speaking, it's probably safe to assume AC all the time, in which case it does seem superfluous to support both interfaces.

It still might be worth displaying the AC id no matter what. For one thing, that will make it clear that providing an explicit ID would make the message more useful. Although that's only immediately obvious for people who are starting from a main() method bootstrap or something similar.

@garyrussell
Spring member

Yeah - problem is removing BFA means changing nearly 300 tests. I can do that as part of this, or maybe open another JIRA.

@markfisher
Spring member

I would say go ahead and merge this one with both BFA and ACA for now. Maybe create another issue in the backlog to remove the need for BFA (and hence modification of all those tests).

@garyrussell garyrussell INT-2951 Add Context Id to Dispatcher has no Subs.
https://jira.springsource.org/browse/INT-2951

Provide the context id in the 'Dispatcher has no Subscribers'
message.

Ease debugging when more than one context in an application.

INT-2951 Polishing

PR Comments - add quotes to context Id in log message.

Polishing

INT-2951 Polishing

Change IOS to have a simple getApplicationContextId() and
add a method getFullChannelName() to AbstractMessageChannel.
498f296
@garyrussell
Spring member

Addressed Mark's suggestion; squashed, rebased, pushed.

Should be mergeable after a quick final review.

@ghillert
Spring member

LGTM - merging.

@ghillert ghillert closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 30, 2013
  1. @garyrussell

    INT-2951 Add Context Id to Dispatcher has no Subs.

    garyrussell committed
    https://jira.springsource.org/browse/INT-2951
    
    Provide the context id in the 'Dispatcher has no Subscribers'
    message.
    
    Ease debugging when more than one context in an application.
    
    INT-2951 Polishing
    
    PR Comments - add quotes to context Id in log message.
    
    Polishing
    
    INT-2951 Polishing
    
    Change IOS to have a simple getApplicationContextId() and
    add a method getFullChannelName() to AbstractMessageChannel.
View
16 ...in/java/org/springframework/integration/amqp/channel/AbstractSubscribableAmqpChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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,6 @@
import org.springframework.integration.dispatcher.MessageDispatcher;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
/**
* @author Mark Fisher
@@ -104,7 +103,7 @@ public void onInit() throws Exception {
? ((RabbitTemplate) this.getAmqpTemplate()).getMessageConverter()
: new SimpleMessageConverter();
MessageListener listener = new DispatchingMessageListener(converter,
- this.dispatcher, this.channelName, this.isPubSub);
+ this.dispatcher, this, this.isPubSub);
this.container.setMessageListener(listener);
if (!this.container.isActive()) {
this.container.afterPropertiesSet();
@@ -124,17 +123,17 @@ public void onInit() throws Exception {
private final MessageConverter converter;
- private final String channelName;
+ private final AbstractSubscribableAmqpChannel channel;
private final boolean isPubSub;
private DispatchingMessageListener(MessageConverter converter,
- MessageDispatcher dispatcher, String channelName, boolean isPubSub) {
+ MessageDispatcher dispatcher, AbstractSubscribableAmqpChannel channel, boolean isPubSub) {
Assert.notNull(converter, "MessageConverter must not be null");
Assert.notNull(dispatcher, "MessageDispatcher must not be null");
this.converter = converter;
this.dispatcher = dispatcher;
- this.channelName = channelName;
+ this.channel = channel;
this.isPubSub = isPubSub;
}
@@ -153,9 +152,8 @@ else if (this.logger.isWarnEnabled()) {
}
}
catch (MessageDispatchingException e) {
- String channelName = StringUtils.hasText(this.channelName) ? this.channelName : "unknown";
- String exceptionMessage = e.getMessage() + " for amqp-channel "
- + channelName + ".";
+ String exceptionMessage = e.getMessage() + " for amqp-channel '"
+ + this.channel.getFullChannelName() + "'.";
if (this.isPubSub) {
// log only for backwards compatibility with pub/sub
if (logger.isWarnEnabled()) {
View
10 ...st/java/org/springframework/integration/amqp/channel/DispatcherHasNoSubscribersTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -71,6 +71,7 @@ public Channel answer(InvocationOnMock invocation) throws Throwable {
PointToPointSubscribableAmqpChannel amqpChannel = new PointToPointSubscribableAmqpChannel("noSubscribersChannel",
container, amqpTemplate);
+ amqpChannel.setBeanName("noSubscribersChannel");
amqpChannel.afterPropertiesSet();
MessageListener listener = (MessageListener) container.getMessageListener();
@@ -79,7 +80,7 @@ public Channel answer(InvocationOnMock invocation) throws Throwable {
fail("Exception expected");
}
catch (MessageDeliveryException e) {
- assertEquals("Dispatcher has no subscribers for amqp-channel noSubscribersChannel.", e.getMessage());
+ assertEquals("Dispatcher has no subscribers for amqp-channel 'noSubscribersChannel'.", e.getMessage());
}
}
@@ -98,12 +99,13 @@ public Channel answer(InvocationOnMock invocation) throws Throwable {
AmqpTemplate amqpTemplate = mock(AmqpTemplate.class);
final Queue queue = new Queue("noSubscribersQueue");
PublishSubscribeAmqpChannel amqpChannel = new PublishSubscribeAmqpChannel("noSubscribersChannel",
- container, amqpTemplate) {
+ container, amqpTemplate) {
@Override
protected Queue initializeQueue(AmqpAdmin admin,
String channelName) {
return queue;
}};
+ amqpChannel.setBeanName("noSubscribersChannel");
amqpChannel.afterPropertiesSet();
List<String> logList = insertMockLoggerInListener(amqpChannel);
@@ -142,7 +144,7 @@ private void verifyLogReceived(final List<String> logList) {
assertNotNull("Failed to get expected exception", message);
if (message.startsWith("Dispatcher has no subscribers")) {
expectedExceptionFound = true;
- assertEquals("Dispatcher has no subscribers for amqp-channel noSubscribersChannel.", message);
+ assertEquals("Dispatcher has no subscribers for amqp-channel 'noSubscribersChannel'.", message);
break;
}
}
View
39 ...on-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2013 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,9 +40,10 @@
* properties such as the channel name. Also provides the common functionality
* for sending and receiving {@link Message Messages} including the invocation
* of any {@link ChannelInterceptor ChannelInterceptors}.
- *
+ *
* @author Mark Fisher
* @author Oleg Zhurakousky
+ * @author Gary Russell
*/
public abstract class AbstractMessageChannel extends IntegrationObjectSupport implements MessageChannel, TrackableComponent {
@@ -54,7 +55,10 @@
private final ChannelInterceptorList interceptors = new ChannelInterceptorList();
+ private volatile String fullChannelName;
+
+ @Override
public String getComponentType() {
return "channel";
}
@@ -66,7 +70,7 @@ public void setShouldTrack(boolean shouldTrack) {
/**
* Specify the Message payload datatype(s) supported by this channel. If a
* payload type does not match directly, but the 'conversionService' is
- * available, then type conversion will be attempted in the order of the
+ * available, then type conversion will be attempted in the order of the
* elements provided in this array.
* <p>
* If this property is not set explicitly, any Message payload type will be
@@ -103,6 +107,7 @@ public void addInterceptor(ChannelInterceptor interceptor) {
* Finally, if that bean is not available, it will fallback to the
* "conversionService" bean, if available.
*/
+ @Override
public void setConversionService(ConversionService conversionService) {
super.setConversionService(conversionService);
}
@@ -115,12 +120,28 @@ protected ChannelInterceptorList getInterceptors() {
}
/**
+ * Returns the fully qualified channel name including the application context
+ * id, if available.
+ * @return The name.
+ */
+ public String getFullChannelName() {
+ if (this.fullChannelName == null) {
+ String contextId = this.getApplicationContextId();
+ String componentName = this.getComponentName();
+ componentName = (StringUtils.hasText(contextId) ? contextId + "." : "") +
+ (StringUtils.hasText(componentName) ? componentName : "unknown.channel.name");
+ this.fullChannelName = componentName;
+ }
+ return this.fullChannelName;
+ }
+
+ /**
* Send a message on this channel. If the channel is at capacity, this
* method will block until either space becomes available or the sending
* thread is interrupted.
- *
+ *
* @param message the Message to send
- *
+ *
* @return <code>true</code> if the message is sent successfully or
* <code>false</code> if the sending thread is interrupted.
*/
@@ -134,10 +155,10 @@ public final boolean send(Message<?> message) {
* is interrupted. If the specified timeout is 0, the method will return
* immediately. If less than zero, it will block indefinitely (see
* {@link #send(Message)}).
- *
+ *
* @param message the Message to send
* @param timeout the timeout in milliseconds
- *
+ *
* @return <code>true</code> if the message is sent successfully,
* <code>false</code> if the message cannot be sent within the allotted
* time or the sending thread is interrupted.
@@ -185,8 +206,8 @@ public final boolean send(Message<?> message, long timeout) {
}
}
throw new MessageDeliveryException(message, "Channel '" + this.getComponentName() +
- "' expected one of the following datataypes [" +
- StringUtils.arrayToCommaDelimitedString(this.datatypes) +
+ "' expected one of the following datataypes [" +
+ StringUtils.arrayToCommaDelimitedString(this.datatypes) +
"], but received [" + message.getPayload().getClass() + "]");
}
View
14 ...re/src/main/java/org/springframework/integration/channel/AbstractSubscribableChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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,7 +27,6 @@
import org.springframework.integration.dispatcher.AbstractDispatcher;
import org.springframework.integration.dispatcher.MessageDispatcher;
import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
/**
* Base implementation of {@link MessageChannel} that invokes the subscribed
@@ -37,7 +36,8 @@
* @author Oleg Zhurakousky
* @author Gary Russell
*/
-public abstract class AbstractSubscribableChannel extends AbstractMessageChannel implements SubscribableChannel {
+public abstract class AbstractSubscribableChannel extends AbstractMessageChannel
+ implements SubscribableChannel {
private final AtomicInteger handlerCounter = new AtomicInteger();
@@ -66,7 +66,7 @@ private void adjustCounterIfNecessary(MessageDispatcher dispatcher, int delta) {
counter = handlerCounter.addAndGet(delta);
}
if (logger.isInfoEnabled()) {
- logger.info("Channel '" + this.getComponentName() + "' has " + counter + " subscriber(s).");
+ logger.info("Channel '" + this.getFullChannelName() + "' has " + counter + " subscriber(s).");
}
}
}
@@ -77,10 +77,8 @@ protected boolean doSend(Message<?> message, long timeout) {
return this.getRequiredDispatcher().dispatch(message);
}
catch (MessageDispatchingException e) {
- String componentName = this.getComponentName();
- componentName = StringUtils.hasText(componentName) ? componentName : "unknown";
- throw new MessageDeliveryException(message, e.getMessage()
- + " for channel " + componentName + ".", e);
+ String description = e.getMessage() + " for channel '" + this.getFullChannelName() + "'.";
+ throw new MessageDeliveryException(message, description, e);
}
}
View
24 ...-core/src/main/java/org/springframework/integration/context/IntegrationObjectSupport.java
@@ -18,11 +18,14 @@
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.BeanInitializationException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.Assert;
@@ -41,8 +44,10 @@
* @author Oleg Zhurakousky
* @author Josh Long
* @author Stefan Ferstl
+ * @author Gary Russell
*/
-public abstract class IntegrationObjectSupport implements BeanNameAware, NamedComponent, BeanFactoryAware, InitializingBean {
+public abstract class IntegrationObjectSupport implements BeanNameAware, NamedComponent,
+ ApplicationContextAware, BeanFactoryAware, InitializingBean {
/**
* Logger that is available to subclasses
@@ -59,6 +64,7 @@
private volatile ConversionService conversionService;
+ private volatile ApplicationContext applicationContext;
public final void setBeanName(String beanName) {
this.beanName = beanName;
@@ -89,10 +95,15 @@ public String getComponentType() {
}
public final void setBeanFactory(BeanFactory beanFactory) {
- Assert.notNull(beanFactory, "beanFactory must not be null");
+ Assert.notNull(beanFactory, "'beanFactory' must not be null");
this.beanFactory = beanFactory;
}
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ Assert.notNull(applicationContext, "'applicationContext' must not be null");
+ this.applicationContext = applicationContext;
+ }
+
public final void afterPropertiesSet() {
try {
this.onInit();
@@ -147,6 +158,15 @@ protected void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
+ /**
+ * Returns the {@link ApplicationContext#getId()} if the
+ * {@link ApplicationContext} is available.
+ * @return The id, or null if there is no application context.
+ */
+ public String getApplicationContextId() {
+ return this.applicationContext == null ? null : this.applicationContext.getId();
+ }
+
@Override
public String toString() {
return (this.beanName != null) ? this.beanName : super.toString();
View
33 ...rc/test/java/org/springframework/integration/channel/DispatcherHasNoSubscribersTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -15,11 +15,14 @@
*/
package org.springframework.integration.channel;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.message.GenericMessage;
@@ -41,14 +44,21 @@
@Autowired
MessageChannel subscribedChannel;
+ @Autowired
+ AbstractApplicationContext applicationContext;
+
+ @Before
+ public void setup() {
+ applicationContext.setId("foo");
+ }
+
@Test
public void oneChannel() {
try {
noSubscribersChannel.send(new GenericMessage<String>("Hello, world!"));
fail("Exception expected");
} catch (MessagingException e) {
- assertEquals("Dispatcher has no subscribers for channel noSubscribersChannel.", e.getMessage());
- assertEquals("Dispatcher has no subscribers for channel noSubscribersChannel.", e.getLocalizedMessage());
+ assertEquals("Dispatcher has no subscribers for channel 'foo.noSubscribersChannel'.", e.getMessage());
}
}
@@ -58,8 +68,19 @@ public void stackedChannels() {
subscribedChannel.send(new GenericMessage<String>("Hello, world!"));
fail("Exception expected");
} catch (MessagingException e) {
- assertEquals("Dispatcher has no subscribers for channel noSubscribersChannel.", e.getMessage());
- assertEquals("Dispatcher has no subscribers for channel noSubscribersChannel.", e.getLocalizedMessage());
+ assertEquals("Dispatcher has no subscribers for channel 'foo.noSubscribersChannel'.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void withNoContext() {
+ DirectChannel channel = new DirectChannel();
+ channel.setBeanName("bar");
+ try {
+ channel.send(new GenericMessage<String>("Hello, world!"));
+ fail("Exception expected");
+ } catch (MessagingException e) {
+ assertEquals("Dispatcher has no subscribers for channel 'bar'.", e.getMessage());
}
}
View
14 ...gration-jms/src/main/java/org/springframework/integration/jms/SubscribableJmsChannel.java
@@ -37,7 +37,6 @@
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
/**
* @author Mark Fisher
@@ -89,7 +88,7 @@ public void onInit() throws Exception {
this.configureDispatcher(isPubSub);
MessageListener listener = new DispatchingMessageListener(
this.getJmsTemplate(), this.dispatcher,
- this.getComponentName(), isPubSub);
+ this, isPubSub);
this.container.setMessageListener(listener);
if (!this.container.isActive()) {
this.container.afterPropertiesSet();
@@ -118,16 +117,16 @@ private void configureDispatcher(boolean isPubSub) {
private final MessageDispatcher dispatcher;
- private final String channelName;
+ private final SubscribableJmsChannel channel;
private final boolean isPubSub;
private DispatchingMessageListener(JmsTemplate jmsTemplate,
- MessageDispatcher dispatcher, String channelName, boolean isPubSub) {
+ MessageDispatcher dispatcher, SubscribableJmsChannel channel, boolean isPubSub) {
this.jmsTemplate = jmsTemplate;
this.dispatcher = dispatcher;
- this.channelName = channelName;
+ this.channel = channel;
this.isPubSub = isPubSub;
}
@@ -146,9 +145,8 @@ else if (this.logger.isWarnEnabled()) {
}
}
catch (MessageDispatchingException e) {
- String channelName = StringUtils.hasText(this.channelName) ? this.channelName : "unknown";
- String exceptionMessage = e.getMessage() + " for jms-channel "
- + channelName + ".";
+ String exceptionMessage = e.getMessage() + " for jms-channel '"
+ + this.channel.getFullChannelName() + "'.";
if (this.isPubSub) {
// log only for backwards compatibility with pub/sub
if (logger.isWarnEnabled()) {
View
4 ...on-jms/src/test/java/org/springframework/integration/jms/SubscribableJmsChannelTests.java
@@ -292,7 +292,7 @@ public void dispatcherHasNoSubscribersQueue() throws Exception {
fail("Exception expected");
}
catch (MessageDeliveryException e) {
- assertEquals("Dispatcher has no subscribers for jms-channel noSubscribersChannel.", e.getMessage());
+ assertEquals("Dispatcher has no subscribers for jms-channel 'noSubscribersChannel'.", e.getMessage());
}
}
@@ -346,7 +346,7 @@ private void verifyLogReceived(final List<String> logList) {
assertNotNull("Failed to get expected exception", message);
if (message.startsWith("Dispatcher has no subscribers")) {
expectedExceptionFound = true;
- assertEquals("Dispatcher has no subscribers for jms-channel noSubscribersChannel.", message);
+ assertEquals("Dispatcher has no subscribers for jms-channel 'noSubscribersChannel'.", message);
break;
}
}
View
7 ...src/main/java/org/springframework/integration/redis/channel/SubscribableRedisChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -191,8 +191,9 @@ public void handleMessage(String s) {
String topicName = SubscribableRedisChannel.this.topicName;
topicName = StringUtils.hasText(topicName) ? topicName : "unknown";
throw new MessageDeliveryException(siMessage, e.getMessage()
- + " for redis-channel "
- + topicName + ".", e);
+ + " for redis-channel '"
+ + topicName + "' (" + SubscribableRedisChannel.this.getFullChannelName()
+ + ").", e);
}
}
}
View
9 ...est/java/org/springframework/integration/redis/channel/SubscribableRedisChannelTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -45,9 +45,9 @@
* @since 2.0
*/
public class SubscribableRedisChannelTests extends RedisAvailableTests{
-
- @Test
+
+ @Test
@RedisAvailable
public void pubSubChanneTest() throws Exception{
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
@@ -77,6 +77,7 @@ public void dispatcherHasNoSubscribersTest() throws Exception{
connectionFactory.afterPropertiesSet();
SubscribableRedisChannel channel = new SubscribableRedisChannel(connectionFactory, "si.test.channel.no.subs");
+ channel.setBeanName("dhnsChannel");
channel.setBeanFactory(mock(BeanFactory.class));
channel.afterPropertiesSet();
@@ -94,7 +95,7 @@ public void dispatcherHasNoSubscribersTest() throws Exception{
catch (InvocationTargetException e) {
Throwable cause = e.getCause();
assertNotNull(cause);
- assertEquals("Dispatcher has no subscribers for redis-channel si.test.channel.no.subs.", cause.getMessage());
+ assertEquals("Dispatcher has no subscribers for redis-channel 'si.test.channel.no.subs' (dhnsChannel).", cause.getMessage());
}
}
Something went wrong with that request. Please try again.