Search in sources :

Example 11 with UnderlyingData

use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.

the class MailboxErrorUtil method handleCascadeFailure.

/**
 * Attempt to delete a list of ids whih previously failed due to foreign key constraint violation. Intended to find which items had the FK issue, and provide a bit more detail about them.
 * Throws the original exception argument, or wraps it with additional details if individual deletes fail
 */
static void handleCascadeFailure(Mailbox mbox, List<Integer> cascadeIds, ServiceException e) throws ServiceException {
    if (causeMatchesFKFailure(e)) {
        ZimbraLog.mailbox.error("deleting cascadeIds failed due to foreign key constraint failed; attempting to delete individually and find failure");
        LinkedList<Integer> failures = new LinkedList<Integer>();
        for (Integer id : cascadeIds) {
            try {
                List<Integer> singleItemList = Collections.singletonList(id);
                ZimbraLog.mailbox.debug("attempting to delete id [" + id + "]");
                DbMailItem.delete(mbox, singleItemList, false);
                ZimbraLog.mailbox.debug("deleted [" + id + "] OK");
            } catch (ServiceException se) {
                ZimbraLog.mailbox.error("deleted FAILED for [" + id + "] due to exception", se);
                failures.add(id);
            }
        }
        if (!failures.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            // find the id,type,subject for each entry. this should help us figure out what's not being removed correctly...
            for (Integer id : failures) {
                MailItem item = mbox.getItemById(id, MailItem.Type.UNKNOWN);
                String logMsg = "failure item id[" + id + "] type[" + item.getType() + ":" + item.getClass().getSimpleName() + "] subject[" + item.getSubject() + "] size[" + item.getSize() + "] folder[" + item.getFolderId() + "] parent[" + item.getParentId() + "]";
                sb.append(logMsg).append("\r\n");
                ZimbraLog.mailbox.error(logMsg);
                if (item instanceof Conversation) {
                    Conversation conv = (Conversation) item;
                    List<Message> children = conv.getMessages();
                    if (children != null && children.size() > 0) {
                        ZimbraLog.mailbox.error("converstaion[" + conv.getId() + "] still has " + children.size() + " children.");
                        for (Message msg : children) {
                            logMsg = "child[" + msg + "] type[" + msg.getType() + "] subject[" + msg.getSubject() + "] in folder[" + msg.getFolderId() + ":" + msg.getFolder().getName() + "] still associated with conv [" + conv.getId() + "]";
                            sb.append(logMsg);
                            ZimbraLog.mailbox.error(logMsg);
                        }
                    }
                } else if (item instanceof Folder) {
                    Folder folder = (Folder) item;
                    List<UnderlyingData> children = DbMailItem.getByFolder(folder, MailItem.Type.UNKNOWN, SortBy.NONE);
                    if (children != null && children.size() > 0) {
                        ZimbraLog.mailbox.error("folder[" + folder.getId() + "] still has " + children.size() + " children.");
                        for (UnderlyingData data : children) {
                            logMsg = "child[" + item + "] type[" + data.type + "] subject[" + data.getSubject() + "] still present in folder [" + folder.getId() + "]";
                            sb.append(logMsg);
                            ZimbraLog.mailbox.error(logMsg);
                        }
                    }
                } else {
                    ZimbraLog.mailbox.warn("cascade failure in unexpected type [" + item.getType() + ":" + item.getClass().getSimpleName() + "] other than folder or conversation");
                }
            }
            throw ServiceException.FAILURE(e.getMessage() + "---" + sb.toString(), e);
        } else {
            throw ServiceException.FAILURE(e.getMessage() + "--- no additional data available from attempting individual deletes.", e);
        }
    } else {
        throw e;
    }
}
Also used : UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) LinkedList(java.util.LinkedList) DbMailItem(com.zimbra.cs.db.DbMailItem) ServiceException(com.zimbra.common.service.ServiceException) List(java.util.List) LinkedList(java.util.LinkedList)

Example 12 with UnderlyingData

use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.

the class MailboxIndex method indexItemList.

/**
 * Index a potentially very large list of {@link MailItem}s. Iterate through the list of items, fetch each one and
 * call generateIndexData(). Buffer the items, IndexData into a chunk and when the chunk gets sufficiently large,
 * run a Mailbox transaction to actually do the indexing
 *
 * @param ids item IDs to index
 * @param status progress will be written to the status
 * @throws ServiceException {@link ServiceException#INTERRUPTED} if {@link #cancelReIndex()} is called
 */
private void indexItemList(Collection<Integer> ids, BatchStatus status) throws ServiceException {
    assert (mailbox.lock.isUnlocked());
    status.setTotal(ids.size());
    if (ids.isEmpty()) {
        return;
    }
    // we re-index 'chunks' of items -- up to a certain size or count
    List<Mailbox.IndexItemEntry> chunk = new ArrayList<Mailbox.IndexItemEntry>();
    long chunkByteSize = 0;
    int i = 0;
    for (int id : ids) {
        i++;
        status.addProcessed(1);
        // Fetch the item and generate the list of Lucene documents to index. Do this without holding the Mailbox
        // lock. Once we've accumulated a "chunk" of items, do a mailbox transaction to actually add them to the
        // index.
        ZimbraLog.index.debug("Tokenizing id=%d", id);
        MailItem item = null;
        try {
            mailbox.beginReadTransaction("IndexItemList-Fetch", null);
            item = mailbox.getItemById(id, MailItem.Type.UNKNOWN, false);
        } catch (MailServiceException.NoSuchItemException e) {
            // fallback to dumpster
            try {
                item = mailbox.getItemById(id, MailItem.Type.UNKNOWN, true);
            } catch (MailServiceException.NoSuchItemException again) {
                // The item has just been deleted.
                ZimbraLog.index.debug("deferred item no longer exist id=%d", id);
                removeDeferredId(id);
                continue;
            }
        } catch (MailServiceException e) {
            // fetch without metadata because reindex will regenerate metadata
            if (MailServiceException.INVALID_METADATA.equals(e.getCode()) && isReIndexInProgress()) {
                UnderlyingData ud = DbMailItem.getById(mailbox, id, MailItem.Type.UNKNOWN, false);
                // ignore corrupted metadata
                ud.metadata = null;
                item = mailbox.getItem(ud);
            } else {
                throw e;
            }
        } catch (Exception e) {
            ZimbraLog.index.warn("Failed to fetch deferred item id=%d", id, e);
            status.addFailed(1);
            continue;
        } finally {
            mailbox.endTransaction(item != null);
        }
        try {
            chunk.add(new Mailbox.IndexItemEntry(item, item.generateIndexData()));
        } catch (MailItem.TemporaryIndexingException e) {
            ZimbraLog.index.warn("Temporary index failure id=%d", id, e);
            lastFailedTime = System.currentTimeMillis();
            status.addFailed(1);
            continue;
        }
        chunkByteSize += item.getSize();
        if (i == ids.size() || chunkByteSize > MAX_TX_BYTES || chunk.size() >= MAX_TX_ITEMS) {
            // we have a chunk of items and their corresponding index data -- add them to the index
            try {
                ZimbraLog.index.debug("Batch progress %d/%d", i, ids.size());
                if (status.isCancelled()) {
                    throw ServiceException.INTERRUPTED("cancelled");
                }
                try {
                    boolean success = false;
                    try {
                        mailbox.beginTransaction("IndexItemList-Commit", null);
                        for (Mailbox.IndexItemEntry entry : chunk) {
                            mailbox.addIndexItemToCurrentChange(entry);
                        }
                        success = true;
                    } finally {
                        mailbox.endTransaction(success);
                    }
                } catch (ServiceException e) {
                    ZimbraLog.index.warn("Failed to index chunk=%s", chunk, e);
                    status.addFailed(chunk.size());
                }
            } finally {
                chunk.clear();
                chunkByteSize = 0;
            }
        }
    }
}
Also used : UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) ArrayList(java.util.ArrayList) ServiceException(com.zimbra.common.service.ServiceException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) IOException(java.io.IOException) IndexPendingDeleteException(com.zimbra.cs.index.IndexPendingDeleteException) IndexItemEntry(com.zimbra.cs.mailbox.Mailbox.IndexItemEntry) DbMailItem(com.zimbra.cs.db.DbMailItem) IndexItemEntry(com.zimbra.cs.mailbox.Mailbox.IndexItemEntry) ServiceException(com.zimbra.common.service.ServiceException)

Example 13 with UnderlyingData

use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.

the class ACLTest method testPublicAccess.

@Test
public void testPublicAccess() throws Exception {
    Account owner = Provisioning.getInstance().get(Key.AccountBy.name, "owner@zimbra.com");
    owner.setExternalSharingEnabled(false);
    Account guestUser = GuestAccount.ANONYMOUS_ACCT;
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(owner);
    Folder folder = mbox.createFolder(null, "sharedCalender", new Folder.FolderOptions().setDefaultView(MailItem.Type.APPOINTMENT));
    OperationContext octxt = new OperationContext(owner);
    mbox.grantAccess(octxt, folder.getId(), guestUser.getId(), ACL.GRANTEE_PUBLIC, ACL.stringToRights("r"), null);
    UnderlyingData underlyingData = new UnderlyingData();
    underlyingData.setSubject("test subject");
    underlyingData.folderId = folder.getId();
    underlyingData.name = "name";
    underlyingData.type = MailItem.Type.APPOINTMENT.toByte();
    underlyingData.uuid = owner.getUid();
    underlyingData.parentId = folder.getId();
    underlyingData.setBlobDigest("test digest");
    CalendarItem calendarItem = new Appointment(mbox, underlyingData, true);
    Assert.assertTrue(calendarItem.canAccess(ACL.RIGHT_READ, guestUser, false));
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) Test(org.junit.Test)

Example 14 with UnderlyingData

use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.

the class CalendarItemTest method setUp.

/**
 * @throws java.lang.Exception
 */
@Before
public void setUp() throws Exception {
    octxt = PowerMockito.mock(OperationContext.class);
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
    calItem = PowerMockito.mock(CalendarItem.class);
    calItem.mData = new UnderlyingData();
    calItem.mMailbox = mbox;
}
Also used : UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) Before(org.junit.Before)

Example 15 with UnderlyingData

use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.

the class DbTag method verifyTagCounts.

// TODO remove JUnit dependency from non test class
private static void verifyTagCounts(DbConnection conn, Mailbox mbox, Map<Integer, UnderlyingData> tdata) throws ServiceException {
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        String mailboxesMatchAnd = DebugConfig.disableMailboxGroups ? "" : "ti.mailbox_id = mi.mailbox_id AND ";
        stmt = conn.prepareStatement("SELECT ti.tag_id, COUNT(ti.item_id), " + Db.clauseIFNULL("SUM(mi.unread)", "0") + " FROM " + getTaggedItemTableName(mbox, "ti") + " INNER JOIN " + DbMailItem.getMailItemTableName(mbox, "mi") + " ON " + mailboxesMatchAnd + "mi.id = ti.item_id" + " WHERE " + inThisMailboxAnd("ti") + "ti.tag_id > 0 AND " + Db.getInstance().bitAND("mi.flags", String.valueOf(Flag.BITMASK_DELETED)) + " = 0" + " GROUP BY ti.tag_id");
        DbMailItem.setMailboxId(stmt, mbox, 1);
        rs = stmt.executeQuery();
        Map<Integer, UnderlyingData> tcheck = new HashMap<Integer, UnderlyingData>(tdata);
        while (rs.next()) {
            int id = rs.getInt(1), size = rs.getInt(2), unread = rs.getInt(3);
            UnderlyingData data = tcheck.remove(id);
            Assert.assertNotNull("no TAG row for id " + id, data);
            Assert.assertEquals("size for tag " + data.name, size, data.size);
            Assert.assertEquals("unread for tag " + data.name, unread, data.unreadCount);
        }
        for (UnderlyingData data : tcheck.values()) {
            Assert.assertEquals("size for tag " + data.name, 0, data.size);
            Assert.assertEquals("unread for tag " + data.name, 0, data.unreadCount);
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("consistency checking TAGGED_ITEM vs. TAG", e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.closeStatement(stmt);
    }
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement)

Aggregations

UnderlyingData (com.zimbra.cs.mailbox.MailItem.UnderlyingData)30 PreparedStatement (java.sql.PreparedStatement)21 SQLException (java.sql.SQLException)21 ResultSet (java.sql.ResultSet)20 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)18 ArrayList (java.util.ArrayList)13 Mailbox (com.zimbra.cs.mailbox.Mailbox)8 Tag (com.zimbra.cs.mailbox.Tag)4 ServiceException (com.zimbra.common.service.ServiceException)3 MailItem (com.zimbra.cs.mailbox.MailItem)3 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 Color (com.zimbra.common.mailbox.Color)2 BufferStream (com.zimbra.common.util.BufferStream)2 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)2 ZSharedFileInputStream (com.zimbra.common.zmime.ZSharedFileInputStream)2 DbMailItem (com.zimbra.cs.db.DbMailItem)2 Folder (com.zimbra.cs.mailbox.Folder)2 ArchiveInputEntry (com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputEntry)2 ArchiveInputStream (com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream)2