/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.core.routing;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mule.runtime.api.message.Message.of;
import static org.mule.tck.MuleTestUtils.getTestFlow;
import org.mule.runtime.api.exception.MuleException;
import org.mule.runtime.api.message.Message;
import org.mule.runtime.core.DefaultEventContext;
import org.mule.runtime.core.api.Event;
import org.mule.runtime.core.api.EventContext;
import org.mule.runtime.core.api.MuleContext;
import org.mule.runtime.core.api.MuleSession;
import org.mule.runtime.core.api.construct.Flow;
import org.mule.runtime.core.routing.correlation.CorrelationSequenceComparator;
import org.mule.runtime.core.routing.correlation.EventCorrelatorCallback;
import org.mule.runtime.core.routing.correlation.ResequenceMessagesCorrelatorCallback;
import org.mule.runtime.core.session.DefaultMuleSession;
import org.mule.tck.junit4.AbstractMuleContextTestCase;
import org.mule.tck.testmodels.fruit.Apple;
import java.util.Comparator;
import org.junit.Test;
public class ResequencerTestCase extends AbstractMuleContextTestCase {
public ResequencerTestCase() {
setStartContext(true);
}
@Test
public void testMessageResequencer() throws Exception {
MuleSession session = new DefaultMuleSession();
Flow flow = getTestFlowWithComponent("test", Apple.class);
assertNotNull(flow);
TestEventResequencer router = new TestEventResequencer(3);
router.setMuleContext(muleContext);
router.setFlowConstruct(flow);
router.initialise();
EventContext context = DefaultEventContext.create(flow, TEST_CONNECTOR_LOCATION, "foo");
Message message1 = of("test event A");
Message message2 = of("test event B");
Message message3 = of("test event C");
Event event1 = Event.builder(context).message(message1).flow(getTestFlow(muleContext)).session(session).build();
Event event2 = Event.builder(context).message(message2).flow(getTestFlow(muleContext)).session(session).build();
Event event3 = Event.builder(context).message(message3).flow(getTestFlow(muleContext)).session(session).build();
assertNull(router.process(event2));
assertNull(router.process(event3));
Event resultEvent = router.process(event1);
assertNotNull(resultEvent);
Message resultMessage = resultEvent.getMessage();
assertNotNull(resultMessage);
assertTrue(getPayloadAsString(resultMessage).equals("test event A")
|| getPayloadAsString(resultMessage).equals("test event B") || getPayloadAsString(resultMessage).equals("test event C"));
}
@Test
public void testMessageResequencerWithComparator() throws Exception {
MuleSession session = new DefaultMuleSession();
Flow flow = getTestFlowWithComponent("test", Apple.class);
assertNotNull(flow);
TestEventResequencer router = new TestEventResequencer(3);
router.setMuleContext(muleContext);
router.setFlowConstruct(flow);
router.initialise();
EventContext context = DefaultEventContext.create(flow, TEST_CONNECTOR_LOCATION, "foo");
Message message1 = of("test event A");
Message message2 = of("test event B");
Message message3 = of("test event C");
Event event1 = Event.builder(context).message(message1).flow(getTestFlow(muleContext)).session(session).build();
Event event2 = Event.builder(context).message(message2).flow(getTestFlow(muleContext)).session(session).build();
Event event3 = Event.builder(context).message(message3).flow(getTestFlow(muleContext)).session(session).build();
// set a resequencing comparator. We need to reset the router since it will
// not process the same event group
// twice
router = new TestEventResequencer(3);
router.setMuleContext(muleContext);
router.setEventComparator(new EventPayloadComparator());
router.setFlowConstruct(flow);
router.initialise();
assertNull(router.process(event2));
assertNull(router.process(event3));
Event resultEvent = router.process(event1);
assertNotNull(resultEvent);
Message resultMessage = resultEvent.getMessage();
assertNotNull(resultMessage);
assertEquals("test event C", getPayloadAsString(resultMessage));
}
public static class TestEventResequencer extends Resequencer {
private int eventCount = 0;
private int eventthreshold = 1;
public TestEventResequencer(int eventthreshold) {
super();
this.eventthreshold = eventthreshold;
this.setEventComparator(new CorrelationSequenceComparator());
}
@Override
protected EventCorrelatorCallback getCorrelatorCallback(MuleContext muleContext) {
return new ResequenceMessagesCorrelatorCallback(getEventComparator(), muleContext, storePrefix) {
@Override
public boolean shouldAggregateEvents(EventGroup events) {
eventCount++;
if (eventCount == eventthreshold) {
eventCount = 0;
return true;
}
return false;
}
};
}
}
public static class EventPayloadComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
try {
return ((Event) o1).getMessageAsString(muleContext).compareTo(((Event) o2).getMessageAsString(muleContext));
} catch (MuleException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
}
}