Search in sources :

Example 1 with CalSummaryCache

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache in project zm-mailbox by Zimbra.

the class Search method runSimpleAppointmentQuery.

private static void runSimpleAppointmentQuery(Element parent, SearchParams params, OperationContext octxt, ZimbraSoapContext zsc, Account authAcct, Mailbox mbox, List<String> folderIdStrs) throws ServiceException {
    Set<MailItem.Type> types = params.getTypes();
    MailItem.Type type = types.size() == 1 ? Iterables.getOnlyElement(types) : MailItem.Type.APPOINTMENT;
    if (params.getSortBy() != null) {
        parent.addAttribute(MailConstants.A_SORTBY, params.getSortBy().toString());
    }
    parent.addAttribute(MailConstants.A_QUERY_OFFSET, params.getOffset());
    parent.addAttribute(MailConstants.A_QUERY_MORE, false);
    List<ItemId> folderIids = new ArrayList<ItemId>(folderIdStrs.size());
    for (String folderIdStr : folderIdStrs) {
        folderIids.add(new ItemId(folderIdStr, zsc));
    }
    Provisioning prov = Provisioning.getInstance();
    MailboxManager mboxMgr = MailboxManager.getInstance();
    Server localServer = prov.getLocalServer();
    Map<Server, Map<String, List<Integer>>> /* folder ids */
    groupedByServer = groupByServer(ItemId.groupFoldersByAccount(octxt, mbox, folderIids));
    // Look up in calendar cache first.
    if (LC.calendar_cache_enabled.booleanValue()) {
        CalSummaryCache calCache = CalendarCacheManager.getInstance().getSummaryCache();
        long rangeStart = params.getCalItemExpandStart();
        long rangeEnd = params.getCalItemExpandEnd();
        for (Iterator<Map.Entry<Server, Map<String, List<Integer>>>> serverIter = groupedByServer.entrySet().iterator(); serverIter.hasNext(); ) {
            Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry = serverIter.next();
            Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
            // for each account
            for (Iterator<Map.Entry<String, List<Integer>>> acctIter = accountFolders.entrySet().iterator(); acctIter.hasNext(); ) {
                Map.Entry<String, List<Integer>> acctEntry = acctIter.next();
                String acctId = acctEntry.getKey();
                List<Integer> folderIds = acctEntry.getValue();
                // Setup ItemIdFormatter appropriate for this folder which might not be in the authed account
                // but also take note of presense of <noqualify/> in SOAP context
                ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, zsc.wantsUnqualifiedIds());
                // for each folder
                for (Iterator<Integer> iterFolderId = folderIds.iterator(); iterFolderId.hasNext(); ) {
                    int folderId = iterFolderId.next();
                    try {
                        CalendarDataResult result = calCache.getCalendarSummary(octxt, acctId, folderId, type, rangeStart, rangeEnd, true);
                        if (result != null) {
                            // Found data in cache.
                            iterFolderId.remove();
                            addCalendarDataToResponse(parent, zsc, ifmt, result.data, result.allowPrivateAccess);
                        }
                    } catch (ServiceException e) {
                        String ecode = e.getCode();
                        if (ecode.equals(ServiceException.PERM_DENIED)) {
                            // share permission was revoked
                            ZimbraLog.calendar.warn("Ignoring permission error during calendar search of folder %s", ifmt.formatItemId(folderId), e);
                        } else if (ecode.equals(MailServiceException.NO_SUCH_FOLDER)) {
                            // shared calendar folder was deleted by the owner
                            ZimbraLog.calendar.warn("Ignoring deleted calendar folder %s", ifmt.formatItemId(folderId));
                        } else {
                            throw e;
                        }
                        iterFolderId.remove();
                    }
                }
                if (folderIds.isEmpty())
                    acctIter.remove();
            }
            if (accountFolders.isEmpty())
                serverIter.remove();
        }
    }
    // For any remaining calendars, we have to get the data the hard way.
    for (Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry : groupedByServer.entrySet()) {
        Server server = serverMapEntry.getKey();
        Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
        if (server.equals(localServer)) {
            // local server
            for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
                String acctId = entry.getKey();
                List<Integer> folderIds = entry.getValue();
                if (folderIds.isEmpty())
                    continue;
                Account targetAcct = prov.get(AccountBy.id, acctId);
                if (targetAcct == null) {
                    ZimbraLog.calendar.warn("Skipping unknown account " + acctId + " during calendar search");
                    continue;
                }
                Mailbox targetMbox = mboxMgr.getMailboxByAccount(targetAcct);
                searchLocalAccountCalendars(parent, params, octxt, zsc, authAcct, targetMbox, folderIds, type);
            }
        } else {
            // remote server
            searchRemoteAccountCalendars(parent, params, zsc, authAcct, accountFolders);
        }
    }
}
Also used : Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ArrayList(java.util.ArrayList) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) ItemId(com.zimbra.cs.service.util.ItemId) Provisioning(com.zimbra.cs.account.Provisioning) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ArrayList(java.util.ArrayList) List(java.util.List) MailItem(com.zimbra.cs.mailbox.MailItem) MailboxManager(com.zimbra.cs.mailbox.MailboxManager) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) HashMap(java.util.HashMap) Map(java.util.Map) CalSummaryCache(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache)

Example 2 with CalSummaryCache

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache in project zm-mailbox by Zimbra.

the class GetMiniCal method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    Account authAcct = getAuthenticatedAccount(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    Element response = getResponseElement(zsc);
    long rangeStart = request.getAttributeLong(MailConstants.A_CAL_START_TIME);
    long rangeEnd = request.getAttributeLong(MailConstants.A_CAL_END_TIME);
    List<ItemId> folderIids = new ArrayList<ItemId>();
    for (Iterator<Element> foldersIter = request.elementIterator(MailConstants.E_FOLDER); foldersIter.hasNext(); ) {
        Element fElem = foldersIter.next();
        ItemId iidFolder = new ItemId(fElem.getAttribute(MailConstants.A_ID), zsc);
        folderIids.add(iidFolder);
    }
    ICalTimeZone tz = parseTimeZone(request);
    if (tz == null)
        // requestor's time zone, not mailbox owner's
        tz = Util.getAccountTimeZone(authAcct);
    TreeSet<String> busyDates = new TreeSet<String>();
    Provisioning prov = Provisioning.getInstance();
    MailboxManager mboxMgr = MailboxManager.getInstance();
    Server localServer = prov.getLocalServer();
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
    Map<ItemId, Resolved> resolved = resolveMountpoints(octxt, mbox, folderIids);
    Map<ItemId, ItemId> /* requested iid */
    reverseMap = new HashMap<ItemId, ItemId>();
    for (Map.Entry<ItemId, Resolved> entry : resolved.entrySet()) {
        ItemId requestedIid = entry.getKey();
        Resolved res = entry.getValue();
        if (res.error == null) {
            reverseMap.put(res.iid, requestedIid);
        } else {
            addError(response, ifmt.formatItemId(requestedIid), res.error.getCode(), res.error.getMessage());
        }
    }
    Map<Server, Map<String, List<Integer>>> /* folder ids */
    groupedByServer = Search.groupByServer(groupFoldersByAccount(resolved));
    // Look up in calendar cache first.
    if (LC.calendar_cache_enabled.booleanValue()) {
        CalSummaryCache calCache = CalendarCacheManager.getInstance().getSummaryCache();
        Calendar cal = new GregorianCalendar(tz);
        for (Iterator<Map.Entry<Server, Map<String, List<Integer>>>> serverIter = groupedByServer.entrySet().iterator(); serverIter.hasNext(); ) {
            Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry = serverIter.next();
            Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
            // for each account
            for (Iterator<Map.Entry<String, List<Integer>>> acctIter = accountFolders.entrySet().iterator(); acctIter.hasNext(); ) {
                Map.Entry<String, List<Integer>> acctEntry = acctIter.next();
                String acctId = acctEntry.getKey();
                List<Integer> folderIds = acctEntry.getValue();
                // for each folder
                for (Iterator<Integer> iterFolderId = folderIds.iterator(); iterFolderId.hasNext(); ) {
                    int folderId = iterFolderId.next();
                    try {
                        CalendarDataResult result = calCache.getCalendarSummary(octxt, acctId, folderId, MailItem.Type.APPOINTMENT, rangeStart, rangeEnd, true);
                        if (result != null) {
                            // Found data in cache.
                            iterFolderId.remove();
                            addBusyDates(cal, result.data, rangeStart, rangeEnd, busyDates);
                        }
                    } catch (ServiceException e) {
                        iterFolderId.remove();
                        ItemId iid = new ItemId(acctId, folderId);
                        // Error must mention folder id requested by client.
                        ItemId reqIid = reverseMap.get(iid);
                        if (reqIid != null) {
                            ZimbraLog.calendar.warn("Error accessing calendar folder " + ifmt.formatItemId(reqIid), e);
                            addError(response, ifmt.formatItemId(reqIid), e.getCode(), e.getMessage());
                        } else {
                            ZimbraLog.calendar.warn("Error accessing calendar folder; resolved id=" + ifmt.formatItemId(iid) + " (missing reverse mapping)", e);
                            addError(response, ifmt.formatItemId(iid), e.getCode(), e.getMessage());
                        }
                    }
                }
                if (folderIds.isEmpty())
                    acctIter.remove();
            }
            if (accountFolders.isEmpty())
                serverIter.remove();
        }
    }
    // For any remaining calendars, we have to get the data the hard way.
    for (Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry : groupedByServer.entrySet()) {
        Server server = serverMapEntry.getKey();
        Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
        if (server.equals(localServer)) {
            // local server
            for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
                String acctId = entry.getKey();
                List<Integer> folderIds = entry.getValue();
                Account targetAcct = prov.get(AccountBy.id, acctId);
                if (targetAcct == null) {
                    ZimbraLog.calendar.warn("Skipping unknown account " + acctId + " during minical search");
                    continue;
                }
                Mailbox targetMbox = mboxMgr.getMailboxByAccount(targetAcct);
                for (int folderId : folderIds) {
                    try {
                        doLocalFolder(octxt, tz, targetMbox, folderId, rangeStart, rangeEnd, busyDates);
                    } catch (ServiceException e) {
                        ItemId iid = new ItemId(acctId, folderId);
                        // Error must mention folder id requested by client.
                        ItemId reqIid = reverseMap.get(iid);
                        if (reqIid != null) {
                            ZimbraLog.calendar.warn("Error accessing calendar folder " + ifmt.formatItemId(reqIid), e);
                            addError(response, ifmt.formatItemId(reqIid), e.getCode(), e.getMessage());
                        } else {
                            ZimbraLog.calendar.warn("Error accessing calendar folder; resolved id=" + ifmt.formatItemId(iid) + " (missing reverse mapping)", e);
                            addError(response, ifmt.formatItemId(iid), e.getCode(), e.getMessage());
                        }
                    }
                }
            }
        } else {
            // remote server
            // mail service soap requests want to see a target account
            String nominalTargetAcctId = null;
            List<String> folderList = new ArrayList<String>();
            for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
                String acctId = entry.getKey();
                if (nominalTargetAcctId == null)
                    nominalTargetAcctId = acctId;
                ItemIdFormatter ifmtRemote = new ItemIdFormatter(authAcct.getId(), acctId, false);
                List<Integer> folderIds = entry.getValue();
                for (int folderId : folderIds) {
                    folderList.add(ifmtRemote.formatItemId(folderId));
                }
            }
            doRemoteFolders(zsc, nominalTargetAcctId, folderList, rangeStart, rangeEnd, busyDates, response, reverseMap, ifmt);
        }
    }
    for (String datestamp : busyDates) {
        Element dateElem = response.addElement(MailConstants.E_CAL_MINICAL_DATE);
        dateElem.setText(datestamp);
    }
    return response;
}
Also used : Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) ArrayList(java.util.ArrayList) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) ItemId(com.zimbra.cs.service.util.ItemId) Provisioning(com.zimbra.cs.account.Provisioning) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) List(java.util.List) OperationContext(com.zimbra.cs.mailbox.OperationContext) Calendar(java.util.Calendar) GregorianCalendar(java.util.GregorianCalendar) GregorianCalendar(java.util.GregorianCalendar) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) MailboxManager(com.zimbra.cs.mailbox.MailboxManager) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) HashMap(java.util.HashMap) Map(java.util.Map) IcalXmlStrMap(com.zimbra.cs.mailbox.calendar.IcalXmlStrMap) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) CalSummaryCache(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache)

Aggregations

ZMailbox (com.zimbra.client.ZMailbox)2 ServiceException (com.zimbra.common.service.ServiceException)2 Account (com.zimbra.cs.account.Account)2 Provisioning (com.zimbra.cs.account.Provisioning)2 Server (com.zimbra.cs.account.Server)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2 Mailbox (com.zimbra.cs.mailbox.Mailbox)2 MailboxManager (com.zimbra.cs.mailbox.MailboxManager)2 CalSummaryCache (com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache)2 CalendarDataResult (com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult)2 ItemId (com.zimbra.cs.service.util.ItemId)2 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 Element (com.zimbra.common.soap.Element)1 AccountServiceException (com.zimbra.cs.account.AccountServiceException)1 MailItem (com.zimbra.cs.mailbox.MailItem)1