use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class EffectiveACLCache method notifyCommittedChanges.
public void notifyCommittedChanges(PendingModifications mods, int changeId) {
Set<EffectiveACLCacheKey> keysToInvalidate = new HashSet<EffectiveACLCacheKey>();
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
// permission change or move to a new parent folder.
if (whatChanged instanceof Folder && (change.why & (Change.ACL | Change.FOLDER)) != 0) {
Folder folder = (Folder) whatChanged;
// Invalidate all child folders because their inherited ACL will need to be recomputed.
String acctId = folder.getMailbox().getAccountId();
// includes "folder" folder
List<Folder> subfolders = folder.getSubfolderHierarchy();
for (Folder subf : subfolders) {
EffectiveACLCacheKey key = new EffectiveACLCacheKey(acctId, subf.getId());
keysToInvalidate.add(key);
}
}
}
}
if (mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER) {
String acctId = entry.getKey().getAccountId();
if (acctId == null)
// just to be safe
continue;
EffectiveACLCacheKey key = new EffectiveACLCacheKey(acctId, entry.getKey().getItemId());
keysToInvalidate.add(key);
}
}
}
try {
mMemcachedLookup.removeMulti(keysToInvalidate);
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Unable to notify folder acl cache. Some cached data may become stale.", e);
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CalSummaryCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingModifications mods, int changeId) {
if (mods.created != null) {
for (Map.Entry<ModificationKey, MailItem> entry : mods.created.entrySet()) {
MailItem item = entry.getValue();
if (item instanceof CalendarItem) {
int folderId = item.getFolderId();
invalidateItem(item.getMailbox(), folderId, item.getId());
}
}
}
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
if (whatChanged instanceof CalendarItem) {
CalendarItem item = (CalendarItem) whatChanged;
Mailbox mbox = item.getMailbox();
int folderId = item.getFolderId();
int itemId = item.getId();
invalidateItem(mbox, folderId, itemId);
// If this is a folder move, invalidate the item from the old folder too.
if ((change.why & Change.FOLDER) != 0) {
String accountId = mbox.getAccountId();
int prevFolderId;
synchronized (mSummaryCache) {
prevFolderId = mSummaryCache.getFolderForItem(accountId, itemId);
}
if (prevFolderId != folderId && prevFolderId != SummaryLRU.FOLDER_NOT_FOUND) {
invalidateItem(mbox, prevFolderId, itemId);
}
}
}
}
}
if (mods.deleted != null) {
String lastAcctId = null;
Mailbox lastMbox = null;
for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.APPOINTMENT || type == MailItem.Type.TASK) {
// We only have item id. Look up the folder id of the item in the cache.
Mailbox mbox = null;
String acctId = entry.getKey().getAccountId();
// just to be safe
if (acctId == null)
continue;
if (acctId.equals(lastAcctId)) {
// Deletion by id list usually happens because of a folder getting emptied.
// It's highly likely the items all belong to the same mailbox, let alone folder.
mbox = lastMbox;
} else {
try {
mbox = MailboxManager.getInstance().getMailboxByAccountId(acctId, FetchMode.DO_NOT_AUTOCREATE);
} catch (ServiceException e) {
ZimbraLog.calendar.error("Error looking up the mailbox of account in delete notification: account=" + acctId, e);
continue;
}
}
if (mbox != null) {
lastAcctId = acctId;
lastMbox = mbox;
int itemId = entry.getKey().getItemId();
String accountId = mbox.getAccountId();
int folderId;
synchronized (mSummaryCache) {
folderId = mSummaryCache.getFolderForItem(accountId, itemId);
}
if (folderId != SummaryLRU.FOLDER_NOT_FOUND) {
invalidateItem(mbox, folderId, itemId);
}
}
}
}
}
if (MemcachedConnector.isConnected()) {
mMemcachedCache.notifyCommittedChanges(mods, changeId);
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CalSummaryMemcachedCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingModifications mods, int changeId) {
Set<CalSummaryKey> keysToInvalidate = new HashSet<CalSummaryKey>();
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
if (whatChanged instanceof Folder) {
Folder folder = (Folder) whatChanged;
MailItem.Type viewType = folder.getDefaultView();
if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
CalSummaryKey key = new CalSummaryKey(folder.getMailbox().getAccountId(), folder.getId());
keysToInvalidate.add(key);
}
}
}
}
if (mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER) {
// We only have item id. Assume it's a folder id and issue a delete.
String acctId = entry.getKey().getAccountId();
if (acctId == null)
// just to be safe
continue;
CalSummaryKey key = new CalSummaryKey(acctId, entry.getKey().getItemId());
keysToInvalidate.add(key);
}
// Let's not worry about hard deletes of invite/reply emails. It has no practical benefit.
}
}
try {
mMemcachedLookup.removeMulti(keysToInvalidate);
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Unable to notify ctag info cache. Some cached data may become stale.", e);
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class PendingRemoteNotificationsTest method testPendingRemoteNotifications.
@Test
public void testPendingRemoteNotifications() throws Exception {
String acctId = "12aa345b-2b47-44e6-8cb8-7fdfa18c1a9f";
ImapMessageInfo imapMsg1 = new ImapMessageInfo(123, 123, Type.MESSAGE.toString(), 0, null);
BaseItemInfo msg1 = ModificationItem.itemUpdate(imapMsg1, Mailbox.ID_FOLDER_INBOX, acctId);
ImapMessageInfo imapMsg2 = new ImapMessageInfo(456, 456, Type.MESSAGE.toString(), 0, null);
BaseItemInfo msg2 = ModificationItem.itemUpdate(imapMsg2, Mailbox.ID_FOLDER_INBOX, acctId);
PendingRemoteModifications prm = new PendingRemoteModifications();
prm.recordCreated(msg1);
assertTrue(!prm.created.isEmpty());
BaseItemInfo newItem = prm.created.get(new ModificationKey(msg1));
assertEquals(imapMsg1.getId(), newItem.getIdInMailbox());
assertEquals(imapMsg1.getImapUid(), newItem.getImapUid());
assertEquals(acctId, newItem.getAccountId());
// rename a tag
ZimbraTag tag = ModificationItem.tagRename(2, "tagname");
prm.recordModified(tag, acctId, Change.NAME);
Change tagChange = prm.modified.get(new ModificationKey(acctId, tag.getTagId()));
assertNotNull(tagChange);
assertEquals(Change.NAME, tagChange.why);
assertEquals(tag, tagChange.what);
// rename a folder
ModificationItem folder = ModificationItem.folderRename(3, "/newpath", acctId);
prm.recordModified(folder, Change.NAME);
Change folderChange = prm.modified.get(new ModificationKey(folder));
assertNotNull(folderChange);
assertEquals(Change.NAME, folderChange.why);
assertEquals(folder, folderChange.what);
// modify an item
BaseItemInfo updateItem = ModificationItem.itemUpdate(imapMsg2, Mailbox.ID_FOLDER_INBOX, acctId);
prm.recordModified(updateItem, Change.FLAGS);
Change itemChange = prm.modified.get(new ModificationKey(updateItem));
assertNotNull(itemChange);
assertEquals(Change.FLAGS, itemChange.why);
assertEquals(updateItem, itemChange.what);
// adding a delete notification for the previously added message
// should remove it from the created map, and NOT add it to the deleted map
prm.recordDeleted(Type.MESSAGE, acctId, imapMsg1.getId());
assertTrue(prm.created.isEmpty());
assertTrue(prm.deleted == null);
// adding a delete notification for a previously modified message
// should remove it from the modified map AND add it to the deleted map
prm.recordDeleted(Type.MESSAGE, acctId, imapMsg2.getId());
assertNull(prm.modified.get(new ModificationKey(msg2)));
assertEquals(1, prm.deleted.size());
Change deletionChange = prm.deleted.get(new ModificationKey(msg2));
assertEquals(Change.NONE, deletionChange.why);
assertEquals(MailItem.Type.MESSAGE, deletionChange.what);
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class FilterListener method notify.
@Override
public void notify(ChangeNotification notification) {
if (notification.mods.modified != null && EVENTS.contains(notification.op)) {
for (PendingModifications.Change change : notification.mods.modified.values()) {
if (change.what instanceof Folder) {
if ((change.why & Change.PARENT) == 0 && (change.why & Change.NAME) == 0) {
continue;
}
Folder folder = (Folder) change.what;
Folder oldFolder = (Folder) change.preModifyObj;
if (oldFolder == null) {
ZimbraLog.filter.warn("Cannot determine the old folder name for %s.", folder.getName());
continue;
}
updateFilterRules(notification.mailboxAccount, folder, oldFolder.getPath());
} else if (change.what instanceof Tag) {
if ((change.why & Change.NAME) == 0) {
continue;
}
Tag tag = (Tag) change.what;
Tag oldTag = (Tag) change.preModifyObj;
if (oldTag == null) {
ZimbraLog.filter.warn("Cannot determine the old tag name for %s.", tag.getName());
continue;
}
updateFilterRules(notification.mailboxAccount, tag, oldTag.getName());
}
}
}
if (notification.mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : notification.mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER || type == MailItem.Type.MOUNTPOINT) {
Folder oldFolder = (Folder) entry.getValue().preModifyObj;
if (oldFolder == null) {
ZimbraLog.filter.warn("Cannot determine the old folder name for %s.", entry.getKey());
continue;
}
updateFilterRules(notification.mailboxAccount, (Folder) null, oldFolder.getPath());
} else if (type == MailItem.Type.TAG) {
Tag oldTag = (Tag) entry.getValue().preModifyObj;
updateFilterRules(notification.mailboxAccount, oldTag);
}
}
}
}
Aggregations