DefaultMessageEndpoint now provides a ReplyHandler callback for ConcurrentHandlers.

This commit is contained in:
Mark Fisher
2008-01-21 16:34:20 +00:00
parent 33143a98d6
commit 89e990f661
15 changed files with 592 additions and 24 deletions

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.integration.dispatcher.DispatcherPolicy;
import org.springframework.integration.message.Message;
import org.springframework.util.Assert;
/**
* Simple implementation of a message channel. Each {@link Message} is
@@ -33,7 +34,7 @@ import org.springframework.integration.message.Message;
*/
public class SimpleChannel implements MessageChannel, BeanNameAware {
private static final int DEFAULT_CAPACITY = 25;
private static final int DEFAULT_CAPACITY = 100;
private String name;
@@ -110,6 +111,7 @@ public class SimpleChannel implements MessageChannel, BeanNameAware {
* <code>false</code> if the sending thread is interrupted.
*/
public boolean send(Message message) {
Assert.notNull(message, "'message' must not be null");
try {
queue.put(message);
return true;
@@ -134,6 +136,7 @@ public class SimpleChannel implements MessageChannel, BeanNameAware {
* time or the sending thread is interrupted.
*/
public boolean send(Message message, long timeout) {
Assert.notNull(message, "'message' must not be null");
try {
if (timeout > 0) {
return this.queue.offer(message, timeout, TimeUnit.MILLISECONDS);

View File

@@ -29,7 +29,9 @@ import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.handler.MessageHandlerNotRunningException;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.selector.MessageSelectorRejectedException;
import org.springframework.integration.scheduling.MessagingTask;
import org.springframework.integration.scheduling.Schedule;
import org.springframework.util.Assert;

View File

@@ -28,15 +28,18 @@ import org.springframework.integration.bus.Subscription;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.dispatcher.MessageHandlerNotRunningException;
import org.springframework.integration.dispatcher.MessageHandlerRejectedExecutionException;
import org.springframework.integration.dispatcher.MessageSelectorRejectedException;
import org.springframework.integration.handler.ConcurrentHandler;
import org.springframework.integration.handler.MessageHandler;
import org.springframework.integration.handler.MessageHandlerNotRunningException;
import org.springframework.integration.handler.MessageHandlerRejectedExecutionException;
import org.springframework.integration.handler.ReplyHandler;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageHeader;
import org.springframework.integration.message.selector.MessageSelector;
import org.springframework.integration.message.selector.MessageSelectorRejectedException;
import org.springframework.integration.util.ErrorHandler;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Default implementation of the {@link MessageEndpoint} interface.
@@ -57,6 +60,8 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
private ErrorHandler errorHandler;
private ReplyHandler replyHandler = new EndpointReplyHandler();
private String defaultOutputChannelName;
private ChannelRegistry channelRegistry;
@@ -145,7 +150,7 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
}
public void afterPropertiesSet() {
if (this.concurrencyPolicy != null) {
if (this.concurrencyPolicy != null || this.handler instanceof ConcurrentHandler) {
if (!(this.handler instanceof ConcurrentHandler)) {
this.handler = new ConcurrentHandler(this.handler, this.concurrencyPolicy);
}
@@ -153,6 +158,7 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
if (this.errorHandler != null) {
concurrentHandler.setErrorHandler(this.errorHandler);
}
concurrentHandler.setReplyHandler(this.replyHandler);
concurrentHandler.afterPropertiesSet();
}
this.initialized = true;
@@ -206,13 +212,7 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
try {
Message<?> replyMessage = handler.handle(message);
if (replyMessage != null) {
MessageChannel replyChannel = this.resolveReplyChannel(message);
if (replyChannel == null) {
throw new MessageHandlingException("Unable to determine reply channel for message. "
+ "Provide a 'replyChannelName' in the message header or a 'defaultOutputChannelName' "
+ "on the message endpoint.");
}
replyChannel.send(replyMessage);
this.replyHandler.handle(replyMessage, message.getHeader());
}
}
catch (MessageHandlerRejectedExecutionException e) {
@@ -228,12 +228,11 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
return null;
}
private MessageChannel resolveReplyChannel(Message<?> message) {
private MessageChannel resolveReplyChannel(String replyChannelName) {
if (this.channelRegistry == null) {
return null;
}
String replyChannelName = message.getHeader().getReplyChannelName();
if (replyChannelName != null && replyChannelName.trim().length() > 0) {
if (StringUtils.hasText(replyChannelName)) {
return this.channelRegistry.lookupChannel(replyChannelName);
}
if (this.defaultOutputChannelName != null) {
@@ -242,4 +241,22 @@ public class DefaultMessageEndpoint implements MessageEndpoint, ChannelRegistryA
return null;
}
private class EndpointReplyHandler implements ReplyHandler {
public void handle(Message<?> replyMessage, MessageHeader originalMessageHeader) {
if (replyMessage == null) {
return;
}
String replyChannelName = originalMessageHeader.getReplyChannelName();
MessageChannel replyChannel = resolveReplyChannel(replyChannelName);
if (replyChannel == null) {
throw new MessageHandlingException("Unable to determine reply channel for message. "
+ "Provide a 'replyChannelName' in the message header or a 'defaultOutputChannelName' "
+ "on the message endpoint.");
}
replyChannel.send(replyMessage);
}
}
}

View File

@@ -21,8 +21,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.Lifecycle;
import org.springframework.integration.dispatcher.MessageHandlerNotRunningException;
import org.springframework.integration.dispatcher.MessageHandlerRejectedExecutionException;
import org.springframework.integration.endpoint.ConcurrencyPolicy;
import org.springframework.integration.message.Message;
import org.springframework.integration.util.ErrorHandler;
@@ -51,6 +49,8 @@ public class ConcurrentHandler implements MessageHandler, Lifecycle, Initializin
private ErrorHandler errorHandler;
private ReplyHandler replyHandler;
private volatile boolean running;
private Object lifecycleMonitor = new Object();
@@ -83,6 +83,10 @@ public class ConcurrentHandler implements MessageHandler, Lifecycle, Initializin
this.errorHandler = errorHandler;
}
public void setReplyHandler(ReplyHandler replyHandler) {
this.replyHandler = replyHandler;
}
public void afterPropertiesSet() {
refreshExecutor();
}
@@ -173,7 +177,10 @@ public class ConcurrentHandler implements MessageHandler, Lifecycle, Initializin
public void run() {
try {
handler.handle(this.message);
Message<?> reply = handler.handle(this.message);
if (replyHandler != null) {
replyHandler.handle(reply, this.message.getHeader());
}
}
catch (Throwable t) {
if (errorHandler != null) {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.integration.dispatcher;
package org.springframework.integration.handler;
import org.springframework.integration.MessageHandlingException;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.integration.dispatcher;
package org.springframework.integration.handler;
import org.springframework.integration.MessageHandlingException;

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2002-2007 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.handler;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageHeader;
/**
* Strategy interface for handling reply messages.
*
* @author Mark Fisher
*/
public interface ReplyHandler {
void handle(Message<?> replyMessage, MessageHeader originalMessageHeader);
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.integration.dispatcher;
package org.springframework.integration.message.selector;
import org.springframework.integration.MessageHandlingException;