package org.osaf.caldav4j;
import net.fortuna.ical4j.model.*;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.DtStart;
import net.fortuna.ical4j.model.property.Summary;
import net.fortuna.ical4j.model.property.Uid;
import net.sf.ehcache.*;
import net.sf.ehcache.event.CacheEventListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.osaf.caldav4j.cache.CalDAVResourceCache;
import org.osaf.caldav4j.cache.EhCacheResourceCache;
import org.osaf.caldav4j.exceptions.CalDAV4JException;
import org.osaf.caldav4j.exceptions.ResourceNotFoundException;
import org.osaf.caldav4j.functional.support.CaldavFixtureHarness;
import org.osaf.caldav4j.util.ICalendarUtils;
import java.util.List;
import static org.junit.Assert.*;
/**
* Tests CalDAVCalendarCollection with caching on. Mostly the same tests, but
* with an EhCahche instead of a NoOp Cache
*
* @author bobbyrullo
*
*/
public class CalDAVCalendarCollectionWithCacheTest extends BaseTestCase {
private static final String HREF_TO_RESOURCE_CACHE = "hrefToResourceCache";
private static final String UID_TO_HREF_CACHE = "uidToHrefCache";
private static final Log log = LogFactory
.getLog(CalDAVCalendarCollectionWithCacheTest.class);
// private CalDAV4JMethodFactory methodFactory = new CalDAV4JMethodFactory();
//
// private HttpClient httpClient = createHttpClient();
private CalDAVResourceCache cache = null;
private class TestingCacheEventListener implements CacheEventListener {
public Element lastUidToHrefElementPut = null;
public Element lastHreftoResourceElementPut = null;
public Element lastUidToHrefElementRemoved = null;
public Element lastHreftoResourceElementRemoved = null;
public Element lastUidToHrefElementUpdated = null;
public Element lastHreftoResourceElementUpdated = null;
public void notifyElementEvicted(Ehcache cache, Element element) {
}
public void notifyRemoveAll(Ehcache cache) {
}
public Object clone(){
return (Object) (new TestingCacheEventListener());
}
public void dispose() {
}
public void notifyElementExpired(Ehcache cache, Element element) {
}
public void notifyElementPut(Ehcache cache, Element element)
throws CacheException {
if (cache.getName().equals(UID_TO_HREF_CACHE)) {
lastUidToHrefElementPut = element;
} else if (cache.getName().equals(HREF_TO_RESOURCE_CACHE)) {
lastHreftoResourceElementPut = element;
}
}
public void notifyElementRemoved(Ehcache cache, Element element)
throws CacheException {
if (cache.getName().equals(UID_TO_HREF_CACHE)) {
lastUidToHrefElementRemoved = element;
} else if (cache.getName().equals(HREF_TO_RESOURCE_CACHE)) {
lastHreftoResourceElementRemoved = element;
}
}
public void notifyElementUpdated(Ehcache cache, Element element)
throws CacheException {
if (cache.getName().equals(UID_TO_HREF_CACHE)) {
lastUidToHrefElementUpdated = element;
} else if (cache.getName().equals(HREF_TO_RESOURCE_CACHE)) {
lastHreftoResourceElementUpdated = element;
}
}
};
public TestingCacheEventListener listener = null;
@Before
public void setUp() throws Exception {
super.setUp();
CaldavFixtureHarness.provisionSimpleEvents(fixture);
cache = new EhCacheResourceCache();
listener = new TestingCacheEventListener();
CacheManager cacheManager = CacheManager.create();
Cache uidToHrefCache = new Cache(UID_TO_HREF_CACHE, 1000, false, false,
600, 300, false, 0);
uidToHrefCache.getCacheEventNotificationService().registerListener(listener);
cacheManager.addCache(uidToHrefCache);
Cache hrefToResourceCache = new Cache(HREF_TO_RESOURCE_CACHE, 1000,
false, false, 600, 300, false, 0);
hrefToResourceCache.getCacheEventNotificationService().registerListener(listener);
cacheManager.addCache(hrefToResourceCache);
((EhCacheResourceCache) cache)
.setHrefToResourceCache(hrefToResourceCache);
((EhCacheResourceCache) cache).setUidToHrefCache(uidToHrefCache);
}
@After
public void tearDown() throws Exception {
CacheManager cacheManager = CacheManager.create();
cacheManager.removeCache(UID_TO_HREF_CACHE);
cacheManager.removeCache(HREF_TO_RESOURCE_CACHE);
fixture.tearDown();
}
@Test
public void testGetCalendar() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
Calendar calendar = null;
try {
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
ICS_DAILY_NY_5PM_UID);
} catch (CalDAV4JException ce) {
assertNull(ce);
}
assertNotNull(calendar);
VEvent vevent = ICalendarUtils.getFirstEvent(calendar);
assertNotNull(vevent);
String summary = ICalendarUtils.getSummaryValue(vevent);
assertEquals(ICS_DAILY_NY_5PM_SUMMARY, summary);
CalDAV4JException calDAV4JException = null;
try {
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
"NON_EXISTENT_RESOURCE");
} catch (CalDAV4JException ce) {
calDAV4JException = ce;
}
assertNotNull(calDAV4JException);
}
@Test
public void testGetCalendarByPath() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
Calendar calendar = null;
try {
calendar = calendarCollection.getCalendarByPath(fixture.getHttpClient(),
ICS_DAILY_NY_5PM_UID + ".ics");
} catch (CalDAV4JException ce) {
assertNull(ce);
}
assertNotNull(calendar);
VEvent vevent = ICalendarUtils.getFirstEvent(calendar);
assertNotNull(vevent);
String summary = ICalendarUtils.getSummaryValue(vevent);
assertEquals(ICS_DAILY_NY_5PM_SUMMARY, summary);
CalDAV4JException calDAV4JException = null;
try {
calendar = calendarCollection.getCalendarByPath(fixture.getHttpClient(),
"NON_EXISTENT_RESOURCE");
} catch (CalDAV4JException ce) {
calDAV4JException = ce;
}
assertNotNull(calDAV4JException);
}
@Test
public void testGetEventResources() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
Date beginDate = ICalendarUtils.createDateTime(2006, 0, 1, null, true);
Date endDate = ICalendarUtils.createDateTime(2006, 0, 9, null, true);
List<Calendar> l = calendarCollection.getEventResources(fixture.getHttpClient(),
beginDate, endDate);
for (Calendar calendar : l) {
ComponentList vevents = calendar.getComponents().getComponents(
Component.VEVENT);
VEvent ve = (VEvent) vevents.get(0);
String uid = ICalendarUtils.getUIDValue(ve);
int correctNumberOfEvents = -1;
if (ICS_DAILY_NY_5PM_UID.equals(uid)) {
// one for each day
correctNumberOfEvents = 1;
} else if (ICS_ALL_DAY_JAN1_UID.equals(uid)) {
correctNumberOfEvents = 1;
} else if (ICS_NORMAL_PACIFIC_1PM_UID.equals(uid)) {
correctNumberOfEvents = 1;
} else if (ICS_FLOATING_JAN2_7PM_UID.equals(uid)) {
correctNumberOfEvents = 0;
} else {
fail(uid
+ " is not the uid of any event that should have been returned");
}
assertEquals(correctNumberOfEvents, vevents.size());
}
// 3 calendars - one for each resource (not including expanded
// recurrences)
assertEquals(3, l.size());
}
// TODO wait on floating test until we can pass timezones
@Test
@Ignore
public void testGetEventResourcesFloatingIssues() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
// make sure our 7pm event gets returned
Date beginDate = ICalendarUtils.createDateTime(2006, 0, 2, 19, 0, 0, 0,
null, true);
Date endDate = ICalendarUtils.createDateTime(2006, 0, 2, 20, 1, 0, 0,
null, true);
List<Calendar> l = calendarCollection.getEventResources(fixture.getHttpClient(),
beginDate, endDate);
assertTrue(hasEventWithUID(l, ICS_FLOATING_JAN2_7PM_UID));
beginDate = ICalendarUtils.createDateTime(2006, 0, 2, 20, 1, 0, 0,
null, true);
endDate = ICalendarUtils.createDateTime(2006, 0, 2, 20, 2, 0, 0, null,
true);
l = calendarCollection
.getEventResources(fixture.getHttpClient(), beginDate, endDate);
assertFalse(hasEventWithUID(l, ICS_FLOATING_JAN2_7PM_UID));
}
@Test
public void testAddNewRemove() throws Exception {
String newUid = "NEW_UID";
String newEvent = "NEW_EVENT";
VEvent ve = new VEvent();
DtStart dtStart = new DtStart(new DateTime());
Summary summary = new Summary(newEvent);
Uid uid = new Uid(newUid);
ve.getProperties().add(dtStart);
ve.getProperties().add(summary);
ve.getProperties().add(uid);
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
calendarCollection.addEvent(fixture.getHttpClient(), ve, null);
Calendar calendar = calendarCollection.getCalendarForEventUID(
fixture.getHttpClient(), newUid);
assertNotNull(calendar);
calendarCollection.deleteEvent(fixture.getHttpClient(), newUid);
calendar = null;
try {
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
newUid);
} catch (ResourceNotFoundException e) {
}
assertNull(calendar);
}
@Test
public void testUpdateEvent() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
Calendar calendar = calendarCollection.getCalendarForEventUID(
fixture.getHttpClient(), ICS_NORMAL_PACIFIC_1PM_UID);
VEvent ve = ICalendarUtils.getFirstEvent(calendar);
// sanity!
assertNotNull(calendar);
assertEquals(ICS_NORMAL_PACIFIC_1PM_SUMMARY, ICalendarUtils
.getSummaryValue(ve));
ICalendarUtils.addOrReplaceProperty(ve, new Summary("NEW"));
calendarCollection.updateMasterEvent(fixture.getHttpClient(), ve, null);
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
ICS_NORMAL_PACIFIC_1PM_UID);
ve = ICalendarUtils.getFirstEvent(calendar);
assertEquals("NEW", ICalendarUtils.getSummaryValue(ve));
}
/**
* We want to make sure that the cache actually is being used!
*
*/
@Test
public void testCacheGetsHit() throws Exception {
CalDAVCalendarCollection calendarCollection = createCalDAVCalendarCollection();
// basically ensure that nothing has been put in the cache yet
assertNull(listener.lastHreftoResourceElementPut);
assertNull(listener.lastUidToHrefElementPut);
Calendar calendar = calendarCollection.getCalendarForEventUID(
fixture.getHttpClient(), ICS_NORMAL_PACIFIC_1PM_UID);
// NOW something should be in the cache - let's make sure
assertNotNull("Something didn't get put in the cache!",
listener.lastHreftoResourceElementPut);
assertNotNull("Something didn't get put in the cache!",
listener.lastUidToHrefElementPut);
// did the right thing get put in the cache? Check the uid.
assertEquals(listener.lastUidToHrefElementPut.getKey(),
ICS_NORMAL_PACIFIC_1PM_UID);
String href = (String) listener.lastUidToHrefElementPut.getValue();
assertEquals(listener.lastHreftoResourceElementPut.getKey(), href);
long lastUID2HrefAccessTime = listener.lastUidToHrefElementPut
.getLastAccessTime();
long lastHref2ResourceAccessTime = listener.lastHreftoResourceElementPut
.getLastAccessTime();
// ok let's get the same resource again, and make sure the cache really
// was hit
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
ICS_NORMAL_PACIFIC_1PM_UID);
// lets see if the cache time changed:
// Note: On some systems, the time may not have changed, thus >=, instead of the previous >
assertTrue(listener.lastUidToHrefElementPut.getLastAccessTime() >= lastUID2HrefAccessTime);
assertTrue(listener.lastHreftoResourceElementPut.getLastAccessTime() >= lastHref2ResourceAccessTime);
// update the values for the next test
Element uidToHrefElement = listener.lastUidToHrefElementPut;
Element hrefToResourceElement = listener.lastHreftoResourceElementPut;
lastUID2HrefAccessTime = listener.lastUidToHrefElementPut
.getLastAccessTime();
lastHref2ResourceAccessTime = listener.lastHreftoResourceElementPut
.getLastAccessTime();
// let's get some random thing from the collection
calendar = calendarCollection.getCalendarForEventUID(fixture.getHttpClient(),
ICS_ALL_DAY_JAN1_UID);
// this time, the access times should be the same since we accessed a
// different resource
assertEquals(uidToHrefElement.getLastAccessTime(), lastUID2HrefAccessTime);
assertEquals(hrefToResourceElement.getLastAccessTime(), lastHref2ResourceAccessTime);
}
private boolean hasEventWithUID(List<Calendar> cals, String uid) {
for (Calendar cal : cals) {
ComponentList vEvents = cal.getComponents().getComponents(
Component.VEVENT);
if (vEvents.size() == 0) {
return false;
}
VEvent ve = (VEvent) vEvents.get(0);
String curUid = ICalendarUtils.getUIDValue(ve);
if (curUid != null && uid.equals(curUid)) {
return true;
}
}
return false;
}
private CalDAVCalendarCollection createCalDAVCalendarCollection() {
CalDAVCalendarCollection calendarCollection = new CalDAVCalendarCollection(
fixture.getCollectionPath(), createHostConfiguration(), fixture.getMethodFactory(),
CalDAVConstants.PROC_ID_DEFAULT);
calendarCollection.setCache(cache);
return calendarCollection;
}
}