/*
* 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 java.util.Optional.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.mule.runtime.api.message.Message;
import org.mule.runtime.core.api.Event;
import org.mule.runtime.core.api.registry.RegistrationException;
import org.mule.runtime.api.store.ObjectStoreException;
import org.mule.runtime.core.api.store.PartitionableObjectStore;
import org.mule.runtime.core.util.UUID;
import org.mule.runtime.core.util.store.DefaultObjectStoreFactoryBean;
import org.mule.tck.junit4.AbstractMuleContextTestCase;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.commons.collections.IteratorUtils;
import org.junit.Before;
import org.junit.Test;
public class EventGroupTestCase extends AbstractMuleContextTestCase {
private PartitionableObjectStore<Event> objectStore;
@Before
public void before() throws RegistrationException {
objectStore = (PartitionableObjectStore) muleContext.getRegistry().lookupObject(DefaultObjectStoreFactoryBean.class)
.createDefaultInMemoryObjectStore();
}
@Test
public void concurrentIteration() throws Exception {
EventGroup eg = new EventGroup(UUID.getUUID(), muleContext);
eg.initEventsStore(objectStore);
assertFalse(eg.iterator().hasNext());
eg.addEvent(eventBuilder().message(Message.of("foo1")).build());
eg.addEvent(eventBuilder().message(Message.of("foo2")).build());
assertTrue(eg.iterator().hasNext());
// now add events while we iterate over the group
Iterator<Event> i = eg.iterator();
assertNotNull(i.next());
eg.addEvent(eventBuilder().message(Message.of("foo3")).build());
assertNotNull(i.next());
eg.addEvent(eventBuilder().message(Message.of("foo4")).build());
assertFalse(i.hasNext());
// the added events should be in there though
assertEquals(4, eg.size());
}
@Test
public void eventGroupEquality() throws ObjectStoreException {
EventGroup g1 = new EventGroup("foo", muleContext);
g1.initEventsStore(objectStore);
EventGroup g2 = new EventGroup("foo", muleContext);
g2.initEventsStore(objectStore);
EventGroup g3 = new EventGroup("bar", muleContext);
g3.initEventsStore(objectStore);
assertEquals(g1, g2);
assertFalse(g1.equals(g3));
MyEventGroup mg = new MyEventGroup("foo");
assertEquals(g1, mg);
assertEquals(mg, g1);
mg = new MyEventGroup("bar");
assertFalse(g1.equals(mg));
assertFalse(mg.equals(g1));
}
@Test
public void eventGroupHashCode() throws ObjectStoreException {
String uuid = UUID.getUUID();
EventGroup g1 = new EventGroup(uuid, muleContext);
g1.initEventsStore(objectStore);
EventGroup g2 = new EventGroup(uuid, muleContext);
g2.initEventsStore(objectStore);
EventGroup g3 = new EventGroup(UUID.getUUID(), muleContext);
g3.initEventsStore(objectStore);
assertEquals(g1.hashCode(), g2.hashCode());
assertEquals(g1, g2);
assertFalse(g1.hashCode() == g3.hashCode());
assertFalse(g1.equals(g3));
assertFalse(g3.equals(g1));
// now test Set compatibility
Set<EventGroup> s = new HashSet<>();
s.add(g1);
// make sure g1 is in the set
assertTrue(s.contains(g1));
assertEquals(1, s.size());
// g2 has the same hash, so it should match
assertTrue(s.contains(g2));
// even though there is only one object in the set
assertEquals(1, s.size());
// make sure g3 cannot be found
assertFalse(s.contains(g3));
// now add it
assertTrue(s.add(g3));
// make sure it is in there
assertTrue(s.contains(g3));
// make sure it is really in there
assertEquals(2, s.size());
}
@Test
public void eventGroupComparison() throws InterruptedException, ObjectStoreException {
String uuid = UUID.getUUID();
EventGroup g1 = new EventGroup(uuid, muleContext);
g1.initEventsStore(objectStore);
EventGroup g2 = new EventGroup(uuid, muleContext);
g2.initEventsStore(objectStore);
EventGroup g3 = new EventGroup(UUID.getUUID(), muleContext);
g3.initEventsStore(objectStore);
// test comparison against null
try {
g1.compareTo(null);
fail("expected NullPointerException");
} catch (NullPointerException npe) {
// expected
}
assertEquals(0, g1.compareTo(g2));
/*
* guids are randomly generated, we cannot compare them with '<' '>' we used to generate them this way:
* generator.generateTimeBasedUUID().toString() but now we generate them as java.util.UUID.randomUUID().toString()
*/
assertTrue(g1.compareTo(g3) != 0);
assertTrue(g3.compareTo(g1) != 0);
assertTrue(g3.compareTo(g2) != 0);
// when the groupId is not Comparable, the creation time is used as fallback
g1 = new EventGroup(new Object(), muleContext);
// sleep a mini bit to ensure that both event groups do not accidentially have the same
// creation timestamp
Thread.sleep(10);
g2 = new EventGroup(new Object(), muleContext);
// g1 is older (smaller) than g2
assertTrue(g1.compareTo(g2) < 0);
assertTrue(g2.compareTo(g1) > 0);
}
@Test
public void eventGroupConversionToArray() throws Exception {
EventGroup eg = new EventGroup(UUID.getUUID(), muleContext);
eg.initEventsStore(objectStore);
eg.addEvent(eventBuilder().message(Message.of("foo1")).build());
eg.addEvent(eventBuilder().message(Message.of("foo2")).build());
Object[] array1 = IteratorUtils.toArray(eg.iterator(false));
Event[] array2 = eg.toArray(false);
assertTrue(Arrays.equals(array1, array2));
}
@Test
public void eventGroupConversionToString() throws Exception {
EventGroup eg = new EventGroup(UUID.getUUID(), muleContext);
eg.initEventsStore(objectStore);
String es = eg.toString();
assertTrue(es.endsWith("events=0}"));
Event firstEvent = eventBuilder().message(Message.of("foo")).build();
String firstId = firstEvent.getCorrelationId();
eg.addEvent(firstEvent);
es = eg.toString();
assertTrue(es.contains("events=1"));
assertTrue(es.endsWith("[" + firstId + "]}"));
Event secondEvent = eventBuilder()
.message(Message.of("foo2"))
.build();
String secondId = secondEvent.getCorrelationId();
eg.addEvent(secondEvent);
es = eg.toString();
assertTrue(es.contains("events=2"));
assertTrue(es.contains(firstId));
assertTrue(es.contains(secondId));
}
@Test
public void mergedSessions() throws Exception {
EventGroup eg = new EventGroup(UUID.getUUID(), muleContext);
eg.initEventsStore(objectStore);
assertFalse(eg.iterator().hasNext());
Event event1 = eventBuilder().message(Message.of("foo1")).build();
Event event2 = eventBuilder().message(Message.of("foo2")).build();
Event event3 = eventBuilder().message(Message.of("foo3")).build();
event1.getSession().setProperty("key1", "value1");
event1.getSession().setProperty("key2", "value2");
event2.getSession().setProperty("KEY2", "value2NEW");
event2.getSession().setProperty("key3", "value3");
event3.getSession().setProperty("key4", "value4");
eg.addEvent(event1);
System.out.println(event1.getSession());
eg.addEvent(event2);
System.out.println(event2.getSession());
eg.addEvent(event3);
System.out.println(event3.getSession());
Event result = eg.getMessageCollectionEvent();
assertEquals("value1", result.getSession().getProperty("key1"));
// Cannot assert this because the ordering of events aren't ordered. See MULE-5998
// assertEquals("value2NEW", result.getSession().getProperty("key2"));
assertEquals("value3", result.getSession().getProperty("key3"));
assertEquals("value4", result.getSession().getProperty("key4"));
}
private static class MyEventGroup extends EventGroup {
private static final long serialVersionUID = 1L;
public MyEventGroup(Object groupId) {
super(groupId, muleContext);
}
public MyEventGroup(Object groupId, int expectedSize) {
super(groupId, muleContext, of(expectedSize), "EventGroupTestCase");
}
}
}