Search in sources :

Example 1 with BlobInfo

use of com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo in project zm-mailbox by Zimbra.

the class DbBlobConsistency method getBlobInfo.

/**
 * Returns blob info for items in the specified id range.
 */
public static Collection<BlobInfo> getBlobInfo(DbConnection conn, Mailbox mbox, int minId, int maxId, short volumeId) throws ServiceException {
    PreparedStatement stmt = null;
    ResultSet rs = null;
    List<BlobInfo> blobs = new ArrayList<BlobInfo>();
    try {
        stmt = conn.prepareStatement("SELECT id, mod_content, 0, size " + "FROM " + DbMailItem.getMailItemTableName(mbox, false) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + " id BETWEEN " + minId + " AND " + maxId + " AND blob_digest IS NOT NULL " + "AND locator = " + volumeId + " UNION " + "SELECT id, mod_content, 0, size " + "FROM " + DbMailItem.getMailItemTableName(mbox, true) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + " id BETWEEN " + minId + " AND " + maxId + " AND blob_digest IS NOT NULL " + "AND locator = " + volumeId + " UNION " + "SELECT item_id, mod_content, version, size " + "FROM " + DbMailItem.getRevisionTableName(mbox, false) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + " item_id BETWEEN " + minId + " AND " + maxId + " AND blob_digest IS NOT NULL " + "AND locator = " + volumeId + " UNION " + "SELECT item_id, mod_content, version, size " + "FROM " + DbMailItem.getRevisionTableName(mbox, true) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + " item_id BETWEEN " + minId + " AND " + maxId + " AND blob_digest IS NOT NULL " + "AND locator = " + volumeId);
        if (!DebugConfig.disableMailboxGroups) {
            stmt.setInt(1, mbox.getId());
            stmt.setInt(2, mbox.getId());
            stmt.setInt(3, mbox.getId());
            stmt.setInt(4, mbox.getId());
        }
        Db.getInstance().enableStreaming(stmt);
        rs = stmt.executeQuery();
        while (rs.next()) {
            BlobInfo info = new BlobInfo();
            info.itemId = rs.getInt(1);
            info.modContent = rs.getInt(2);
            info.version = rs.getInt(3);
            info.dbSize = rs.getLong(4);
            info.volumeId = volumeId;
            info.path = FileBlobStore.getBlobPath(mbox, info.itemId, info.modContent, volumeId);
            blobs.add(info);
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("getting items with blobs for mailbox " + mbox.getId(), e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.quietCloseStatement(stmt);
    }
    return blobs;
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) BlobInfo(com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo)

Example 2 with BlobInfo

use of com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo in project zm-mailbox by Zimbra.

the class DbBlobConsistency method getExternalBlobInfo.

private static Collection<BlobInfo> getExternalBlobInfo(DbConnection conn, Mailbox mbox, String query) throws ServiceException {
    PreparedStatement stmt = null;
    ResultSet rs = null;
    List<BlobInfo> blobs = new ArrayList<BlobInfo>();
    try {
        stmt = conn.prepareStatement(query);
        if (!DebugConfig.disableMailboxGroups) {
            stmt.setInt(1, mbox.getId());
        }
        Db.getInstance().enableStreaming(stmt);
        rs = stmt.executeQuery();
        while (rs.next()) {
            BlobInfo info = new BlobInfo();
            info.itemId = rs.getInt(1);
            info.modContent = rs.getInt(2);
            info.version = rs.getInt(3);
            info.dbSize = rs.getLong(4);
            info.path = rs.getString(5);
            info.external = true;
            blobs.add(info);
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("getting items with blobs for mailbox " + mbox.getId(), e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.quietCloseStatement(stmt);
    }
    return blobs;
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) BlobInfo(com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo)

Example 3 with BlobInfo

use of com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo in project zm-mailbox by Zimbra.

the class AbstractBlobConsistencyCheckTest method unexpectedBlobs.

@Test
public void unexpectedBlobs() throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
    String path = createUnexpectedBlob(0);
    BlobConsistencyChecker checker = getChecker();
    Results results = checker.check(getVolumeIds(), mbox.getId(), true, false);
    Assert.assertEquals(0, results.missingBlobs.size());
    Assert.assertEquals(1, results.unexpectedBlobs.size());
    BlobInfo info = results.unexpectedBlobs.values().iterator().next();
    Assert.assertEquals(path, info.path);
    Assert.assertEquals(0, results.usedBlobs.size());
    Assert.assertEquals(0, results.incorrectSize.size());
    Assert.assertEquals(0, results.incorrectModContent.size());
    deleteAllBlobs();
    DeliveryOptions dopt = new DeliveryOptions().setFolderId(Mailbox.ID_FOLDER_INBOX);
    mbox.addMessage(null, new ParsedMessage("From: test1-1@sub1.zimbra.com".getBytes(), false), dopt, null);
    int msgs = 10;
    for (int i = 0; i < msgs; i++) {
        createUnexpectedBlob(i);
    }
    results = checker.check(getVolumeIds(), mbox.getId(), true, false);
    Assert.assertEquals(0, results.missingBlobs.size());
    Assert.assertEquals(msgs, results.unexpectedBlobs.size());
    Assert.assertEquals(0, results.usedBlobs.size());
    Assert.assertEquals(0, results.incorrectSize.size());
    Assert.assertEquals(0, results.incorrectModContent.size());
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) Results(com.zimbra.cs.store.file.BlobConsistencyChecker.Results) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) BlobConsistencyChecker(com.zimbra.cs.store.file.BlobConsistencyChecker) BlobInfo(com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo) DeliveryOptions(com.zimbra.cs.mailbox.DeliveryOptions) Test(org.junit.Test)

Example 4 with BlobInfo

use of com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo in project zm-mailbox by Zimbra.

the class AbstractBlobConsistencyCheckTest method wrongSize.

@Test
public void wrongSize() throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
    DeliveryOptions dopt = new DeliveryOptions().setFolderId(Mailbox.ID_FOLDER_INBOX);
    Message msg = mbox.addMessage(null, new ParsedMessage("From: test1-1@sub1.zimbra.com".getBytes(), false), dopt, null);
    MailboxBlob blob = msg.getBlob();
    String text = "some garbage";
    appendText(blob, text);
    BlobConsistencyChecker checker = getChecker();
    Results results = checker.check(getVolumeIds(), mbox.getId(), true, false);
    Assert.assertEquals(0, results.missingBlobs.size());
    Assert.assertEquals(0, results.unexpectedBlobs.size());
    Assert.assertEquals(0, results.usedBlobs.size());
    Assert.assertEquals(1, results.incorrectSize.size());
    BlobInfo info = results.incorrectSize.values().iterator().next();
    Assert.assertEquals(blob.size + text.length(), (long) info.fileDataSize);
    Assert.assertEquals(0, results.incorrectModContent.size());
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) Message(com.zimbra.cs.mailbox.Message) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Results(com.zimbra.cs.store.file.BlobConsistencyChecker.Results) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) BlobConsistencyChecker(com.zimbra.cs.store.file.BlobConsistencyChecker) BlobInfo(com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo) DeliveryOptions(com.zimbra.cs.mailbox.DeliveryOptions) Test(org.junit.Test)

Example 5 with BlobInfo

use of com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo in project zm-mailbox by Zimbra.

the class BlobConsistencyUtil method checkMailbox.

private void checkMailbox(int mboxId, SoapProvisioning prov) throws ServiceException {
    XMLElement request = new XMLElement(AdminConstants.CHECK_BLOB_CONSISTENCY_REQUEST);
    for (short volumeId : volumeIds) {
        request.addElement(AdminConstants.E_VOLUME).addAttribute(AdminConstants.A_ID, volumeId);
    }
    request.addElement(AdminConstants.E_MAILBOX).addAttribute(AdminConstants.A_ID, mboxId);
    request.addAttribute(AdminConstants.A_CHECK_SIZE, !skipSizeCheck);
    request.addAttribute(AdminConstants.A_REPORT_USED_BLOBS, outputUsedBlobs || usedBlobWriter != null);
    if (prov.isExpired()) {
        prov.soapZimbraAdminAuthenticate();
    }
    Element response = prov.invoke(request);
    for (Element mboxEl : response.listElements(AdminConstants.E_MAILBOX)) {
        // Print results.
        BlobConsistencyChecker.Results results = new BlobConsistencyChecker.Results(mboxEl);
        for (BlobInfo blob : results.missingBlobs.values()) {
            System.out.format("Mailbox %d, item %d, rev %d, %s: blob not found.\n", results.mboxId, blob.itemId, blob.modContent, locatorText(blob));
        }
        for (BlobInfo blob : results.incorrectSize.values()) {
            System.out.format("Mailbox %d, item %d, rev %d, %s: incorrect data size.  Expected %d, was %d.  File size is %d.\n", results.mboxId, blob.itemId, blob.modContent, locatorText(blob), blob.dbSize, blob.fileDataSize, blob.fileSize);
        }
        for (BlobInfo blob : results.unexpectedBlobs.values()) {
            System.out.format("Mailbox %d, %s: unexpected blob.  File size is %d.\n", results.mboxId, locatorText(blob), blob.fileSize);
            if (unexpectedBlobWriter != null) {
                unexpectedBlobWriter.println(blob.path);
            }
        }
        for (BlobInfo blob : results.incorrectModContent.values()) {
            System.out.format("Mailbox %d, item %d, rev %d, %s: file has incorrect revision.\n", results.mboxId, blob.itemId, blob.modContent, locatorText(blob));
        }
        for (BlobInfo blob : results.usedBlobs.values()) {
            if (outputUsedBlobs) {
                System.out.format("Used blob: Mailbox %d, item %d, rev %d, %s.\n", results.mboxId, blob.itemId, blob.version, locatorText(blob));
            }
            if (usedBlobWriter != null) {
                usedBlobWriter.println(blob.path);
            }
        }
        // Fix inconsistencies.
        if (missingBlobDeleteItem && results.missingBlobs.size() > 0) {
            exportAndDelete(prov, results);
        }
        if (incorrectRevisionRenameFile) {
            for (BlobInfo blob : results.incorrectModContent.values()) {
                File file = new File(blob.path);
                File dir = file.getParentFile();
                if (dir != null) {
                    File newFile = new File(dir, FileBlobStore.getFilename(blob.itemId, blob.modContent));
                    System.out.format("Renaming %s to %s.\n", file.getAbsolutePath(), newFile.getAbsolutePath());
                    if (!file.renameTo(newFile)) {
                        System.err.format("Unable to rename %s to %s.\n", file.getAbsolutePath(), newFile.getAbsolutePath());
                    }
                } else {
                    System.err.format("Could not determine parent directory of %s.\n", file.getAbsolutePath());
                }
            }
        }
    }
}
Also used : XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) BlobInfo(com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo) XMLElement(com.zimbra.common.soap.Element.XMLElement) File(java.io.File)

Aggregations

BlobInfo (com.zimbra.cs.store.file.BlobConsistencyChecker.BlobInfo)6 DeliveryOptions (com.zimbra.cs.mailbox.DeliveryOptions)2 Mailbox (com.zimbra.cs.mailbox.Mailbox)2 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)2 BlobConsistencyChecker (com.zimbra.cs.store.file.BlobConsistencyChecker)2 Results (com.zimbra.cs.store.file.BlobConsistencyChecker.Results)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 ArrayList (java.util.ArrayList)2 Test (org.junit.Test)2 Element (com.zimbra.common.soap.Element)1 XMLElement (com.zimbra.common.soap.Element.XMLElement)1 Message (com.zimbra.cs.mailbox.Message)1 ExportAndDeleteItemsRequest (com.zimbra.soap.admin.message.ExportAndDeleteItemsRequest)1 ExportAndDeleteMailboxSpec (com.zimbra.soap.admin.type.ExportAndDeleteMailboxSpec)1 File (java.io.File)1