INT-3298 WARN if RSFB Falls Back to SeqSizeRS

JIRA: https://jira.springsource.org/browse/INT-3298

Emit a WARN log whenever the `ReleaseStrategyFactoryBean`
falls back to using the `SequenceSizeReleaseStrategy`.

This will happen if no method name is provided and no
annotated method is found, or a null reference is provided.
This commit is contained in:
Gary Russell
2014-03-04 15:25:16 -05:00
committed by Artem Bilan
parent 29bd9e981f
commit 00c0533004
2 changed files with 166 additions and 10 deletions

View File

@@ -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.
@@ -17,26 +17,32 @@ package org.springframework.integration.config;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.integration.aggregator.ReleaseStrategy;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.aggregator.ReleaseStrategy;
import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy;
import org.springframework.util.StringUtils;
/**
* Convenience factory for XML configuration of a {@link ReleaseStrategy}. Encapsulates the knowledge of the default
* strategy and search algorithms for POJO and annotated methods.
*
*
* @author Dave Syer
*
* @author Gary Russell
*
*/
public class ReleaseStrategyFactoryBean implements FactoryBean<ReleaseStrategy> {
private static final Log logger = LogFactory.getLog(ReleaseStrategyFactoryBean.class);
private ReleaseStrategy delegate = new SequenceSizeReleaseStrategy();
/**
* Create a factory and set up the delegate which clients of the factory will see as its product.
*
*
* @param target the target object (null if default strategy is acceptable)
*/
public ReleaseStrategyFactoryBean(Object target) {
@@ -45,36 +51,50 @@ public class ReleaseStrategyFactoryBean implements FactoryBean<ReleaseStrategy>
/**
* Create a factory and set up the delegate which clients of the factory will see as its product.
*
*
* @param target the target object (null if default strategy is acceptable)
* @param methodName the method name to invoke in the target (null if it can be inferred)
*/
public ReleaseStrategyFactoryBean(Object target, String methodName) {
if (target instanceof ReleaseStrategy && !StringUtils.hasText(methodName)) {
delegate = (ReleaseStrategy) target;
this.delegate = (ReleaseStrategy) target;
return;
}
if (target != null) {
if (StringUtils.hasText(methodName)) {
delegate = new MethodInvokingReleaseStrategy(target, methodName);
this.delegate = new MethodInvokingReleaseStrategy(target, methodName);
}
else {
Method method = AnnotationFinder.findAnnotatedMethod(target, org.springframework.integration.annotation.ReleaseStrategy.class);
if (method != null) {
delegate = new MethodInvokingReleaseStrategy(target, method);
this.delegate = new MethodInvokingReleaseStrategy(target, method);
}
else {
if (logger.isWarnEnabled()) {
logger.warn("No annotated method found; falling back to SequenceSizeReleaseStrategy, target:"
+ target + ", methodName:" + methodName);
}
}
}
}
else {
if (logger.isWarnEnabled()) {
logger.warn("No target supplied; falling back to SequenceSizeReleaseStrategy");
}
}
}
@Override
public ReleaseStrategy getObject() throws Exception {
return delegate;
return this.delegate;
}
@Override
public Class<?> getObjectType() {
return ReleaseStrategy.class;
}
@Override
public boolean isSingleton() {
return true;
}

View File

@@ -0,0 +1,136 @@
/*
* 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 static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.Collection;
import org.junit.Test;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.aggregator.ReleaseStrategy;
import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy;
import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.test.util.TestUtils;
/**
* @author Gary Russell
* @since 3.0.2
*
*/
public class ReleaseStrategyFactoryBeanTests {
public void testRefWithMethod() throws Exception {
Foo foo = new Foo();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo, "doRelease");
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Foo.class), is(foo));
}
@Test
public void testRefWithMethodWithDifferentAnnotatedMethod() throws Exception {
Bar bar = new Bar();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar, "doRelease2");
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class),
equalTo("#target.doRelease2(messages)"));
}
@Test
public void testRefWithNoMethodWithAnnotation() throws Exception {
Bar bar = new Bar();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar);
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar));
}
@Test
public void testNoRefNoMethod() throws Exception {
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(null);
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class));
}
@Test
public void testRefWithNoMethodNoAnnotation() throws Exception {
Foo foo = new Foo();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo);
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class));
}
@Test
public void testRefThatImplements() throws Exception {
Baz baz = new Baz();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz);
ReleaseStrategy delegate = factory.getObject();
assertThat((Baz) delegate, is(baz));
}
@Test
public void testRefThatImplementsWithDifferentMethod() throws Exception {
Baz baz = new Baz();
ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz, "doRelease2");
ReleaseStrategy delegate = factory.getObject();
assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Baz.class), is(baz));
assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class),
equalTo("#target.doRelease2(messages)"));
}
public class Foo {
boolean doRelease(Collection<?> foo) {
return true;
}
}
public class Bar {
@org.springframework.integration.annotation.ReleaseStrategy
public boolean doRelease(Collection<?> bar) {
return true;
}
public boolean doRelease2(Collection<?> bar) {
return true;
}
}
public class Baz implements ReleaseStrategy {
@Override
public boolean canRelease(MessageGroup group) {
return true;
}
public boolean doRelease2(Collection<?> bar) {
return true;
}
}
}