Search in sources :

Example 1 with FetchResponseHandler

use of com.zimbra.cs.mailclient.imap.FetchResponseHandler in project zm-mailbox by Zimbra.

the class ImapFolderSync method refetchPurgedMsgsInConversation.

protected void refetchPurgedMsgsInConversation(ParsedMessage pm) throws ServiceException, IOException {
    if (!mailbox.getAccount().isFeatureDataSourcePurgingEnabled()) {
        return;
    }
    Threader threader = pm.getThreader(ds.getMailbox());
    List<PurgedConversation> purgedConvs = threader.lookupPurgedConversations(ds);
    if (purgedConvs.size() == 0) {
        return;
    } else {
        for (PurgedConversation conv : purgedConvs) {
            ImapConnection conn;
            try {
                conn = getRefetchConnection();
            } catch (ServiceException e) {
                ZimbraLog.datasource.warn("could not establish IMAP connection to refetch purged messages");
                return;
            }
            for (PurgedMessage msg : conv.getMessages()) {
                String remoteFolderId = msg.getRemoteFolder();
                String msgUid = msg.getUid();
                final Integer folderId = msg.getLocalFolderId();
                ZimbraLog.datasource.info("restoring message " + msgUid + " in remote folder " + remoteFolderId);
                conn.select(remoteFolderId);
                final Map<Long, MessageData> msgFlags = conn.uidFetch(msgUid, "(FLAGS INTERNALDATE)");
                FetchResponseHandler handler = new FetchResponseHandler() {

                    @Override
                    public void handleFetchResponse(MessageData md) throws Exception {
                        long uid = md.getUid();
                        IOExceptionHandler.getInstance().trackSyncItem(mailbox, uid);
                        try {
                            handleFetch(md, msgFlags, folderId, false, false);
                            clearError(uid);
                        } catch (OutOfMemoryError e) {
                            Zimbra.halt("Out of memory", e);
                        } catch (Exception e) {
                            if (!IOExceptionHandler.getInstance().isRecoverable(mailbox, uid, "Exception re-fetching UID " + uid, e)) {
                                syncFailed("re-fetch failed for uid " + uid, e);
                                SyncErrorManager.incrementErrorCount(ds, remoteId(uid));
                            }
                        }
                    }
                };
                conn.uidFetch(msgUid, "BODY.PEEK[]", handler);
            }
            conv.unpurge();
        }
    }
}
Also used : MessageData(com.zimbra.cs.mailclient.imap.MessageData) Threader(com.zimbra.cs.mailbox.Threader) ImapConnection(com.zimbra.cs.mailclient.imap.ImapConnection) MailException(com.zimbra.cs.mailclient.MailException) ServiceException(com.zimbra.common.service.ServiceException) SQLException(java.sql.SQLException) CommandFailedException(com.zimbra.cs.mailclient.CommandFailedException) IOException(java.io.IOException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) RemoteServiceException(com.zimbra.common.service.RemoteServiceException) PurgedConversation(com.zimbra.cs.db.DbDataSource.PurgedConversation) PurgedMessage(com.zimbra.cs.db.DbDataSource.PurgedMessage) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) RemoteServiceException(com.zimbra.common.service.RemoteServiceException) FetchResponseHandler(com.zimbra.cs.mailclient.imap.FetchResponseHandler)

Example 2 with FetchResponseHandler

use of com.zimbra.cs.mailclient.imap.FetchResponseHandler in project zm-mailbox by Zimbra.

the class ImapFolderSync method fetchMessages.

private void fetchMessages(String seq) throws ServiceException, IOException {
    final Map<Long, MessageData> flagsByUid = connection.uidFetch(seq, "(FLAGS INTERNALDATE)");
    removeDeleted(flagsByUid);
    final Set<Long> uidSet = flagsByUid.keySet();
    if (uidSet.isEmpty())
        return;
    FetchResponseHandler handler = new FetchResponseHandler() {

        @Override
        public void handleFetchResponse(MessageData md) throws Exception {
            long uid = md.getUid();
            IOExceptionHandler.getInstance().trackSyncItem(mailbox, uid);
            try {
                handleFetch(md, flagsByUid, true);
                clearError(uid);
            } catch (OutOfMemoryError e) {
                Zimbra.halt("Out of memory", e);
            } catch (Exception e) {
                if (!IOExceptionHandler.getInstance().isRecoverable(mailbox, uid, "Exception syncing UID " + uid + " in folder " + remoteFolder.getPath(), e)) {
                    syncFailed("Fetch failed for uid " + uid, e);
                    SyncErrorManager.incrementErrorCount(ds, remoteId(uid));
                }
            }
            uidSet.remove(uid);
        }
    };
    // Try fetching group of messages first
    LOG.debug("Fetching messages for sequence: " + seq);
    try {
        connection.uidFetch(getSequence(uidSet), "BODY.PEEK[]", handler);
    } catch (CommandFailedException e) {
        String msg = "UID FETCH failed: " + e.toString();
        checkCanContinue(msg, e);
        LOG.warn(msg, e);
    }
    if (uidSet.isEmpty())
        return;
    LOG.info("Fetching remaining messages one at a time for UIDs: " + uidSet);
    for (long uid : getOrderedUids(uidSet)) {
        try {
            LOG.info("Fetching message for uid: " + uid);
            MessageData md = connection.uidFetch(uid, "BODY.PEEK[]");
            if (md == null) {
                //FLAGS returned data for UID but BODY.PEEK[] is not; server error; provide more meaningful error than NPE
                throw ServiceException.FAILURE("Server returned no response for UID FETCH " + uid + " BODY.PEEK[]", null);
            }
            handler.handleFetchResponse(md);
        } catch (Exception e) {
            String msg = "Error while fetching message for UID " + uid;
            checkCanContinue(msg, e);
            LOG.warn(msg, e);
        }
    }
    if (!uidSet.isEmpty()) {
        LOG.error("Unable to fetch messages for uids: " + uidSet);
    }
}
Also used : MessageData(com.zimbra.cs.mailclient.imap.MessageData) FetchResponseHandler(com.zimbra.cs.mailclient.imap.FetchResponseHandler) MailException(com.zimbra.cs.mailclient.MailException) ServiceException(com.zimbra.common.service.ServiceException) SQLException(java.sql.SQLException) CommandFailedException(com.zimbra.cs.mailclient.CommandFailedException) IOException(java.io.IOException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) RemoteServiceException(com.zimbra.common.service.RemoteServiceException) CommandFailedException(com.zimbra.cs.mailclient.CommandFailedException)

Example 3 with FetchResponseHandler

use of com.zimbra.cs.mailclient.imap.FetchResponseHandler in project zm-mailbox by Zimbra.

the class RemoteFolder method getFlags.

/*
     * Fetch message flags for specific UID sequence. Exclude messages which
     * have been flagged \Deleted.
     */
public List<MessageData> getFlags(long startUid, long endUid) throws IOException {
    final List<MessageData> mds = new ArrayList<MessageData>();
    String end = endUid > 0 ? String.valueOf(endUid) : "*";
    connection.uidFetch(startUid + ":" + end, "FLAGS", new FetchResponseHandler() {

        public void handleFetchResponse(MessageData md) {
            Flags flags = md.getFlags();
            if (flags != null && !flags.isDeleted()) {
                mds.add(md);
            }
        }
    });
    // result.
    if (endUid <= 0 && mds.size() == 1 && mds.get(0).getUid() < startUid) {
        return Collections.emptyList();
    }
    return mds;
}
Also used : MessageData(com.zimbra.cs.mailclient.imap.MessageData) ArrayList(java.util.ArrayList) FetchResponseHandler(com.zimbra.cs.mailclient.imap.FetchResponseHandler) Flags(com.zimbra.cs.mailclient.imap.Flags)

Aggregations

FetchResponseHandler (com.zimbra.cs.mailclient.imap.FetchResponseHandler)3 MessageData (com.zimbra.cs.mailclient.imap.MessageData)3 RemoteServiceException (com.zimbra.common.service.RemoteServiceException)2 ServiceException (com.zimbra.common.service.ServiceException)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2 CommandFailedException (com.zimbra.cs.mailclient.CommandFailedException)2 MailException (com.zimbra.cs.mailclient.MailException)2 IOException (java.io.IOException)2 SQLException (java.sql.SQLException)2 PurgedConversation (com.zimbra.cs.db.DbDataSource.PurgedConversation)1 PurgedMessage (com.zimbra.cs.db.DbDataSource.PurgedMessage)1 Threader (com.zimbra.cs.mailbox.Threader)1 Flags (com.zimbra.cs.mailclient.imap.Flags)1 ImapConnection (com.zimbra.cs.mailclient.imap.ImapConnection)1 ArrayList (java.util.ArrayList)1