Search in sources :

Example 16 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class ExternalStoreManager method renameTo.

@Override
public MailboxBlob renameTo(StagedBlob src, Mailbox destMbox, int destMsgId, int destRevision) throws IOException, ServiceException {
    // rename is a noop
    ExternalStagedBlob staged = (ExternalStagedBlob) src;
    staged.markInserted();
    MailboxBlob mblob = new ExternalMailboxBlob(destMbox, destMsgId, destRevision, staged.getLocator());
    return mblob.setSize(staged.getSize()).setDigest(staged.getDigest());
}
Also used : MailboxBlob(com.zimbra.cs.store.MailboxBlob)

Example 17 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class ExternalBlobConsistencyChecker method checkExternalBlob.

private void checkExternalBlob(Mailbox mbox, boolean checkSize, BlobInfo blobInfo, ExternalStoreManager sm) throws ServiceException {
    MailboxBlob mblob = sm.getMailboxBlob(mbox, blobInfo.itemId, blobInfo.version, blobInfo.path, false);
    if (mblob == null) {
        results.missingBlobs.put(blobInfo.itemId, blobInfo);
    } else {
        try {
            unexpectedBlobPaths.remove(mblob.getLocator());
            Blob blob = sm.getLocalBlob(mbox, mblob.getLocator(), false);
            if (blob == null) {
                results.missingBlobs.put(blobInfo.itemId, blobInfo);
            } else {
                //blob exists for the locator
                blobInfo.fileModContent = blobInfo.modContent;
                if (reportUsedBlobs) {
                    results.usedBlobs.put(blobInfo.itemId, blobInfo);
                }
                if (checkSize) {
                    blobInfo.fileSize = blob.getFile().length();
                    blobInfo.fileDataSize = getDataSize(blob.getFile(), blobInfo.dbSize);
                    if (blobInfo.dbSize != blobInfo.fileDataSize) {
                        results.incorrectSize.put(blobInfo.itemId, blobInfo);
                    }
                }
            }
        } catch (Exception e) {
            blobInfo.fetchException = e instanceof IOException ? (IOException) e : new IOException("Exception fetching blob", e);
            results.missingBlobs.put(blobInfo.itemId, blobInfo);
        }
    }
}
Also used : Blob(com.zimbra.cs.store.Blob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) IOException(java.io.IOException) IOException(java.io.IOException) ServiceException(com.zimbra.common.service.ServiceException)

Example 18 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class Mailbox method endTransaction.

/**
     * Be very careful when changing code in this method.  The order of almost
     * every line of code is important to ensure correct redo logging and crash
     * recovery.
     *
     * @param success true to commit the transaction, false to rollback
     * @throws ServiceException error
     */
protected void endTransaction(boolean success) throws ServiceException {
    assert !Thread.holdsLock(this) : "Use MailboxLock";
    if (lock.isUnlocked()) {
        ZimbraLog.mailbox.warn("transaction canceled because of lock failure");
        assert (!success);
        return;
    }
    // blob and index to delete
    PendingDelete deletes = null;
    // blob to delete for failure cases
    List<Object> rollbackDeletes = null;
    try {
        if (!currentChange().isActive()) {
            // would like to throw here, but it might cover another
            // exception...
            ZimbraLog.mailbox.warn("cannot end a transaction when not inside a transaction", new Exception());
            return;
        }
        if (!currentChange().endChange()) {
            return;
        }
        ServiceException exception = null;
        if (success) {
            List<IndexItemEntry> indexItems = currentChange().indexItems;
            if (!indexItems.isEmpty()) {
                assert (currentChange().writeChange);
                //TODO: See bug 15072 - we need to clear mCurrentChange.indexItems (it is stored in a temporary) here,
                // just in case item.reindex() recurses into a new transaction...
                currentChange().indexItems = new ArrayList<IndexItemEntry>();
                index.add(indexItems);
            }
            // update mailbox size, folder unread/message counts
            try {
                snapshotCounts();
            } catch (ServiceException e) {
                exception = e;
                success = false;
            }
        }
        DbConnection conn = currentChange().conn;
        // transaction, so no redo cleanup is necessary.
        if (!success) {
            DbPool.quietRollback(conn);
            rollbackDeletes = rollbackCache(currentChange());
            if (exception != null) {
                throw exception;
            }
            return;
        }
        RedoableOp redoRecorder = currentChange().recorder;
        boolean needRedo = needRedo(currentChange().octxt, redoRecorder);
        // Log the change redo record for main transaction.
        if (redoRecorder != null && needRedo) {
            redoRecorder.log(true);
        }
        boolean dbCommitSuccess = false;
        try {
            // Commit the main transaction in database.
            if (conn != null) {
                try {
                    conn.commit();
                } catch (Throwable t) {
                    // Any exception during database commit is a disaster
                    // because we don't know if the change is committed or
                    // not.  Force the server to abort.  Next restart will
                    // redo the operation to ensure the change is made and
                    // committed.  (bug 2121)
                    Zimbra.halt("Unable to commit database transaction.  Forcing server to abort.", t);
                }
            }
            dbCommitSuccess = true;
        } finally {
            if (!dbCommitSuccess) {
                // recovery will try to redo the operation.
                if (needRedo) {
                    if (redoRecorder != null) {
                        redoRecorder.abort();
                    }
                }
                DbPool.quietRollback(conn);
                rollbackDeletes = rollbackCache(currentChange());
                return;
            }
        }
        if (needRedo) {
            // case would result in a redo error, and the second case would index the wrong value.
            if (redoRecorder != null) {
                if (currentChange().dirty != null && !currentChange().dirty.changedTypes.isEmpty()) {
                    // if an "all accounts" waitset is active, and this change has an appropriate type,
                    // then we'll need to set a commit-callback
                    AllAccountsRedoCommitCallback cb = AllAccountsRedoCommitCallback.getRedoCallbackIfNecessary(getAccountId(), currentChange().dirty.changedTypes);
                    if (cb != null) {
                        redoRecorder.setCommitCallback(cb);
                    }
                }
                redoRecorder.commit();
            }
        }
        boolean changeMade = currentChange().changeId != MailboxChange.NO_CHANGE;
        // keep a reference for cleanup
        deletes = currentChange().deletes;
        // deletes outside the lock
        // We are finally done with database and redo commits. Cache update
        // comes last.
        commitCache(currentChange());
        // down in its call stack.
        if (changeMade) {
            index.maybeIndexDeferredItems();
        }
    } finally {
        lock.release();
        // entail a blocking network operation
        if (deletes != null) {
            if (!deletes.indexIds.isEmpty()) {
                // delete any index entries associated with items deleted from db
                index.delete(deletes.indexIds);
            }
            if (deletes.blobs != null) {
                // delete any blobs associated with items deleted from db/index
                StoreManager sm = StoreManager.getInstance();
                for (MailboxBlob blob : deletes.blobs) {
                    sm.quietDelete(blob);
                }
            }
        }
        if (rollbackDeletes != null) {
            StoreManager sm = StoreManager.getInstance();
            for (Object obj : rollbackDeletes) {
                if (obj instanceof MailboxBlob) {
                    sm.quietDelete((MailboxBlob) obj);
                } else if (obj instanceof Blob) {
                    sm.quietDelete((Blob) obj);
                }
            }
        }
    }
}
Also used : StoreIncomingBlob(com.zimbra.cs.redolog.op.StoreIncomingBlob) StagedBlob(com.zimbra.cs.store.StagedBlob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) Blob(com.zimbra.cs.store.Blob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) AllAccountsRedoCommitCallback(com.zimbra.cs.session.AllAccountsRedoCommitCallback) AccountServiceException(com.zimbra.cs.account.AccountServiceException) IOException(java.io.IOException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) MessageChannelException(com.zimbra.cs.iochannel.MessageChannelException) ServiceException(com.zimbra.common.service.ServiceException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) StoreManager(com.zimbra.cs.store.StoreManager) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) RedoableOp(com.zimbra.cs.redolog.op.RedoableOp) PendingDelete(com.zimbra.cs.mailbox.MailItem.PendingDelete)

Example 19 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class WikiDigestFixup method getWikiDigests.

private static List<WikiDigest> getWikiDigests(int mboxId) throws IOException, ServiceException {
    Mailbox mbox = null;
    try {
        mbox = MailboxManager.getInstance().getMailboxById(mboxId);
    } catch (ServiceException e) {
        String code = e.getCode();
        if (AccountServiceException.NO_SUCH_ACCOUNT.equals(code) || ServiceException.WRONG_HOST.equals(code))
            return null;
        else
            throw e;
    }
    OperationContext octxt = new OperationContext(mbox);
    List<MailItem> items = new ArrayList<MailItem>();
    List<MailItem> wikis = mbox.getItemList(octxt, MailItem.Type.WIKI);
    if (wikis != null && wikis.size() > 0)
        items.addAll(wikis);
    List<MailItem> documents = mbox.getItemList(octxt, MailItem.Type.DOCUMENT);
    if (documents != null && documents.size() > 0)
        items.addAll(documents);
    int len = items.size();
    List<WikiDigest> list = new ArrayList<WikiDigest>(len);
    if (len > 0) {
        for (MailItem item : items) {
            // didn't support >2GB wiki items when the bug was occurring
            if (item.getSize() > Integer.MAX_VALUE)
                continue;
            int id = item.getId();
            MailboxBlob blob = sStore.getMailboxBlob(item);
            InputStream is = null;
            try {
                is = sStore.getContent(blob);
                byte[] data = ByteUtil.getContent(is, (int) item.getSize());
                String digest = ByteUtil.getSHA1Digest(data, true);
                String currentDigest = item.getDigest();
                if (!digest.equals(currentDigest)) {
                    System.out.println("Found id " + id + ", current digest = \"" + currentDigest + "\"");
                    WikiDigest wd = new WikiDigest(mboxId, id, digest);
                    list.add(wd);
                } else {
                    System.out.println("Found id " + id + " but skipping because digest is correct.");
                }
            } finally {
                ByteUtil.closeStream(is);
            }
        }
    }
    return list;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) MailboxBlob(com.zimbra.cs.store.MailboxBlob) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException)

Example 20 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class TestStoreManager method testStore.

@Test
public void testStore() throws Exception {
    ParsedMessage pm = getMessage();
    byte[] mimeBytes = TestUtil.readInputStream(pm.getRawInputStream());
    Mailbox mbox = TestUtil.getMailbox(USER_NAME);
    StoreManager sm = StoreManager.getInstance();
    Blob blob = sm.storeIncoming(pm.getRawInputStream());
    Assert.assertEquals("blob size = message size", pm.getRawData().length, blob.getRawSize());
    Assert.assertTrue("blob content = mime content", TestUtil.bytesEqual(mimeBytes, blob.getInputStream()));
    StagedBlob staged = sm.stage(blob, mbox);
    Assert.assertEquals("staged size = blob size", blob.getRawSize(), staged.getSize());
    MailboxBlob mblob = sm.link(staged, mbox, 0, 0);
    Assert.assertEquals("link size = staged size", staged.getSize(), mblob.getSize());
    Assert.assertTrue("link content = mime content", TestUtil.bytesEqual(mimeBytes, mblob.getLocalBlob().getInputStream()));
    mblob = sm.getMailboxBlob(mbox, 0, 0, staged.getLocator());
    Assert.assertEquals("mblob size = staged size", staged.getSize(), mblob.getSize());
    Assert.assertTrue("mailboxblob content = mime content", TestUtil.bytesEqual(mimeBytes, mblob.getLocalBlob().getInputStream()));
}
Also used : Blob(com.zimbra.cs.store.Blob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) StagedBlob(com.zimbra.cs.store.StagedBlob) StagedBlob(com.zimbra.cs.store.StagedBlob) Mailbox(com.zimbra.cs.mailbox.Mailbox) MailboxBlob(com.zimbra.cs.store.MailboxBlob) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) StoreManager(com.zimbra.cs.store.StoreManager) Test(org.junit.Test)

Aggregations

MailboxBlob (com.zimbra.cs.store.MailboxBlob)27 StoreManager (com.zimbra.cs.store.StoreManager)16 StagedBlob (com.zimbra.cs.store.StagedBlob)14 Mailbox (com.zimbra.cs.mailbox.Mailbox)12 Blob (com.zimbra.cs.store.Blob)12 IOException (java.io.IOException)11 ServiceException (com.zimbra.common.service.ServiceException)8 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)7 Test (org.junit.Test)7 ArrayList (java.util.ArrayList)6 InputStream (java.io.InputStream)5 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)4 CreateMountpoint (com.zimbra.cs.redolog.op.CreateMountpoint)4 AccountServiceException (com.zimbra.cs.account.AccountServiceException)3 DbMailItem (com.zimbra.cs.db.DbMailItem)3 DbTag (com.zimbra.cs.db.DbTag)3 IndexDocument (com.zimbra.cs.index.IndexDocument)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Message (com.zimbra.cs.mailbox.Message)3 NormalizedTags (com.zimbra.cs.mailbox.Tag.NormalizedTags)3