simplifying MessageHistory

This commit is contained in:
Mark Fisher
2010-04-30 03:15:26 +00:00
parent c9eca95ace
commit 477e8e1a9e
24 changed files with 71 additions and 264 deletions

View File

@@ -21,7 +21,6 @@ import java.util.List;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -61,8 +60,8 @@ public abstract class AbstractMessageAggregator extends
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("aggregator");
public String getComponentType() {
return "aggregator";
}
@Override

View File

@@ -42,7 +42,6 @@ import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.store.MessageStore;
import org.springframework.integration.store.SimpleMessageStore;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.Assert;
@@ -171,8 +170,8 @@ public class CorrelatingMessageHandler extends AbstractMessageHandler implements
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("aggregator");
public String getComponentType() {
return "aggregator";
}
@Override

View File

@@ -23,7 +23,6 @@ import java.util.SortedSet;
import java.util.TreeSet;
import org.springframework.integration.core.Message;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.CollectionUtils;
/**
@@ -64,8 +63,8 @@ public class Resequencer extends AbstractMessageBarrierHandler<SortedSet<Message
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("resequencer");
public String getComponentType() {
return "resequencer";
}
@Override

View File

@@ -32,7 +32,6 @@ import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessagingException;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -64,6 +63,11 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport im
return this.getBeanName();
}
@Override
public String getComponentType() {
return "channel";
}
/**
* Return the current count of Messages that have been sent
* to this channel successfully.
@@ -133,11 +137,6 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport im
return this.interceptors;
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("channel");
}
/**
* Send a message on this channel. If the channel is at capacity, this
* method will block until either space becomes available or the sending
@@ -170,7 +169,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport im
Assert.notNull(message, "message must not be null");
Assert.notNull(message.getPayload(), "message payload must not be null");
message = this.convertPayloadIfNecessary(message);
message.getHeaders().getHistory().addEvent(this.getComponentMetadata());
message.getHeaders().getHistory().addEvent(this.getBeanName(), this.getComponentType());
message = this.interceptors.preSend(message, this);
if (message == null) {
return false;

View File

@@ -24,11 +24,10 @@ 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.beans.factory.NamedBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.integration.channel.BeanFactoryChannelResolver;
import org.springframework.integration.channel.ChannelResolver;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.integration.support.ComponentMetadataProvider;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.Assert;
@@ -43,7 +42,7 @@ import org.springframework.util.Assert;
*
* @author Mark Fisher
*/
public abstract class IntegrationObjectSupport implements ComponentMetadataProvider, BeanNameAware, BeanFactoryAware, InitializingBean {
public abstract class IntegrationObjectSupport implements BeanNameAware, NamedBean, BeanFactoryAware, InitializingBean {
/** Logger that is available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@@ -58,19 +57,20 @@ public abstract class IntegrationObjectSupport implements ComponentMetadataProvi
private volatile ConversionService conversionService;
private final ComponentMetadata componentMetadata = new ComponentMetadata();
public final void setBeanName(String beanName) {
this.beanName = beanName;
}
protected String getBeanName() {
public final String getBeanName() {
return this.beanName;
}
public ComponentMetadata getComponentMetadata() {
return this.componentMetadata;
/**
* Subclasses may implement this method to provide component type information.
*/
public String getComponentType() {
return null;
}
public final void setBeanFactory(BeanFactory beanFactory) {
@@ -79,8 +79,6 @@ public abstract class IntegrationObjectSupport implements ComponentMetadataProvi
}
public final void afterPropertiesSet() {
this.componentMetadata.setComponentName(this.beanName);
this.populateComponentMetadata(this.componentMetadata);
try {
this.onInit();
}
@@ -142,12 +140,6 @@ public abstract class IntegrationObjectSupport implements ComponentMetadataProvi
this.conversionService = conversionService;
}
/**
* Subclasses may override this to add attributes to the {@link ComponentMetadata}.
*/
protected void populateComponentMetadata(ComponentMetadata metadata) {
}
@Override
public String toString() {
return (this.beanName != null) ? this.beanName : super.toString();

View File

@@ -17,10 +17,9 @@
package org.springframework.integration.endpoint;
import org.springframework.core.Ordered;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.integration.support.ComponentMetadataProvider;
/**
* A {@link MessageHandler} implementation that delegates to a target
@@ -34,15 +33,16 @@ class HandlerInvocationChain implements MessageHandler, Ordered {
private final MessageHandler handler;
private final ComponentMetadata metadata;
private final String endpointName;
private final String handlerType;
public HandlerInvocationChain(MessageHandler handler, String endpointName) {
this.handler = handler;
this.metadata = (this.handler instanceof ComponentMetadataProvider)
? ((ComponentMetadataProvider) this.handler).getComponentMetadata()
: new ComponentMetadata();
this.metadata.setComponentName(endpointName);
this.endpointName = endpointName;
this.handlerType = (handler instanceof IntegrationObjectSupport) ?
((IntegrationObjectSupport) this.handler).getComponentType() : null;
}
@@ -52,8 +52,8 @@ class HandlerInvocationChain implements MessageHandler, Ordered {
}
public void handleMessage(Message<?> message) {
if (message != null) {
message.getHeaders().getHistory().addEvent(this.metadata);
if (message != null && this.endpointName != null) {
message.getHeaders().getHistory().addEvent(this.endpointName, this.handlerType);
}
this.handler.handleMessage(message);
}

View File

@@ -20,7 +20,6 @@ import org.springframework.integration.channel.MessageChannelTemplate;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -33,8 +32,6 @@ public abstract class MessageProducerSupport extends AbstractEndpoint implements
private volatile MessageChannel outputChannel;
private final ComponentMetadata componentMetadata = new ComponentMetadata();
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
@@ -53,7 +50,7 @@ public abstract class MessageProducerSupport extends AbstractEndpoint implements
protected boolean sendMessage(Message<?> message) {
if (message != null) {
message.getHeaders().getHistory().addEvent(this.componentMetadata);
message.getHeaders().getHistory().addEvent(this.getBeanName(), this.getComponentType());
}
return this.channelTemplate.send(message, this.outputChannel);
}

View File

@@ -22,7 +22,6 @@ import org.springframework.integration.handler.AbstractReplyProducingMessageHand
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.MessageRejectedException;
import org.springframework.integration.selector.MessageSelector;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -83,8 +82,8 @@ public class MessageFilter extends AbstractReplyProducingMessageHandler {
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("filter");
public String getComponentType() {
return "filter";
}
@Override

View File

@@ -39,7 +39,6 @@ import org.springframework.integration.core.Message;
import org.springframework.integration.core.MessagingException;
import org.springframework.integration.message.InboundMessageMapper;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -123,7 +122,7 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
private final List<MethodParameter> parameterList;
private final ComponentMetadata metadata = new ComponentMetadata();
private final String gatewayName;
public ArgumentArrayMessageMapper(Method method, String gatewayName) {
@@ -131,9 +130,7 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
Assert.notNull(gatewayName, "gatewayName must not be null");
this.method = method;
this.parameterList = this.getMethodParameterList(method);
this.metadata.setComponentName(gatewayName);
// TODO: add METHOD_NAME key for attributes?
this.metadata.setAttribute("method", this.method.getName());
this.gatewayName = gatewayName;
}
public Message<?> toMessage(Object[] arguments) {
@@ -145,7 +142,7 @@ public class ArgumentArrayMessageMapper implements InboundMessageMapper<Object[]
}
Message<?> message = this.mapArgumentsToMessage(arguments);
if (message != null) {
message.getHeaders().getHistory().addEvent(this.metadata);
message.getHeaders().getHistory().addEvent(this.gatewayName, "gateway");
}
return message;
}

View File

@@ -17,7 +17,6 @@
package org.springframework.integration.handler;
import org.springframework.integration.core.Message;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -37,8 +36,8 @@ import org.springframework.util.Assert;
public class BridgeHandler extends AbstractReplyProducingMessageHandler {
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("bridge");
public String getComponentType() {
return "bridge";
}
@Override

View File

@@ -20,7 +20,6 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import org.springframework.integration.core.Message;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.StringUtils;
/**
@@ -66,8 +65,8 @@ public class LoggingHandler extends AbstractMessageHandler {
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("logging-channel-adapter");
public String getComponentType() {
return "logging-channel-adapter";
}
@Override

View File

@@ -26,7 +26,6 @@ import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.filter.MessageFilter;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -91,8 +90,8 @@ public class MessageHandlerChain extends IntegrationObjectSupport implements Mes
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("chain");
public String getComponentType() {
return "chain";
}
private void initialize() {
@@ -128,9 +127,6 @@ public class MessageHandlerChain extends IntegrationObjectSupport implements Mes
nextHandler.handleMessage(message);
return true;
}
public String getName() {
return null;
}
};
((MessageProducer) handler).setOutputChannel(nextChannel);
}
@@ -150,10 +146,6 @@ public class MessageHandlerChain extends IntegrationObjectSupport implements Mes
private class ReplyForwardingMessageChannel implements MessageChannel {
public String getName() {
return MessageHandlerChain.this.getBeanName();
}
public boolean send(Message<?> message) {
return this.send(message, -1);
}

View File

@@ -21,7 +21,6 @@ import java.lang.reflect.Method;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.support.ComponentMetadata;
/**
* @author Mark Fisher
@@ -45,8 +44,8 @@ public class ServiceActivatingHandler extends AbstractReplyProducingMessageHandl
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("service-activator");
public String getComponentType() {
return "service-activator";
}
@Override

View File

@@ -16,8 +16,6 @@
package org.springframework.integration.history;
import org.springframework.integration.support.ComponentMetadata;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
@@ -40,9 +38,9 @@ public class MessageHistory implements Iterable<MessageHistoryEvent>, Serializab
/**
* Add a new event with the provided component metadata.
*/
public MessageHistoryEvent addEvent(ComponentMetadata metadata) {
if (metadata != null && metadata.getComponentName() != null) {
MessageHistoryEvent event = new MessageHistoryEvent(metadata.getComponentType(), metadata.getComponentName());
public MessageHistoryEvent addEvent(String name, String type) {
if (name != null) {
MessageHistoryEvent event = new MessageHistoryEvent(name, type);
this.events.add(event);
return event;
}

View File

@@ -27,19 +27,19 @@ import java.io.Serializable;
*/
public class MessageHistoryEvent implements Serializable {
private final String type;
private final String name;
private final String type;
private final long timestamp;
/**
* Create a MessageHistoryEvent with the metadata of the source component.
*/
public MessageHistoryEvent(String type, String name) {
this.type = type;
public MessageHistoryEvent(String name, String type) {
this.name = name;
this.type = type;
this.timestamp = System.currentTimeMillis();
}

View File

@@ -26,7 +26,6 @@ import org.springframework.integration.core.MessageHeaders;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.support.ComponentMetadata;
/**
* Base class for Message Routers.
@@ -97,8 +96,8 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("router");
public String getComponentType() {
return "router";
}
@Override

View File

@@ -27,7 +27,6 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.selector.MessageSelector;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -89,8 +88,8 @@ public class RecipientListRouter extends AbstractMessageRouter implements Initia
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("recipient-list-router");
public String getComponentType() {
return "recipient-list-router";
}
@Override

View File

@@ -26,7 +26,6 @@ import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessageHeaders;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.support.ComponentMetadata;
/**
* Base class for Message-splitting handlers.
@@ -92,8 +91,8 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
}
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("splitter");
public String getComponentType() {
return "splitter";
}
/**

View File

@@ -1,119 +0,0 @@
/*
* Copyright 2002-2010 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.support;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Metadata describing a messaging component including the
* component's name and type as well as any other attributes.
*
* @author Mark Fisher
* @since 2.0
*/
public class ComponentMetadata implements Serializable {
public static final String COMPONENT_NAME = "componentName";
public static final String COMPONENT_TYPE = "componentType";
private final Map<String, Object> attributes = new HashMap<String, Object>();
/**
* Create a new ComponentMetadata instance with no attributes.
*/
public ComponentMetadata() {
}
/**
* Create a new ComponentMetadata instance that copies all attributes
* from the provided ComponentMetadata.
*/
public ComponentMetadata(ComponentMetadata metadata) {
this.attributes.putAll(metadata.getAttributes());
}
public ComponentMetadata setComponentName(String componentName) {
this.setAttribute(COMPONENT_NAME, componentName);
return this;
}
public ComponentMetadata setComponentType(String componentType) {
this.setAttribute(COMPONENT_TYPE, componentType);
return this;
}
public String getComponentName() {
return this.getAttribute(COMPONENT_NAME, String.class);
}
public String getComponentType() {
return this.getAttribute(COMPONENT_TYPE, String.class);
}
public ComponentMetadata setAttribute(String key, String value) {
this.attributes.put(key, value);
return this;
}
public ComponentMetadata setAttribute(String key, Number value) {
this.attributes.put(key, value);
return this;
}
public ComponentMetadata setAttribute(String key, Boolean value) {
this.attributes.put(key, value);
return this;
}
public Object getAttribute(String key) {
return this.attributes.get(key);
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(String key, Class<T> type) {
Object value = this.attributes.get(key);
if (value != null && type.isAssignableFrom(value.getClass())) {
return (T) value;
}
return null;
}
public Map<String, Object> getAttributes() {
return Collections.unmodifiableMap(this.attributes);
}
public boolean equals(Object other) {
return (other instanceof ComponentMetadata
&& this.attributes.equals(((ComponentMetadata) other).attributes));
}
public int hashCode() {
return 17 * this.attributes.hashCode();
}
public String toString() {
return this.attributes.toString();
}
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2002-2010 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.support;
/**
* Interface to be implemented by messaging components
* that provide {@link ComponentMetadata}.
*
* @author Mark Fisher
* @since 2.0
*/
public interface ComponentMetadataProvider {
/**
* Returns the {@link ComponentMetadata}
*/
ComponentMetadata getComponentMetadata();
}

View File

@@ -19,7 +19,6 @@ package org.springframework.integration.transformer;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.integration.core.Message;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.support.ComponentMetadata;
import org.springframework.util.Assert;
/**
@@ -45,8 +44,8 @@ public class MessageTransformingHandler extends AbstractReplyProducingMessageHan
@Override
protected void populateComponentMetadata(ComponentMetadata metadata) {
metadata.setComponentType("transformer");
public String getComponentType() {
return "transformer";
}
@Override

View File

@@ -283,13 +283,12 @@ public class GatewayProxyFactoryBeanTests {
MessageHistoryEvent event1 = historyIterator.next();
MessageHistoryEvent event2 = historyIterator.next();
MessageHistoryEvent event3 = historyIterator.next();
// assertEquals("echo", event1.getAttribute("method", String.class));
//assertEquals("echo", event1.getAttribute("method", String.class));
assertEquals("testGateway", event1.getName());
assertEquals("channel", event2.getType());
assertEquals("testChannel", event2.getName());
assertEquals("bridge", event3.getType());
assertEquals("testBridge", event3.getName());
System.out.println(message);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,41 +13,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.history;
import org.junit.Test;
import org.springframework.integration.support.ComponentMetadata;
package org.springframework.integration.history;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* @author Oleg Zhurakousky
* @since 2.0
*/
public class MessageHistoryTests {
private long times = 1000;
private ExecutorService executor = Executors.newCachedThreadPool();
@Test
public void testConcurrentModificationsOnObjectMethods() throws Exception{
final MessageHistory history = new MessageHistory();
final MessageHistory otherHistory = new MessageHistory();
executor.execute(new Runnable() {
public void run() {
for (int i = 0; i < times; i++) {
ComponentMetadata event = new ComponentMetadata();
event.setAttribute("foo", "foo");
event.setAttribute("bar", "bar");
event.setComponentName("MessageHistoryTests");
history.addEvent(event);
otherHistory.addEvent(event);
history.addEvent("testName", "testType");
otherHistory.addEvent("testName", "testType");
}
}
});
executor.execute(new Runnable() {
public void run() {
for (int i = 0; i < times; i++) {
@@ -72,4 +68,5 @@ public class MessageHistoryTests {
executor.shutdown();
executor.awaitTermination(3, TimeUnit.SECONDS);
}
}