INT-1141 Improve on how MessageHandlers are stored

INT-1141 polished code

INT-1141 added tests

INT-1141 improved how iterator is obtaind from OrderAwareLikedHashSet

INT-1141 polishing

INT-1141 stashed commit with List-based collection and performance tests

INT-1141 improved OrderedAwareLinkedHashSet

INT-1141 polishing

INT-1141, INT-2627 improved LoadBalancingStrategy and
RoundRobinLoadBalancingStrategy to obtain handler's iterator faster

INT-1141 improved getHandlerIterator method to ensure that it only executes reordering logic if there are more then one handler

INT-1141 simplified OrderedAwareLinkedHashSet to not to extend from LinkedHashSet

INT-1141
changed OrderedAwareLinkedHashSet to OrderedAwareCopyOnWriteArraySetTests, imporoved array creation in RoundRobinLoadBalancingStrategy

INT-1141 polished failing tests and RoundRobinLoadBalancingStrategy. Removed 'transient' from OrderedAwareCopyOnWriteArraySet
This commit is contained in:
Oleg Zhurakousky
2012-06-07 12:18:37 -04:00
committed by Gary Russell
parent 7dd1255351
commit 2b49c66f64
12 changed files with 212 additions and 133 deletions

View File

@@ -16,9 +16,6 @@
package org.springframework.integration.dispatcher;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -35,31 +32,32 @@ import org.springframework.util.Assert;
* dispatching strategies may invoke handles in different ways (e.g. round-robin
* vs. failover), this class does maintain the order of the underlying
* collection. See the {@link OrderedAwareLinkedHashSet} for more detail.
*
*
* @author Mark Fisher
* @author Iwein Fuld
* @author Oleg Zhurakousky
* @author Gary Russell
* @author Diego Belfer
*/
public abstract class AbstractDispatcher implements MessageDispatcher {
protected final Log logger = LogFactory.getLog(this.getClass());
private final Set<MessageHandler> handlers = new OrderedAwareLinkedHashSet<MessageHandler>();
private final OrderedAwareCopyOnWriteArraySet<MessageHandler> handlers =
new OrderedAwareCopyOnWriteArraySet<MessageHandler>();
/**
* Returns a copied, unmodifiable List of this dispatcher's handlers. This
* Returns an unmodifiable {@link Set} of this dispatcher's handlers. This
* is provided for access by subclasses.
*/
protected List<MessageHandler> getHandlers() {
return Collections.<MessageHandler>unmodifiableList(Arrays.<MessageHandler>asList(
this.handlers.toArray(new MessageHandler[this.handlers.size()])));
protected Set<MessageHandler> getHandlers() {
return handlers.asUnmodifiableSet();
}
/**
* Add the handler to the internal Set.
*
*
* @return the result of {@link Set#add(Object)}
*/
public boolean addHandler(MessageHandler handler) {
@@ -69,7 +67,7 @@ public abstract class AbstractDispatcher implements MessageDispatcher {
/**
* Remove the handler from the internal handler Set.
*
*
* @return the result of {@link Set#remove(Object)}
*/
public boolean removeHandler(MessageHandler handler) {
@@ -77,6 +75,7 @@ public abstract class AbstractDispatcher implements MessageDispatcher {
return this.handlers.remove(handler);
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " with handlers: " + this.handlers.toString();
}

View File

@@ -16,7 +16,7 @@
package org.springframework.integration.dispatcher;
import java.util.List;
import java.util.Collection;
import java.util.concurrent.Executor;
import org.springframework.integration.Message;
@@ -34,10 +34,11 @@ import org.springframework.integration.support.MessageBuilder;
* If the 'ignoreFailures' flag is set to <code>true</code> on the other hand, it will make a best effort to send the
* message to each of its handlers. In other words, when 'ignoreFailures' is <code>true</code>, if it fails to send to
* any one handler, it will simply log a warn-level message but continue to send the Message to any other handlers.
*
*
* @author Mark Fisher
* @author Iwein Fuld
* @author Gary Russell
* @author Oleg Zhurakousky
*/
public class BroadcastingDispatcher extends AbstractDispatcher {
@@ -91,7 +92,7 @@ public class BroadcastingDispatcher extends AbstractDispatcher {
public boolean dispatch(Message<?> message) {
boolean dispatched = false;
int sequenceNumber = 1;
List<MessageHandler> handlers = this.getHandlers();
Collection<MessageHandler> handlers = this.getHandlers();
if (this.requireSubscribers && handlers.size() == 0) {
throw new MessageDispatchingException(message, "Dispatcher has no subscribers");
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2002-2009 the original author or authors.
/* Copyright 2002-2012 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.
@@ -15,20 +15,21 @@
package org.springframework.integration.dispatcher;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageHandler;
/**
* Strategy for determining the iteration order of a MessageHandler list.
*
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @since 1.0.3
*/
public interface LoadBalancingStrategy {
public Iterator<MessageHandler> getHandlerIterator(Message<?> message, List<MessageHandler> handlers);
public Iterator<MessageHandler> getHandlerIterator(Message<?> message, Collection<MessageHandler> handlers);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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,9 +17,12 @@
package org.springframework.integration.dispatcher;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
@@ -34,23 +37,24 @@ import org.springframework.util.StringUtils;
/**
* Special Set that maintains the following semantics:
* All elements that are un-ordered (do not implement {@link Ordered} interface or annotated
* {@link Order} annotation) will be stored in the order in which they were added, maintaining the
* semantics of the {@link LinkedHashSet}. However, for all {@link Ordered} elements a
* {@link Order} annotation) will be stored in the order in which they were added.
* However, for all {@link Ordered} elements a
* {@link Comparator} (instantiated by default) for this implementation of {@link Set}, will be
* used. Those elements will have precedence over un-ordered elements. If elements have the same
* order but themselves do not equal to one another the more recent addition will be placed to the
* right of (appended next to) the existing element with the same order, thus preserving the order
* of the insertion and maintaining {@link LinkedHashSet} semantics for the un-ordered elements.
* of the insertion while maintaining the order of insertion for the un-ordered elements.
* <p>
* The class is package-protected and only intended for use by the AbstractDispatcher. It
* <emphasis>must</emphasis> enforce safe concurrent access for all usage by the dispatcher.
*
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author Diego Belfer
* @since 1.0.3
*/
@SuppressWarnings({"unchecked", "serial"})
class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
@SuppressWarnings({"unchecked"})
class OrderedAwareCopyOnWriteArraySet<E> implements Set<E> {
private final OrderComparator comparator = new OrderComparator();
@@ -60,6 +64,19 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
private final WriteLock writeLock = rwl.writeLock();
private final CopyOnWriteArraySet<E> elements;
private final Set<E> unmodifiableElements;
public OrderedAwareCopyOnWriteArraySet() {
elements = new CopyOnWriteArraySet<E>();
unmodifiableElements = Collections.unmodifiableSet(elements);
}
public Set<E> asUnmodifiableSet() {
return unmodifiableElements;
}
/**
* Every time an Ordered element is added via this method this
@@ -69,19 +86,19 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
public boolean add(E o) {
Assert.notNull(o,"Can not add NULL object");
writeLock.lock();
try {
try {
boolean present = false;
if (o instanceof Ordered){
present = this.addOrderedElement((Ordered) o);
}
else {
present = super.add(o);
present = elements.add(o);
}
return present;
}
finally {
writeLock.unlock();
}
}
}
/**
@@ -91,9 +108,9 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
Assert.notNull(c,"Can not merge with NULL set");
writeLock.lock();
try {
for (E object : c) {
for (E object : c) {
this.add(object);
}
}
return true;
}
finally {
@@ -102,12 +119,14 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
}
/**
* {@inheritDoc}
* {@inheritDoc}
*/
public boolean remove(Object o) {
writeLock.lock();
try {
return super.remove(o);
boolean removed = elements.remove(o);
//unmodifiableElements = Collections.unmodifiableSet(this);
return removed;
}
finally {
writeLock.unlock();
@@ -115,7 +134,7 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
}
/**
* {@inheritDoc}
* {@inheritDoc}
*/
public boolean removeAll(Collection<?> c){
if (CollectionUtils.isEmpty(c)){
@@ -123,18 +142,17 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
}
writeLock.lock();
try {
return super.removeAll(c);
return elements.removeAll(c);
}
finally {
writeLock.unlock();
}
}
@Override
public <T> T[] toArray(T[] a) {
readLock.lock();
try {
return super.toArray(a);
return elements.toArray(a);
}
finally {
readLock.unlock();
@@ -145,7 +163,7 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
public String toString() {
readLock.lock();
try {
return StringUtils.collectionToCommaDelimitedString(this);
return StringUtils.collectionToCommaDelimitedString(elements);
}
finally {
readLock.unlock();
@@ -153,27 +171,27 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
}
@SuppressWarnings("rawtypes")
private boolean addOrderedElement(Ordered adding) {
private boolean addOrderedElement(Ordered adding) {
boolean added = false;
E[] tempUnorderedElements = (E[]) this.toArray();
if (super.contains(adding)) {
E[] tempUnorderedElements = (E[]) elements.toArray();
if (elements.contains(adding)) {
return false;
}
super.clear();
elements.clear();
if (tempUnorderedElements.length == 0) {
added = super.add((E) adding);
added = elements.add((E) adding);
}
else {
Set tempSet = new LinkedHashSet();
for (E current : tempUnorderedElements) {
if (current instanceof Ordered) {
if (this.comparator.compare(adding, current) < 0) {
added = super.add((E) adding);
super.add(current);
added = elements.add((E) adding);
elements.add(current);
}
else {
super.add(current);
elements.add(current);
}
}
else {
@@ -181,13 +199,44 @@ class OrderedAwareLinkedHashSet<E> extends LinkedHashSet<E> {
}
}
if (!added) {
added = super.add((E) adding);
added = elements.add((E) adding);
}
for (Object object : tempSet) {
super.add((E) object);
elements.add((E) object);
}
}
return added;
}
public Iterator<E> iterator() {
return this.elements.iterator();
}
public int size(){
return this.elements.size();
}
public boolean isEmpty() {
return this.elements.isEmpty();
}
public boolean contains(Object o) {
return this.elements.contains(o);
}
public Object[] toArray() {
return this.elements.toArray();
}
public boolean containsAll(Collection<?> c) {
return this.elements.containsAll(c);
}
public boolean retainAll(Collection<?> c) {
return this.elements.retainAll(c);
}
public void clear() {
this.elements.clear();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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,9 +16,8 @@
package org.springframework.integration.dispatcher;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.integration.Message;
@@ -28,32 +27,56 @@ import org.springframework.integration.core.MessageHandler;
* Round-robin implementation of {@link LoadBalancingStrategy}. This
* implementation will keep track of the index of the handler that has been
* tried first and use a different starting handler every dispatch.
*
*
* @author Iwein Fuld
* @author Mark Fisher
* @author Oleg Zhurakousky
* @since 1.0.3
*/
public class RoundRobinLoadBalancingStrategy implements LoadBalancingStrategy {
private final AtomicInteger currentHandlerIndex = new AtomicInteger();
/**
* Returns an iterator that starts at a new point in the list every time the
* Returns an iterator that starts at a new point in the collection every time the
* first part of the list that is skipped will be used at the end of the
* iteration, so it guarantees all handlers are returned once on subsequent
* <code>next()</code> invocations.
*/
public final Iterator<MessageHandler> getHandlerIterator(final Message<?> message, final List<MessageHandler> handlers) {
public final Iterator<MessageHandler> getHandlerIterator(final Message<?> message, final Collection<MessageHandler> handlers) {
int size = handlers.size();
if (size == 0) {
if (size < 2) {
this.getNextHandlerStartIndex(size);
return handlers.iterator();
}
return this.buildHandlerIterator(size, handlers.toArray(new MessageHandler[size]));
}
private Iterator<MessageHandler> buildHandlerIterator(int size, final MessageHandler[] handlers){
int nextHandlerStartIndex = getNextHandlerStartIndex(size);
List<MessageHandler> reorderedHandlers = new ArrayList<MessageHandler>(
handlers.subList(nextHandlerStartIndex, size));
reorderedHandlers.addAll(handlers.subList(0, nextHandlerStartIndex));
return reorderedHandlers.iterator();
final MessageHandler[] reorderedHandlers = new MessageHandler[size];
System.arraycopy(handlers, nextHandlerStartIndex, reorderedHandlers, 0, size-nextHandlerStartIndex);
System.arraycopy(handlers, 0, reorderedHandlers, size-nextHandlerStartIndex, 0+nextHandlerStartIndex);
return new Iterator<MessageHandler>() {
int currentIndex = 0;
public boolean hasNext() {
return currentIndex < reorderedHandlers.length;
}
public MessageHandler next() {
return reorderedHandlers[currentIndex++];
}
public void remove() {
throw new UnsupportedOperationException("Remove is not supported by this Iterator");
}
};
}
/**
@@ -62,8 +85,12 @@ public class RoundRobinLoadBalancingStrategy implements LoadBalancingStrategy {
* <code>size</code>.
*/
private int getNextHandlerStartIndex(int size) {
int indexTail = currentHandlerIndex.getAndIncrement() % size;
return indexTail < 0 ? indexTail + size : indexTail;
if (size > 0){
int indexTail = currentHandlerIndex.getAndIncrement() % size;
return indexTail < 0 ? indexTail + size : indexTail;
}
else {
return size;
}
}
}

View File

@@ -42,7 +42,7 @@ import org.springframework.integration.core.MessageHandler;
* <p/>
* A load-balancing strategy may be provided to this class to control the order in
* which the handlers will be tried.
*
*
* @author Iwein Fuld
* @author Mark Fisher
* @author Gary Russell
@@ -52,7 +52,7 @@ import org.springframework.integration.core.MessageHandler;
public class UnicastingDispatcher extends AbstractDispatcher {
private volatile boolean failover = true;
private ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private volatile LoadBalancingStrategy loadBalancingStrategy;
private final Executor executor;
@@ -84,7 +84,7 @@ public class UnicastingDispatcher extends AbstractDispatcher {
lock.lock();
try {
this.loadBalancingStrategy = loadBalancingStrategy;
}
}
finally {
lock.unlock();
}
@@ -145,7 +145,7 @@ public class UnicastingDispatcher extends AbstractDispatcher {
}
} finally {
lock.unlock();
}
}
return this.getHandlers().iterator();
}

View File

@@ -16,20 +16,21 @@
package org.springframework.integration.dispatcher;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.springframework.core.Ordered;
import static org.junit.Assert.assertEquals;
import org.springframework.core.Ordered;
/**
* @author Oleg Zhurakousky
* @since 1.0.3
*/
@SuppressWarnings("unchecked")
public class OrderedAwareLinkedHashSetTests {
public class OrderedAwareCopyOnWriteArraySetTests {
/**
* Tests that semantics of the LinkedHashSet were not broken
@@ -37,7 +38,7 @@ public class OrderedAwareLinkedHashSetTests {
@SuppressWarnings("rawtypes")
@Test
public void testAddUnordered(){
OrderedAwareLinkedHashSet setToTest = new OrderedAwareLinkedHashSet();
OrderedAwareCopyOnWriteArraySet setToTest = new OrderedAwareCopyOnWriteArraySet();
setToTest.add("foo");
setToTest.add("bar");
setToTest.add("baz");
@@ -49,16 +50,16 @@ public class OrderedAwareLinkedHashSetTests {
}
/**
* Tests that semantics of TreeSet(Comparator) were not broken.
* However, there is a special Comparator (instantiated by default) for this implementation of Set,
* However, there is a special Comparator (instantiated by default) for this implementation of Set,
* which allows elements with the same "order" as long as these elements themselves are not equal.
* In this case element with the same order will be placed to the right (appended next to) of
* the already existing element, thus preserving the order of insertion (LinkedHashset semantics)
* within the elements that have the same "order" value.
* In this case element with the same order will be placed to the right (appended next to) of
* the already existing element, thus preserving the order of insertion (LinkedHashset semantics)
* within the elements that have the same "order" value.
*/
@SuppressWarnings("rawtypes")
@Test
public void testAddOrdered(){
OrderedAwareLinkedHashSet setToTest = new OrderedAwareLinkedHashSet();
OrderedAwareCopyOnWriteArraySet setToTest = new OrderedAwareCopyOnWriteArraySet();
Object o1 = new Foo(3);
Object o2 = new Foo(1);
Object o3 = new Foo(2);
@@ -78,7 +79,7 @@ public class OrderedAwareLinkedHashSetTests {
setToTest.add(o7);
setToTest.add(o8);
setToTest.add(o9);
setToTest.add(o10);
setToTest.add(o10);
assertEquals(10, setToTest.size());
Object[] elements = setToTest.toArray();
assertEquals(o7, elements[0]);
@@ -92,7 +93,7 @@ public class OrderedAwareLinkedHashSetTests {
assertEquals(o5, elements[8]);
assertEquals(o6, elements[9]);
}
@SuppressWarnings("rawtypes")
@Test
public void testAddAllOrderedUnordered(){
@@ -116,9 +117,9 @@ public class OrderedAwareLinkedHashSetTests {
tempList.add(o7);
tempList.add(o8);
tempList.add(o9);
tempList.add(o10);
tempList.add(o10);
assertEquals(10, tempList.size());
OrderedAwareLinkedHashSet orderAwareSet = new OrderedAwareLinkedHashSet();
OrderedAwareCopyOnWriteArraySet orderAwareSet = new OrderedAwareCopyOnWriteArraySet();
orderAwareSet.addAll(tempList);
Object[] elements = orderAwareSet.toArray();
assertEquals(o7, elements[0]);
@@ -132,7 +133,7 @@ public class OrderedAwareLinkedHashSetTests {
assertEquals(o3, elements[8]);
assertEquals(o10, elements[9]);
}
@Test
public void testConcurrent(){
for(int i = 0; i < 1000; i++){
@@ -141,7 +142,7 @@ public class OrderedAwareLinkedHashSetTests {
}
@SuppressWarnings("rawtypes")
private void doConcurrent(){
final OrderedAwareLinkedHashSet setToTest = new OrderedAwareLinkedHashSet();
final OrderedAwareCopyOnWriteArraySet setToTest = new OrderedAwareCopyOnWriteArraySet();
final Object o1 = new Foo(3);
final Object o2 = new Foo(1);
final Object o3 = new Foo(2);
@@ -163,20 +164,20 @@ public class OrderedAwareLinkedHashSetTests {
});
Thread t2 = new Thread(new Runnable() {
public void run() {
setToTest.add(o2);
setToTest.add(o4);
setToTest.add(o6);
setToTest.add(o8);
setToTest.add(o10);
setToTest.add(o2);
setToTest.add(o4);
setToTest.add(o6);
setToTest.add(o8);
setToTest.add(o10);
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
setToTest.add(1);
setToTest.add(new Foo(2));
setToTest.add(3);
setToTest.add(new Foo(9));
setToTest.add(8);
setToTest.add(1);
setToTest.add(new Foo(2));
setToTest.add(3);
setToTest.add(new Foo(9));
setToTest.add(8);
}
});
t1.start();
@@ -190,8 +191,8 @@ public class OrderedAwareLinkedHashSetTests {
e.printStackTrace();
throw new RuntimeException(e);
}
assertEquals(15, setToTest.size());
}
/**
@@ -216,7 +217,7 @@ public class OrderedAwareLinkedHashSetTests {
Object o8 = new Foo(Ordered.HIGHEST_PRECEDENCE);
Object o9 = new Foo(4);
Object o10 = "Baz";
tempList.add(o1);
tempList.add(o2);
tempList.add(o3);
@@ -226,8 +227,8 @@ public class OrderedAwareLinkedHashSetTests {
tempList.add(o7);
tempList.add(o8);
tempList.add(o9);
tempList.add(o10);
final OrderedAwareLinkedHashSet orderAwareSet = new OrderedAwareLinkedHashSet();
tempList.add(o10);
final OrderedAwareCopyOnWriteArraySet orderAwareSet = new OrderedAwareCopyOnWriteArraySet();
Thread t1 = new Thread(new Runnable() {
public void run() {
orderAwareSet.addAll(tempList);
@@ -256,9 +257,9 @@ public class OrderedAwareLinkedHashSetTests {
Thread t3 = new Thread(new Runnable() {
public void run() {
orderAwareSet.add("hello");
orderAwareSet.add("hello again");
orderAwareSet.add("hello again");
}
});
});
t1.start();
t2.start();
@@ -275,13 +276,14 @@ public class OrderedAwareLinkedHashSetTests {
assertEquals(18, elements.length);
}
private static class Foo implements Ordered {
private int order;
private final int order;
public Foo(int order){
this.order = order;
}
public int getOrder() {
return order;
}
}
@Override
public String toString(){
return "Foo-" + order;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -47,7 +47,7 @@ public class FtpOutboundChannelAdapterParserTests {
@Test
public void testFtpOutboundChannelAdapterComplete() throws Exception{
ApplicationContext ac =
ApplicationContext ac =
new ClassPathXmlApplicationContext("FtpOutboundChannelAdapterParserTests-context.xml", this.getClass());
Object consumer = ac.getBean("ftpOutbound");
assertTrue(consumer instanceof EventDrivenConsumer);
@@ -70,7 +70,7 @@ public class FtpOutboundChannelAdapterParserTests {
assertEquals("localhost", TestUtils.getPropertyValue(sessionFactory, "host"));
assertEquals(22, TestUtils.getPropertyValue(sessionFactory, "port"));
assertEquals(23, TestUtils.getPropertyValue(handler, "order"));
//verify subscription order
//verify subscription order
@SuppressWarnings("unchecked")
Set<MessageHandler> handlers = (Set<MessageHandler>) TestUtils
.getPropertyValue(
@@ -80,7 +80,7 @@ public class FtpOutboundChannelAdapterParserTests {
assertSame(TestUtils.getPropertyValue(ac.getBean("ftpOutbound2"), "handler"), iterator.next());
assertSame(handler, iterator.next());
}
@Test(expected=BeanCreationException.class)
public void testFailWithEmptyRfsAndAcdTrue() throws Exception{
new ClassPathXmlApplicationContext("FtpOutboundChannelAdapterParserTests-fail.xml", this.getClass());

View File

@@ -29,6 +29,7 @@ import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -65,6 +66,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gary Russell
* @author Oleg Zhurakousky
* @since 2.0
*/
@ContextConfiguration

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -19,7 +19,6 @@ package org.springframework.integration.sftp.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
@@ -53,7 +52,7 @@ public class OutboundChannelAdapterParserTests {
@Test
public void testOutboundChannelAdapterWithId(){
ApplicationContext context =
ApplicationContext context =
new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context.xml", this.getClass());
Object consumer = context.getBean("sftpOutboundAdapter");
assertTrue(consumer instanceof EventDrivenConsumer);
@@ -90,7 +89,7 @@ public class OutboundChannelAdapterParserTests {
@Test
public void testOutboundChannelAdapterWithWithRemoteDirectoryAndFileExpression(){
ApplicationContext context =
ApplicationContext context =
new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context.xml", this.getClass());
Object consumer = context.getBean("sftpOutboundAdapterWithExpression");
assertTrue(consumer instanceof EventDrivenConsumer);
@@ -106,9 +105,9 @@ public class OutboundChannelAdapterParserTests {
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryDirectory"));
assertNull(TestUtils.getPropertyValue(handler, "temporaryDirectoryExpressionProcessor"));
}
@Test
public void testOutboundChannelAdapterWithNoTemporaryFileName(){
ApplicationContext context =
@@ -121,12 +120,12 @@ public class OutboundChannelAdapterParserTests {
@Test(expected=BeanDefinitionStoreException.class)
public void testFailWithRemoteDirAndExpression(){
new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context-fail.xml", this.getClass());
}
@Test(expected=BeanDefinitionStoreException.class)
public void testFailWithFileExpressionAndFileGenerator(){
new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context-fail-fileFileGen.xml", this.getClass());
}
}

View File

@@ -18,6 +18,8 @@ package org.springframework.integration.test.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.springframework.integration.test.matcher.HeaderMatcher.hasHeader;
import static org.springframework.integration.test.matcher.PayloadMatcher.hasPayload;
import java.util.ArrayList;
import java.util.List;
@@ -26,27 +28,24 @@ import org.springframework.integration.Message;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.test.context.ContextConfiguration;
import static org.springframework.integration.test.matcher.PayloadMatcher.hasPayload;
import static org.springframework.integration.test.matcher.HeaderMatcher.hasHeader;
@ContextConfiguration
@ContextConfiguration
public class MessageScenariosTests extends AbstractRequestResponseScenarioTests {
@Override
protected List<RequestResponseScenario> defineRequestResponseScenarios() {
List<RequestResponseScenario> scenarios= new ArrayList<RequestResponseScenario>();
RequestResponseScenario scenario1 = new RequestResponseScenario(
"inputChannel","outputChannel")
.setPayload("hello")
.setResponseValidator(new PayloadValidator<String>() {
.setResponseValidator(new PayloadValidator<String>() {
@Override
protected void validateResponse(String response) {
assertEquals("HELLO",response);
}
});
scenarios.add(scenario1);
scenarios.add(scenario1);
RequestResponseScenario scenario2 = new RequestResponseScenario(
"inputChannel","outputChannel")
.setMessage(MessageBuilder.withPayload("hello").setHeader("foo", "bar").build())
@@ -55,11 +54,11 @@ public class MessageScenariosTests extends AbstractRequestResponseScenarioTests
protected void validateMessage(Message<?> message) {
assertThat(message,hasPayload("HELLO"));
assertThat(message,hasHeader("foo","bar"));
}
}
});
scenarios.add(scenario2);
scenarios.add(scenario2);
RequestResponseScenario scenario3 = new RequestResponseScenario(
"inputChannel2","outputChannel2")
.setMessage(MessageBuilder.withPayload("hello").setHeader("foo", "bar").build())
@@ -68,11 +67,11 @@ public class MessageScenariosTests extends AbstractRequestResponseScenarioTests
protected void validateMessage(Message<?> message) {
assertThat(message,hasPayload("HELLO"));
assertThat(message,hasHeader("foo","bar"));
}
}
});
scenarios.add(scenario3);
scenarios.add(scenario3);
return scenarios;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@@ -56,7 +56,7 @@ public class PresenceOutboundChannelAdapterParserTests {
.getPropertyValue(pollingConsumer, "handler");
assertEquals(23, TestUtils.getPropertyValue(handler, "order"));
}
@Test
public void testRosterEventOutboundChannelAdapterParserEventConsumer(){
Object eventConsumer = context.getBean("eventOutboundRosterAdapter");
@@ -65,7 +65,7 @@ public class PresenceOutboundChannelAdapterParserTests {
.getPropertyValue(eventConsumer, "handler");
assertEquals(34, TestUtils.getPropertyValue(handler, "order"));
}
@Test
public void testRosterEventOutboundChannel(){
Object channel = context.getBean("eventOutboundRosterChannel");