INT-1002: add support for fixed-rate, fixed-interval and cron attributes
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
@@ -46,7 +48,12 @@ import org.springframework.util.xml.DomUtils;
|
||||
*/
|
||||
public class PollerParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
public static final String MULTIPLE_TRIGGER_DEFINITIONS = "A <poller> cannot specify more than one trigger configuration.";
|
||||
|
||||
public static final String NO_TRIGGER_DEFINITIONS = "A <poller> must have a one and only one trigger configuration.";
|
||||
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
if (element.getAttribute("default").equals("true")) {
|
||||
@@ -91,34 +98,59 @@ public class PollerParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
|
||||
private void configureTrigger(Element pollerElement, BeanDefinitionBuilder targetBuilder, ParserContext parserContext) {
|
||||
String triggerBeanName = null;
|
||||
if (pollerElement.hasAttribute("trigger")) {
|
||||
triggerBeanName = pollerElement.getAttribute("trigger");
|
||||
// Polling frequency can be configured either through attributes or by using sub-elements
|
||||
// Since Spring Integration 2.0 trigger sub-elements are deprecated
|
||||
String triggerAttribute = pollerElement.getAttribute("trigger");
|
||||
String fixedRateAttribute = pollerElement.getAttribute("fixed-rate");
|
||||
String fixedDelayAttribute = pollerElement.getAttribute("fixed-delay");
|
||||
String cronAttribute = pollerElement.getAttribute("cron");
|
||||
|
||||
List<String> triggerBeanNames = new ArrayList<String>();
|
||||
if (StringUtils.hasText(triggerAttribute)) {
|
||||
triggerBeanNames.add(triggerAttribute);
|
||||
} else if (StringUtils.hasText(fixedRateAttribute)) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.scheduling.support.PeriodicTrigger");
|
||||
builder.addConstructorArgValue(fixedRateAttribute);
|
||||
builder.addPropertyValue("fixedRate", Boolean.TRUE);
|
||||
String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
triggerBeanNames.add(triggerBeanName);
|
||||
} else if (StringUtils.hasText(fixedDelayAttribute)) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.scheduling.support.PeriodicTrigger");
|
||||
builder.addConstructorArgValue(fixedDelayAttribute);
|
||||
builder.addPropertyValue("fixedRate", Boolean.FALSE);
|
||||
String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
triggerBeanNames.add(triggerBeanName);
|
||||
} else if (StringUtils.hasText(cronAttribute)) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.scheduling.support.CronTrigger");
|
||||
builder.addConstructorArgValue(cronAttribute);
|
||||
String triggerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
triggerBeanNames.add(triggerBeanName);
|
||||
}
|
||||
Element intervalElement = DomUtils.getChildElementByTagName(pollerElement, "interval-trigger");
|
||||
if (intervalElement != null) {
|
||||
if (triggerBeanName != null) {
|
||||
parserContext.getReaderContext().error(
|
||||
"A <poller> element with the 'trigger' attribute cannot have <interval-trigger/> or <cron-trigger/> child elements. ", pollerElement);
|
||||
}
|
||||
triggerBeanName = parseIntervalTrigger(intervalElement, parserContext);
|
||||
parserContext.getReaderContext().warning("Poller configuration via 'interval-trigger' subelements is deprecated, use attributes instead", pollerElement);
|
||||
triggerBeanNames.add(parseIntervalTrigger(intervalElement, parserContext));
|
||||
}
|
||||
else {
|
||||
Element cronElement = DomUtils.getChildElementByTagName(pollerElement, "cron-trigger");
|
||||
parserContext.getReaderContext().warning("Poller configuration via 'cron-trigger' subelements is deprecated, use attributes instead", pollerElement);
|
||||
if (cronElement != null) {
|
||||
if (triggerBeanName != null) {
|
||||
parserContext.getReaderContext().error(
|
||||
"A <poller> element with the 'trigger' attribute cannot have <interval-trigger/> or <cron-trigger/> child elements. ", pollerElement);
|
||||
}
|
||||
triggerBeanName = parseCronTrigger(cronElement, parserContext);
|
||||
triggerBeanNames.add(parseCronTrigger(cronElement, parserContext));
|
||||
}
|
||||
}
|
||||
if (triggerBeanName == null) {
|
||||
if (triggerBeanNames.isEmpty()) {
|
||||
parserContext.getReaderContext().error(
|
||||
"A <poller> element must include a trigger definition, either as a 'trigger' attribute, or as an <interval-trigger/> or <cron-trigger/> child element.", pollerElement);
|
||||
NO_TRIGGER_DEFINITIONS, pollerElement);
|
||||
}
|
||||
targetBuilder.addPropertyReference("trigger", triggerBeanName);
|
||||
}
|
||||
if (triggerBeanNames.size() > 1) {
|
||||
parserContext.getReaderContext().error(
|
||||
MULTIPLE_TRIGGER_DEFINITIONS, pollerElement);
|
||||
}
|
||||
targetBuilder.addPropertyReference("trigger", triggerBeanNames.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an "interval-trigger" element
|
||||
|
||||
@@ -1018,10 +1018,12 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<!-- Poller sub-elements are deprecated since Spring Integration 2.0 -->
|
||||
<xsd:choice minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="interval-trigger" type="intervalTriggerType" />
|
||||
<xsd:element name="cron-trigger" type="cronTriggerType" />
|
||||
</xsd:choice>
|
||||
<!-- Poller sub-elements are deprecated since Spring Integration 2.0 -->
|
||||
<xsd:element name="transactional" type="transactionalType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="advice-chain" minOccurs="0" maxOccurs="1">
|
||||
<xsd:complexType>
|
||||
@@ -1046,7 +1048,21 @@
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<!-- <xsd:attribute name="ref" type="xsd:string" />-->
|
||||
<xsd:attribute name="fixed-delay" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Fixed delay trigger (in milliseconds).</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="fixed-rate" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Fixed rate trigger (in milliseconds).</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cron" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Cron trigger.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="trigger" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<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"
|
||||
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">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller id="poller" receive-timeout="1234">
|
||||
<poller id="pollerWithSubElement" receive-timeout="1234">
|
||||
<cron-trigger expression="*/10 * 9-17 * * MON-FRI"/>
|
||||
</poller>
|
||||
|
||||
<poller id="pollerWithAttribute" cron="*/10 * 9-17 * * MON-FRI" receive-timeout="1234"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -41,8 +41,8 @@ public class CronTriggerParserTests {
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void checkConfig() {
|
||||
Object poller = context.getBean("poller");
|
||||
public void checkConfigWithSubElement() {
|
||||
Object poller = context.getBean("pollerWithSubElement");
|
||||
assertEquals(PollerMetadata.class, poller.getClass());
|
||||
PollerMetadata metadata = (PollerMetadata) poller;
|
||||
Trigger trigger = metadata.getTrigger();
|
||||
@@ -54,4 +54,19 @@ public class CronTriggerParserTests {
|
||||
assertEquals("*/10 * 9-17 * * MON-FRI", expression);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkConfigWithAttribute() {
|
||||
Object poller = context.getBean("pollerWithAttribute");
|
||||
assertEquals(PollerMetadata.class, poller.getClass());
|
||||
PollerMetadata metadata = (PollerMetadata) poller;
|
||||
Trigger trigger = metadata.getTrigger();
|
||||
assertEquals(CronTrigger.class, trigger.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
|
||||
String expression = (String) new DirectFieldAccessor(
|
||||
accessor.getPropertyValue("sequenceGenerator"))
|
||||
.getPropertyValue("expression");
|
||||
assertEquals("*/10 * 9-17 * * MON-FRI", expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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">
|
||||
|
||||
<poller id="pollerWithFixedRateAttribute" fixed-rate="36" receive-timeout="1234"/>
|
||||
|
||||
<poller id="pollerWithFixedDelayAttribute" fixed-delay="37" receive-timeout="1234"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.scheduling.PollerMetadata;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class IntervalTriggerParserTests {
|
||||
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testFixedRateTrigger() {
|
||||
Object poller = context.getBean("pollerWithFixedRateAttribute");
|
||||
assertEquals(PollerMetadata.class, poller.getClass());
|
||||
PollerMetadata metadata = (PollerMetadata) poller;
|
||||
Trigger trigger = metadata.getTrigger();
|
||||
assertEquals(PeriodicTrigger.class, trigger.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
|
||||
Boolean fixedRate = (Boolean) accessor.getPropertyValue("fixedRate");
|
||||
Long period = (Long) accessor.getPropertyValue("period");
|
||||
assertEquals(fixedRate, true);
|
||||
assertEquals(36l, period.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedDelayTrigger() {
|
||||
Object poller = context.getBean("pollerWithFixedDelayAttribute");
|
||||
assertEquals(PollerMetadata.class, poller.getClass());
|
||||
PollerMetadata metadata = (PollerMetadata) poller;
|
||||
Trigger trigger = metadata.getTrigger();
|
||||
assertEquals(PeriodicTrigger.class, trigger.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
|
||||
Boolean fixedRate = (Boolean) accessor.getPropertyValue("fixedRate");
|
||||
Long period = (Long) accessor.getPropertyValue("period");
|
||||
assertEquals(fixedRate, false);
|
||||
assertEquals(37l, period.longValue());
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.config.TestTrigger;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.scheduling.PollerMetadata;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
|
||||
Reference in New Issue
Block a user