Search in sources :

Example 16 with StoreManager

use of com.zimbra.cs.store.StoreManager 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)

Example 17 with StoreManager

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

the class Mailbox method saveDraft.

/**
     * Saves draft.
     *
     * @param autoSendTime time at which the draft needs to be auto-sent. Note that this method does not schedule
     *                     the task for auto-sending the draft. It just persists this time for tracking purposes.
     * @see com.zimbra.cs.service.mail.SaveDraft#handle(com.zimbra.common.soap.Element, java.util.Map)
     */
public Message saveDraft(OperationContext octxt, ParsedMessage pm, int id, String origId, String replyType, String identityId, String accountId, long autoSendTime) throws IOException, ServiceException {
    Message.DraftInfo dinfo = null;
    if ((replyType != null && origId != null) || identityId != null || accountId != null || autoSendTime != 0) {
        dinfo = new Message.DraftInfo(replyType, origId, identityId, accountId, autoSendTime);
    }
    if (id == ID_AUTO_INCREMENT) {
        // special-case saving a new draft
        return addMessage(octxt, pm, ID_FOLDER_DRAFTS, true, Flag.BITMASK_DRAFT | Flag.BITMASK_FROM_ME, null, ID_AUTO_INCREMENT, ":API:", dinfo, null, null);
    }
    // write the draft content directly to the mailbox's blob staging area
    StoreManager sm = StoreManager.getInstance();
    StagedBlob staged;
    InputStream is = pm.getRawInputStream();
    try {
        staged = sm.stage(is, this);
    } finally {
        ByteUtil.closeStream(is);
    }
    String digest = staged.getDigest();
    int size = (int) staged.getSize();
    SaveDraft redoRecorder = new SaveDraft(mId, id, digest, size);
    InputStream redoStream = null;
    boolean success = false;
    try {
        beginTransaction("saveDraft", octxt, redoRecorder);
        SaveDraft redoPlayer = (SaveDraft) currentChange().getRedoPlayer();
        Message msg = getMessageById(id);
        if (!msg.isTagged(Flag.FlagInfo.DRAFT)) {
            throw MailServiceException.IMMUTABLE_OBJECT(id);
        }
        if (!checkItemChangeID(msg)) {
            throw MailServiceException.MODIFY_CONFLICT();
        }
        // content changed, so we're obliged to change the IMAP uid
        int imapID = getNextItemId(redoPlayer == null ? ID_AUTO_INCREMENT : redoPlayer.getImapId());
        redoRecorder.setImapId(imapID);
        redoRecorder.setMessageBodyInfo(new ParsedMessageDataSource(pm), size);
        msg.setDraftAutoSendTime(autoSendTime);
        if (dinfo != null) {
            if (replyType != null) {
                msg.setDraftReplyType(replyType);
            }
            if (origId != null) {
                msg.setDraftOrigId(origId);
            }
            if (identityId != null) {
                msg.setDraftIdentityId(identityId);
            }
            if (accountId != null) {
                msg.setDraftAccountId(accountId);
            }
            if (autoSendTime != 0) {
                msg.setDraftAutoSendTime(autoSendTime);
            }
        }
        // update the content and increment the revision number
        msg.setContent(staged, pm);
        index.add(msg);
        success = true;
        try {
            Notification.getInstance().interceptIfNecessary(this, pm.getMimeMessage(), "save draft", msg.getFolder());
        } catch (ServiceException e) {
            ZimbraLog.mailbox.error("Unable to send lawful intercept message.", e);
        }
        return msg;
    } finally {
        endTransaction(success);
        ByteUtil.closeStream(redoStream);
        sm.quietDelete(staged);
    }
}
Also used : ParsedMessageDataSource(com.zimbra.cs.mime.ParsedMessageDataSource) StagedBlob(com.zimbra.cs.store.StagedBlob) ImapMessage(com.zimbra.cs.imap.ImapMessage) Pop3Message(com.zimbra.cs.pop3.Pop3Message) MimeMessage(javax.mail.internet.MimeMessage) CreateMessage(com.zimbra.cs.redolog.op.CreateMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) Rfc822ValidationInputStream(com.zimbra.common.mime.Rfc822ValidationInputStream) CopyInputStream(com.zimbra.common.util.CopyInputStream) InputStream(java.io.InputStream) SaveDraft(com.zimbra.cs.redolog.op.SaveDraft) RefreshMountpoint(com.zimbra.cs.redolog.op.RefreshMountpoint) TargetConstraint(com.zimbra.cs.mailbox.MailItem.TargetConstraint) CreateMountpoint(com.zimbra.cs.redolog.op.CreateMountpoint) StoreManager(com.zimbra.cs.store.StoreManager)

Example 18 with StoreManager

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

the class Mailbox method addDocumentRevision.

public Document addDocumentRevision(OperationContext octxt, int docId, ParsedDocument pd) throws IOException, ServiceException {
    StoreManager sm = StoreManager.getInstance();
    StagedBlob staged = sm.stage(pd.getBlob(), this);
    AddDocumentRevision redoRecorder = new AddDocumentRevision(mId, pd.getDigest(), pd.getSize(), 0);
    boolean success = false;
    try {
        beginTransaction("addDocumentRevision", octxt, redoRecorder);
        Document doc = getDocumentById(docId);
        redoRecorder.setDocument(pd);
        redoRecorder.setDocId(docId);
        redoRecorder.setItemType(doc.getType());
        // TODO: simplify the redoRecorder by not subclassing from CreateMessage
        // Get the redolog data from the mailbox blob.  This is less than ideal in the
        // HTTP store case because it will result in network access, and possibly an
        // extra write to local disk.  If this becomes a problem, we should update the
        // ParsedDocument constructor to take a DataSource instead of an InputStream.
        MailboxBlob mailboxBlob = doc.setContent(staged, pd);
        redoRecorder.setMessageBodyInfo(new MailboxBlobDataSource(mailboxBlob), mailboxBlob.getSize());
        index.add(doc);
        success = true;
        return doc;
    } catch (IOException ioe) {
        throw ServiceException.FAILURE("error writing document blob", ioe);
    } finally {
        endTransaction(success);
        sm.quietDelete(staged);
    }
}
Also used : StagedBlob(com.zimbra.cs.store.StagedBlob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) MailboxBlobDataSource(com.zimbra.cs.store.MailboxBlobDataSource) AddDocumentRevision(com.zimbra.cs.redolog.op.AddDocumentRevision) IOException(java.io.IOException) ParsedDocument(com.zimbra.cs.mime.ParsedDocument) IndexDocument(com.zimbra.cs.index.IndexDocument) SaveDocument(com.zimbra.cs.redolog.op.SaveDocument) StoreManager(com.zimbra.cs.store.StoreManager)

Example 19 with StoreManager

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

the class AbstractExternalStoreManagerTest method testUncachedFile.

@Test
public void testUncachedFile() throws Exception {
    ParsedMessage pm = ThreaderTest.getRootMessage();
    byte[] mimeBytes = TestUtil.readInputStream(pm.getRawInputStream());
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
    StoreManager sm = StoreManager.getInstance();
    Blob blob = sm.storeIncoming(pm.getRawInputStream());
    StagedBlob staged = sm.stage(blob, mbox);
    MailboxBlob mblob = sm.link(staged, mbox, 0, 0);
    mblob = sm.getMailboxBlob(mbox, 0, 0, staged.getLocator());
    Blob localBlob = mblob.getLocalBlob();
    InputStream stream = sm.getContent(localBlob);
    Assert.assertTrue("input stream external", stream instanceof BlobInputStream);
    if (sm instanceof ExternalStoreManager) {
        ((ExternalStoreManager) sm).clearCache();
    }
    blob.getFile().delete();
    Assert.assertFalse(blob.getFile().exists());
    //now get it again. this would bomb if it only looked in cache
    stream = sm.getContent(mblob.getLocalBlob());
    Assert.assertTrue("input stream external", stream instanceof ExternalBlobInputStream);
    ExternalBlobInputStream extStream = (ExternalBlobInputStream) stream;
    File file = extStream.getRootFile();
    Assert.assertTrue(file.exists());
    Assert.assertTrue("stream content = mime content", TestUtil.bytesEqual(mimeBytes, stream));
}
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) BlobInputStream(com.zimbra.cs.store.BlobInputStream) InputStream(java.io.InputStream) BlobInputStream(com.zimbra.cs.store.BlobInputStream) File(java.io.File) StoreManager(com.zimbra.cs.store.StoreManager) Test(org.junit.Test) AbstractStoreManagerTest(com.zimbra.cs.store.AbstractStoreManagerTest) ThreaderTest(com.zimbra.cs.mailbox.ThreaderTest)

Example 20 with StoreManager

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

the class DbMailItem method accumulateLeafNodes.

/**
     * Accumulates <tt>PendingDelete</tt> info for the given <tt>ResultSet</tt>.
     * @return a <tt>List</tt> of all versioned items, to be used in a subsequent call to
     * {@link DbMailItem#accumulateLeafRevisions}, or an empty list.
     */
static List<Integer> accumulateLeafNodes(PendingDelete info, Mailbox mbox, ResultSet rs) throws SQLException, ServiceException {
    boolean dumpsterEnabled = mbox.dumpsterEnabled();
    boolean useDumpsterForSpam = mbox.useDumpsterForSpam();
    StoreManager sm = StoreManager.getInstance();
    List<Integer> versioned = new ArrayList<Integer>();
    while (rs.next()) {
        // first check to make sure we don't have a modify conflict
        int revision = rs.getInt(LEAF_CI_MOD_CONTENT);
        int modMetadata = rs.getInt(LEAF_CI_MOD_METADATA);
        if (!mbox.checkItemChangeID(modMetadata, revision)) {
            info.incomplete = true;
            continue;
        }
        int id = rs.getInt(LEAF_CI_ID);
        String uuid = rs.getString(LEAF_CI_UUID);
        long size = rs.getLong(LEAF_CI_SIZE);
        MailItem.Type type = MailItem.Type.of(rs.getByte(LEAF_CI_TYPE));
        Integer itemId = Integer.valueOf(id);
        info.itemIds.add(type, itemId, uuid);
        info.size += size;
        if (rs.getBoolean(LEAF_CI_IS_UNREAD)) {
            info.unreadIds.add(itemId);
        }
        boolean isMessage = false;
        switch(type) {
            case CONTACT:
                info.contacts++;
                break;
            case CHAT:
            case MESSAGE:
                isMessage = true;
                break;
        }
        // record deleted virtual conversations and modified-or-deleted real conversations
        if (isMessage) {
            int parentId = rs.getInt(LEAF_CI_PARENT_ID);
            if (rs.wasNull() || parentId <= 0) {
                // conversations don't have UUIDs, so this is safe
                info.itemIds.add(MailItem.Type.VIRTUAL_CONVERSATION, -id, null);
            } else {
                info.modifiedIds.add(parentId);
            }
        }
        int flags = rs.getInt(LEAF_CI_FLAGS);
        if ((flags & Flag.BITMASK_VERSIONED) != 0) {
            versioned.add(id);
        }
        Integer folderId = rs.getInt(LEAF_CI_FOLDER_ID);
        boolean isDeleted = (flags & Flag.BITMASK_DELETED) != 0;
        LocationCount fcount = info.folderCounts.get(folderId);
        if (fcount == null) {
            info.folderCounts.put(folderId, new LocationCount(1, isDeleted ? 1 : 0, size));
        } else {
            fcount.increment(1, isDeleted ? 1 : 0, size);
        }
        String[] tags = DbTag.deserializeTags(rs.getString(LEAF_CI_TAGS));
        if (tags != null) {
            for (String tag : tags) {
                LocationCount tcount = info.tagCounts.get(tag);
                if (tcount == null) {
                    info.tagCounts.put(tag, new LocationCount(1, isDeleted ? 1 : 0, size));
                } else {
                    tcount.increment(1, isDeleted ? 1 : 0, size);
                }
            }
        }
        int fid = folderId != null ? folderId.intValue() : -1;
        if (!dumpsterEnabled || fid == Mailbox.ID_FOLDER_DRAFTS || (fid == Mailbox.ID_FOLDER_SPAM && !useDumpsterForSpam)) {
            String blobDigest = rs.getString(LEAF_CI_BLOB_DIGEST);
            if (blobDigest != null) {
                info.blobDigests.add(blobDigest);
                String locator = rs.getString(LEAF_CI_LOCATOR);
                try {
                    MailboxBlob mblob = sm.getMailboxBlob(mbox, id, revision, locator, false);
                    if (mblob == null) {
                        ZimbraLog.mailbox.warn("missing blob for id: %d, change: %d", id, revision);
                    } else {
                        info.blobs.add(mblob);
                    }
                } catch (Exception e1) {
                    ZimbraLog.mailbox.warn("Exception while getting mailbox blob", e1);
                }
            }
            int indexId = rs.getInt(LEAF_CI_INDEX_ID);
            boolean indexed = !rs.wasNull();
            if (indexed) {
                if (info.sharedIndex == null) {
                    info.sharedIndex = new HashSet<Integer>();
                }
                boolean shared = (flags & Flag.BITMASK_COPIED) != 0;
                if (shared) {
                    info.sharedIndex.add(indexId);
                } else {
                    info.indexIds.add(indexId > MailItem.IndexStatus.STALE.id() ? indexId : id);
                }
            }
        }
    }
    return versioned;
}
Also used : MailboxBlob(com.zimbra.cs.store.MailboxBlob) ArrayList(java.util.ArrayList) EncoderException(org.apache.commons.codec.EncoderException) DecoderException(org.apache.commons.codec.DecoderException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ServiceException(com.zimbra.common.service.ServiceException) SQLException(java.sql.SQLException) IOException(java.io.IOException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) StoreManager(com.zimbra.cs.store.StoreManager) MailItem(com.zimbra.cs.mailbox.MailItem)

Aggregations

StoreManager (com.zimbra.cs.store.StoreManager)29 MailboxBlob (com.zimbra.cs.store.MailboxBlob)17 StagedBlob (com.zimbra.cs.store.StagedBlob)16 IOException (java.io.IOException)14 InputStream (java.io.InputStream)11 Blob (com.zimbra.cs.store.Blob)10 Mailbox (com.zimbra.cs.mailbox.Mailbox)9 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)9 Rfc822ValidationInputStream (com.zimbra.common.mime.Rfc822ValidationInputStream)6 ServiceException (com.zimbra.common.service.ServiceException)6 CopyInputStream (com.zimbra.common.util.CopyInputStream)6 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)5 CreateMountpoint (com.zimbra.cs.redolog.op.CreateMountpoint)5 Test (org.junit.Test)5 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)4 RefreshMountpoint (com.zimbra.cs.redolog.op.RefreshMountpoint)4 ArrayList (java.util.ArrayList)4 AccountServiceException (com.zimbra.cs.account.AccountServiceException)3 DbMailItem (com.zimbra.cs.db.DbMailItem)3 ParsedMessageDataSource (com.zimbra.cs.mime.ParsedMessageDataSource)3