INT-3286: Add @EnableMessageHistory
JIRA: https://jira.springsource.org/browse/INT-3286 Introduce `@EnableMessageHistory` and `MessageHistoryRegistrar`. Refactoring for `MessageHistoryParser` to use `MessageHistoryRegistrar` to follow with DRY Add test for `@EnableMessageHistory` INT-3286: Polishing INT-3286: Enable several MHs with the same value Previously the Framework allowed only one `<message-history>` independent of their `tracked-components`. With introduction of `@EnableMessageHistory` and `MessageHistoryRegistrar` the `MessageHistoryConfigurer` is improved to allow several `<message-history>` or `@EnableMessageHistory` with the same set of `componentNamePatterns`. INT-3286 Polishing + JMX + Docs * Allows setComponentNamePatterns and/or setComponentNamePatternsSet to be used as long as the settings are consistent. * Handle the case where the `MHC` was configured as a bean (no managed set exists) * Add support for changing the component name patterns over JMX + test case * Docs INT-3286 More Polishing * Change bean name to `messageHistoryConfigurer` * Move constant to `ICU` * Export the MBean by the `IMBE`
This commit is contained in:
committed by
Gary Russell
parent
d8e4818c5e
commit
2fd27e3a6c
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2014 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.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Enables {@link org.springframework.integration.history.MessageHistory} for Integration components.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(MessageHistoryRegistrar.class)
|
||||
public @interface EnableMessageHistory {
|
||||
|
||||
String[] value() default "*";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2014 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.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedSet;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.history.MessageHistoryConfigurer;
|
||||
|
||||
/**
|
||||
* Registers the {@link MessageHistoryConfigurer} {@link org.springframework.beans.factory.config.BeanDefinition}
|
||||
* for {@link org.springframework.integration.history.MessageHistory}.
|
||||
* This registrar is applied from {@code @EnableMessageHistory} on the {@code Configuration} class
|
||||
* or from {@code MessageHistoryParser}.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MessageHistoryRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
Map<String,Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableMessageHistory.class.getName());
|
||||
Object componentNamePatterns = annotationAttributes.get("value");
|
||||
|
||||
if (componentNamePatterns instanceof String[]) {
|
||||
StringBuilder componentNamePatternsString = new StringBuilder();
|
||||
for (String s : (String[]) componentNamePatterns) {
|
||||
componentNamePatternsString.append(s).append(",");
|
||||
}
|
||||
componentNamePatterns = componentNamePatternsString.substring(0, componentNamePatternsString.length() - 1);
|
||||
}
|
||||
|
||||
if (!registry.containsBeanDefinition(IntegrationContextUtils.INTEGRATION_MESSAGE_HISTORY_CONFIGURER)) {
|
||||
Set<Object> componentNamePatternsSet = new ManagedSet<Object>();
|
||||
componentNamePatternsSet.add(componentNamePatterns);
|
||||
|
||||
AbstractBeanDefinition messageHistoryConfigurer = BeanDefinitionBuilder.genericBeanDefinition(MessageHistoryConfigurer.class)
|
||||
.addPropertyValue("componentNamePatternsSet", componentNamePatternsSet)
|
||||
.getBeanDefinition();
|
||||
|
||||
registry.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_MESSAGE_HISTORY_CONFIGURER, messageHistoryConfigurer);
|
||||
|
||||
}
|
||||
else {
|
||||
BeanDefinition beanDefinition = registry.getBeanDefinition(IntegrationContextUtils.INTEGRATION_MESSAGE_HISTORY_CONFIGURER);
|
||||
PropertyValue propertyValue = beanDefinition
|
||||
.getPropertyValues().getPropertyValue("componentNamePatternsSet");
|
||||
if (propertyValue != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Object> currentComponentNamePatternsSet = (Set<Object>) propertyValue.getValue();
|
||||
currentComponentNamePatternsSet.add(componentNamePatterns);
|
||||
}
|
||||
else {
|
||||
Set<Object> componentNamePatternsSet = new ManagedSet<Object>();
|
||||
componentNamePatternsSet.add(componentNamePatterns);
|
||||
beanDefinition.getPropertyValues().addPropertyValue("componentNamePatternsSet", componentNamePatternsSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,47 +16,41 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.type.StandardAnnotationMetadata;
|
||||
import org.springframework.integration.config.MessageHistoryRegistrar;
|
||||
|
||||
/**
|
||||
* The {@code <message-history/>} parser.
|
||||
* Delegates the {@link BeanDefinition} registration to the {@link MessageHistoryRegistrar}.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MessageHistoryParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
private static final String CONFIGURER_CLASSNAME = "org.springframework.integration.history.MessageHistoryConfigurer";
|
||||
public class MessageHistoryParser implements BeanDefinitionParser {
|
||||
|
||||
private final MessageHistoryRegistrar messageHistoryRegistrar = new MessageHistoryRegistrar();
|
||||
|
||||
@Override
|
||||
protected String getBeanClassName(Element element) {
|
||||
return CONFIGURER_CLASSNAME;
|
||||
}
|
||||
public BeanDefinition parse(final Element element, ParserContext parserContext) {
|
||||
this.messageHistoryRegistrar.registerBeanDefinitions(new StandardAnnotationMetadata(MessageHistoryParser.class) {
|
||||
|
||||
@Override
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return Collections.<String, Object>singletonMap("value", element.getAttribute("tracked-components"));
|
||||
}
|
||||
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(CONFIGURER_CLASSNAME)) {
|
||||
throw new BeanDefinitionStoreException("At most one MessageHistoryConfigurer may be registered within a context.");
|
||||
}
|
||||
return CONFIGURER_CLASSNAME;
|
||||
}, parserContext.getRegistry());
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
|
||||
|
||||
}
|
||||
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "tracked-components", "componentNamePatterns");
|
||||
postProcess(builder, element);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ public abstract class IntegrationContextUtils {
|
||||
|
||||
public static final String INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME = "IntegrationConfigurationBeanFactoryPostProcessor";
|
||||
|
||||
public static final String INTEGRATION_MESSAGE_HISTORY_CONFIGURER = "messageHistoryConfigurer";
|
||||
|
||||
/**
|
||||
* @param beanFactory BeanFactory for lookup, must not be null.
|
||||
* @return The {@link MetadataStore} bean whose name is "metadataStore".
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2014 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,6 +16,7 @@
|
||||
|
||||
package org.springframework.integration.history;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -28,20 +29,31 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@ManagedResource
|
||||
public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAware {
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private volatile String[] componentNamePatterns = new String[] { "*" };
|
||||
|
||||
private volatile boolean componentNamePatternsExplicitlySet;
|
||||
|
||||
private final Set<String> currentlyTrackedComponentNames = new HashSet<String>();
|
||||
|
||||
private volatile BeanFactory beanFactory;
|
||||
@@ -50,16 +62,76 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar
|
||||
|
||||
private volatile boolean autoStartup = true;
|
||||
|
||||
private int phase = Integer.MIN_VALUE;
|
||||
private final int phase = Integer.MIN_VALUE;
|
||||
|
||||
private final Object lifecycleMonitor = new Object();
|
||||
|
||||
|
||||
/**
|
||||
* The patterns for which components will be tracked; default '*' (all trackable
|
||||
* components). Cannot be changed if {@link #isRunning()}; invoke {@link #stop()} first.
|
||||
* @param componentNamePatterns The patterns.
|
||||
*/
|
||||
public void setComponentNamePatterns(String[] componentNamePatterns) {
|
||||
Assert.notEmpty(componentNamePatterns, "componentNamePatterns must not be empty");
|
||||
this.componentNamePatterns = componentNamePatterns;
|
||||
Assert.state(!this.running, "'componentNamePatterns' cannot be changed without invoking stop() first");
|
||||
String[] trimmedAndSortedComponentNamePatterns = componentNamePatterns.clone();
|
||||
for (int i = 0; i < componentNamePatterns.length; i++) {
|
||||
trimmedAndSortedComponentNamePatterns[i] = trimmedAndSortedComponentNamePatterns[i].trim();
|
||||
}
|
||||
Arrays.sort(trimmedAndSortedComponentNamePatterns);
|
||||
Assert.isTrue(!this.componentNamePatternsExplicitlySet
|
||||
|| Arrays.equals(this.componentNamePatterns, trimmedAndSortedComponentNamePatterns),
|
||||
"When more than one message history definition " +
|
||||
"(@EnableMessageHistory or <message-history>)" +
|
||||
" is found in the context, they all must have the same 'componentNamePatterns'");
|
||||
this.componentNamePatterns = trimmedAndSortedComponentNamePatterns;
|
||||
this.componentNamePatternsExplicitlySet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A comma-delimited list of patterns for which components will be tracked; default '*' (all trackable
|
||||
* components). Cannot be changed if {@link #isRunning()}; invoke {@link #stop()} first.
|
||||
* @param componentNamePatterns The patterns.
|
||||
*/
|
||||
@ManagedAttribute(description="comma-delimited list of patterns; must invoke stop() before changing.")
|
||||
public void setComponentNamePatternsString(String componentNamePatterns) {
|
||||
this.setComponentNamePatterns(StringUtils.delimitedListToStringArray(componentNamePatterns, ",", " "));
|
||||
}
|
||||
|
||||
@ManagedAttribute
|
||||
public String getComponentNamePatternsString() {
|
||||
return StringUtils.arrayToCommaDelimitedString(this.componentNamePatterns);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The patterns for which components will be tracked; default '*' (all trackable
|
||||
* components). Cannot be changed if {@link #isRunning()}; invoke {@link #stop()} first.
|
||||
* All members of the set must canonically represent the same patterns - allows multiple
|
||||
* EnableMessageHistory annotations as long they all have the same patterns.
|
||||
* @param componentNamePatternsSet A set of lists of comma-delimited patterns.
|
||||
*/
|
||||
public void setComponentNamePatternsSet(Set<String> componentNamePatternsSet) {
|
||||
Assert.notNull(componentNamePatternsSet, "'componentNamePatternsSet' must not be null");
|
||||
Assert.state(!this.running, "'componentNamePatternsSet' cannot be changed without invoking stop() first");
|
||||
for (String s : componentNamePatternsSet) {
|
||||
String[] componentNamePatterns = StringUtils.delimitedListToStringArray(s, "," , " ");
|
||||
Arrays.sort(componentNamePatterns);
|
||||
if (this.componentNamePatternsExplicitlySet
|
||||
&& !Arrays.equals(this.componentNamePatterns, componentNamePatterns)) {
|
||||
throw new BeanDefinitionValidationException("When more than one message history definition " +
|
||||
"(@EnableMessageHistory or <message-history>)" +
|
||||
" is found in the context, they all must have the same 'componentNamePatterns'");
|
||||
}
|
||||
else {
|
||||
this.componentNamePatterns = componentNamePatterns;
|
||||
this.componentNamePatternsExplicitlySet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
@@ -73,18 +145,23 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar
|
||||
* SmartLifecycle implementation
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return this.autoStartup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
@ManagedOperation
|
||||
@Override
|
||||
public void start() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (!this.running && this.beanFactory instanceof ListableBeanFactory) {
|
||||
@@ -104,6 +181,8 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar
|
||||
}
|
||||
}
|
||||
|
||||
@ManagedOperation
|
||||
@Override
|
||||
public void stop() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (this.running && this.beanFactory instanceof ListableBeanFactory) {
|
||||
@@ -118,10 +197,12 @@ public class MessageHistoryConfigurer implements SmartLifecycle, BeanFactoryAwar
|
||||
}
|
||||
this.currentlyTrackedComponentNames.clear();
|
||||
this.running = false;
|
||||
this.componentNamePatternsExplicitlySet = false; // allow pattern changes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
this.stop();
|
||||
callback.run();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<message-history tracked-components="publishedChannel,input"/>
|
||||
|
||||
<beans:bean id="messageHistoryConfigurer"
|
||||
class="org.springframework.integration.history.MessageHistoryConfigurer">
|
||||
<beans:property name="componentNamePatterns">
|
||||
<beans:array>
|
||||
<beans:value> input </beans:value>
|
||||
<beans:value> publishedChannel </beans:value>
|
||||
</beans:array>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
package org.springframework.integration.configuration;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -26,6 +30,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.integration.annotation.MessageEndpoint;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
import org.springframework.integration.annotation.Publisher;
|
||||
@@ -33,10 +40,15 @@ import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.config.EnableMessageHistory;
|
||||
import org.springframework.integration.history.MessageHistory;
|
||||
import org.springframework.integration.history.MessageHistoryConfigurer;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
@@ -45,7 +57,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
* @author Artem Bilan
|
||||
* @since 4.0
|
||||
*/
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {EnableIntegrationTests.ContextConfiguration.class, EnableIntegrationTests.ContextConfiguration2.class})
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class EnableIntegrationTests {
|
||||
|
||||
@@ -58,6 +70,9 @@ public class EnableIntegrationTests {
|
||||
@Autowired
|
||||
private PollableChannel publishedChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageHistoryConfigurer configurer;
|
||||
|
||||
@Test
|
||||
public void testAnnotatedServiceActivator() {
|
||||
this.input.send(MessageBuilder.withPayload("Foo").build());
|
||||
@@ -65,15 +80,43 @@ public class EnableIntegrationTests {
|
||||
assertNotNull(receive);
|
||||
assertEquals("FOO", receive.getPayload());
|
||||
|
||||
MessageHistory messageHistory = receive.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class);
|
||||
assertNotNull(messageHistory);
|
||||
String messageHistoryString = messageHistory.toString();
|
||||
assertThat(messageHistoryString, Matchers.containsString("input"));
|
||||
assertThat(messageHistoryString, Matchers.not(Matchers.containsString("output")));
|
||||
|
||||
receive = this.publishedChannel.receive(1000);
|
||||
assertNotNull(receive);
|
||||
assertEquals("foo", receive.getPayload());
|
||||
|
||||
messageHistory = receive.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class);
|
||||
assertNotNull(messageHistory);
|
||||
messageHistoryString = messageHistory.toString();
|
||||
assertThat(messageHistoryString, Matchers.not(Matchers.containsString("input")));
|
||||
assertThat(messageHistoryString, Matchers.not(Matchers.containsString("output")));
|
||||
assertThat(messageHistoryString, Matchers.containsString("publishedChannel"));
|
||||
}
|
||||
|
||||
@Test @DirtiesContext
|
||||
public void testChangePatterns() {
|
||||
try {
|
||||
this.configurer.setComponentNamePatterns(new String[] {"*"});
|
||||
fail("ExpectedException");
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
assertThat(e.getMessage(), containsString("cannot be changed"));
|
||||
}
|
||||
this.configurer.stop();
|
||||
this.configurer.setComponentNamePatterns(new String[] {"*"});
|
||||
assertEquals("*", TestUtils.getPropertyValue(this.configurer, "componentNamePatterns", String[].class)[0]);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = EnableIntegrationTests.class)
|
||||
@EnableIntegration
|
||||
@PropertySource("classpath:org/springframework/integration/configuration/EnableIntegrationTests.properties")
|
||||
@EnableMessageHistory({"input", "publishedChannel"})
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -86,6 +129,19 @@ public class EnableIntegrationTests {
|
||||
return new QueueChannel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableIntegration
|
||||
@ImportResource("classpath:org/springframework/integration/configuration/EnableIntegrationTests-context.xml")
|
||||
@EnableMessageHistory("${message.history.tracked.components}")
|
||||
public static class ContextConfiguration2 {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PollableChannel publishedChannel() {
|
||||
return new QueueChannel();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
message.history.tracked.components=input, publishedChannel
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -29,11 +29,11 @@ import java.util.Properties;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.integration.MessageRejectedException;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.config.ConsumerEndpointFactoryBean;
|
||||
@@ -41,6 +41,7 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
/**
|
||||
@@ -200,7 +201,7 @@ public class MessageHistoryIntegrationTests {
|
||||
Mockito.verify(handler, Mockito.times(1)).handleMessage(Mockito.any(Message.class));
|
||||
}
|
||||
|
||||
@Test(expected=BeanDefinitionParsingException.class)
|
||||
@Test(expected=BeanCreationException.class)
|
||||
public void testMessageHistoryMoreThanOneNamespaceFail() {
|
||||
new ClassPathXmlApplicationContext("messageHistoryWithHistoryWriterNamespace-fail.xml", MessageHistoryIntegrationTests.class);
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<bean class="org.springframework.integration.context.MessageHistoryBeanPostProcessor"/>
|
||||
<bean class="org.springframework.integration.context.MessageHistoryBeanPostProcessor"/>
|
||||
|
||||
</beans>
|
||||
@@ -6,6 +6,6 @@
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<int:message-history/>
|
||||
<int:message-history/>
|
||||
<int:message-history tracked-components="foo*"/>
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user