Search in sources :

Example 26 with StoreManager

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

the class MailItem method icopy.

/** Copies the item to the target folder.  Persists the new item to the
     *  database and the in-memory cache.  Copies to the same folder as the
     *  original item will succeed, but it is strongly suggested that
     *  {@link #copy(Folder, int, int, short)} be used in that case.<p>
     *
     *  Immutable copied items (both the original and the target) share the
     *  same entry in the index and get the {@link Flag#BITMASK_COPIED} flag to
     *  facilitate garbage collection of index entries.  (Mutable copied items
     *  are indexed separately.)  They do not share the same blob on disk,
     *  although the system will use a hard link where possible.  Copied
     *  {@link Message}s are remain in the same {@link Conversation}, but the
     *  <b>original</b> Message is placed in a new {@link VirtualConversation}
     *  rather than being grouped with the copied Message.
     *
     * @param target  The folder to copy the item to.
     * @param copyId  The item id for the newly-created copy.
     * @perms {@link ACL#RIGHT_INSERT} on the target folder,
     *        {@link ACL#RIGHT_READ} on the original item
     * @throws ServiceException  The following error codes are possible:<ul>
     *    <li><tt>mail.CANNOT_COPY</tt> - if the item is not copyable
     *    <li><tt>mail.CANNOT_CONTAIN</tt> - if the target folder can't hold
     *        the copy of the item
     *    <li><tt>service.FAILURE</tt> - if there's a database failure
     *    <li><tt>service.PERM_DENIED</tt> - if you don't have sufficient
     *        permissions</ul> */
MailItem icopy(Folder target, int copyId, String copyUuid) throws IOException, ServiceException {
    if (!isCopyable())
        throw MailServiceException.CANNOT_COPY(mId);
    if (!target.canContain(this))
        throw MailServiceException.CANNOT_CONTAIN();
    // permissions required are the same as for copy()
    if (!canAccess(ACL.RIGHT_READ))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
    if (!target.canAccess(ACL.RIGHT_INSERT))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the target folder");
    // fetch the parent *before* changing the DB
    MailItem parent = getParent();
    // first, copy the item to the target folder while setting:
    //   - FLAGS -> FLAGS | Flag.BITMASK_COPIED
    //   - INDEX_ID -> old index id
    //   - FOLDER_ID -> new folder
    //   - IMAP_ID -> new IMAP uid
    //   - VOLUME_ID -> target volume ID
    // then, update the original item
    //   - PARENT_ID -> NULL
    //   - FLAGS -> FLAGS | Flag.BITMASK_COPIED
    // finally, update OPEN_CONVERSATION if PARENT_ID was NULL
    //   - ITEM_ID = copy's id for hash
    String locator = null;
    MailboxBlob srcMblob = getBlob();
    if (srcMblob != null) {
        StoreManager sm = StoreManager.getInstance();
        MailboxBlob mblob = sm.copy(srcMblob, mMailbox, copyId, mMailbox.getOperationChangeID());
        mMailbox.markOtherItemDirty(mblob);
        locator = mblob.getLocator();
    }
    // We'll share the index entry if this item can't change out from under us. Re-index the copy if existing item
    // (a) wasn't indexed or (b) is mutable.
    boolean shareIndex = !isMutable() && getIndexStatus() == IndexStatus.DONE && !target.inSpam();
    UnderlyingData data = mData.duplicate(copyId, copyUuid, target.getId(), locator);
    data.metadata = encodeMetadata().toString();
    data.imapId = copyId;
    data.indexId = shareIndex ? getIndexId() : IndexStatus.DEFERRED.id();
    data.contentChanged(mMailbox);
    ZimbraLog.mailop.info("Performing IMAP copy of %s: copyId=%d, folderId=%d, folderName=%s, parentId=%d.", getMailopContext(this), copyId, target.getId(), target.getName(), data.parentId);
    DbMailItem.icopy(this, data, shareIndex);
    MailItem copy = constructItem(mMailbox, data);
    copy.finishCreation(null);
    if (shareIndex && !isTagged(Flag.FlagInfo.COPIED)) {
        Flag copiedFlag = mMailbox.getFlagById(Flag.ID_COPIED);
        tagChanged(copiedFlag, true);
        copy.tagChanged(copiedFlag, true);
        if (parent != null)
            parent.inheritedTagChanged(copiedFlag, true);
    }
    if (parent != null && parent.getId() > 0) {
        markItemModified(Change.PARENT);
        parent.markItemModified(Change.CHILDREN);
        mData.parentId = mData.type == Type.MESSAGE.toByte() ? -mId : -1;
        metadataChanged();
    }
    if (!shareIndex) {
        mMailbox.index.add(copy);
    }
    return copy;
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) MailboxBlob(com.zimbra.cs.store.MailboxBlob) StoreManager(com.zimbra.cs.store.StoreManager)

Example 27 with StoreManager

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

the class MailItem method copy.

/** Copies an item to a {@link Folder}.  Persists the new item to the
     *  database and the in-memory cache.  Copies to the same folder as the
     *  original item will succeed.<p>
     *
     *  Immutable copied items (both the original and the target) share the
     *  same entry in the index and get the {@link Flag#BITMASK_COPIED} flag to
     *  facilitate garbage collection of index entries.  (Mutable copied items
     *  are indexed separately.)  They do not share the same blob on disk,
     *  although the system will use a hard link where possible.  Copying a
     *  {@link Message} will put it in the same {@link Conversation} as the
     *  original (exceptions: draft messages, messages in the Junk folder).
     *
     * @param folder    The folder to copy the item to.
     * @param copyId    The item id for the newly-created copy.
     * @param parent    The target parent MailItem for the new copy.
     * @perms {@link ACL#RIGHT_INSERT} on the target folder,
     *        {@link ACL#RIGHT_READ} on the original item
     * @throws ServiceException  The following error codes are possible:<ul>
     *    <li><tt>mail.CANNOT_COPY</tt> - if the item is not copyable
     *    <li><tt>mail.CANNOT_CONTAIN</tt> - if the target folder can't hold
     *        the copy of the item
     *    <li><tt>service.FAILURE</tt> - if there's a database failure
     *    <li><tt>service.PERM_DENIED</tt> - if you don't have sufficient
     *        permissions</ul> */
MailItem copy(Folder folder, int copyId, String copyUuid, MailItem parent) throws IOException, ServiceException {
    if (!isCopyable())
        throw MailServiceException.CANNOT_COPY(mId);
    if (!folder.canContain(this))
        throw MailServiceException.CANNOT_CONTAIN();
    if (!canAccess(ACL.RIGHT_READ))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
    if (!folder.canAccess(ACL.RIGHT_INSERT))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the target folder");
    // We'll share the index entry if this item can't change out from under us. Re-index the copy if existing item
    // (a) wasn't indexed or (b) is mutable or (c) existing item is in dumpster (which implies copy is not in
    // dumpster)
    boolean inDumpster = inDumpster();
    boolean shareIndex = !inDumpster && !isMutable() && getIndexStatus() == IndexStatus.DONE && !folder.inSpam();
    // if the copy or original is in Spam, put the copy in its own conversation
    boolean detach = parent == null || isTagged(Flag.FlagInfo.DRAFT) || inSpam() != folder.inSpam();
    parent = detach ? null : parent;
    if (shareIndex && !isTagged(Flag.FlagInfo.COPIED)) {
        alterSystemFlag(mMailbox.getFlagById(Flag.ID_COPIED), true);
        if (ZimbraLog.mailop.isDebugEnabled()) {
            ZimbraLog.mailop.debug("setting copied flag for %s", getMailopContext(this));
        }
    }
    StoreManager sm = StoreManager.getInstance();
    // main item
    String locator = null;
    MailboxBlob srcMblob = getBlob();
    if (srcMblob != null) {
        MailboxBlob mblob = sm.copy(srcMblob, mMailbox, copyId, mMailbox.getOperationChangeID());
        mMailbox.markOtherItemDirty(mblob);
        locator = mblob.getLocator();
    }
    UnderlyingData data = mData.duplicate(copyId, copyUuid, folder.getId(), locator);
    data.parentId = detach ? -1 : parent.mId;
    data.indexId = shareIndex ? getIndexId() : IndexStatus.DEFERRED.id();
    if (!shareIndex) {
        data.unsetFlag(Flag.FlagInfo.COPIED);
    }
    // The copy is never in dumpster.
    data.unsetFlag(Flag.FlagInfo.IN_DUMPSTER);
    data.metadata = encodeMetadata().toString();
    data.contentChanged(mMailbox);
    ZimbraLog.mailop.info("Copying %s: copyId=%d, folderId=%d, folderName=%s, parentId=%d.", getMailopContext(this), copyId, folder.getId(), folder.getName(), data.parentId);
    String prevFolders = DbMailItem.copy(this, copyId, copyUuid, folder, data.indexId, data.parentId, data.locator, data.metadata, inDumpster);
    if (!StringUtil.isNullOrEmpty(prevFolders)) {
        data.setPrevFolders(prevFolders);
    }
    if (this instanceof CalendarItem)
        DbMailItem.copyCalendarItem((CalendarItem) this, copyId, inDumpster);
    // it is never desirable to copy old revisions. (bug 55070)
    if (inDumpster) {
        for (MailItem revision : loadRevisions()) {
            MailboxBlob srcRevBlob = revision.getBlob();
            String revLocator = null;
            if (srcRevBlob != null) {
                MailboxBlob copyRevBlob = sm.copy(srcRevBlob, mMailbox, copyId, revision.getSavedSequence());
                mMailbox.markOtherItemDirty(copyRevBlob);
                revLocator = copyRevBlob.getLocator();
            }
            DbMailItem.copyRevision(revision, copyId, revLocator, inDumpster);
        }
    }
    MailItem copy = constructItem(mMailbox, data);
    copy.finishCreation(parent);
    if (!shareIndex) {
        mMailbox.index.add(copy);
    }
    return copy;
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) MailboxBlob(com.zimbra.cs.store.MailboxBlob) StoreManager(com.zimbra.cs.store.StoreManager)

Example 28 with StoreManager

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

the class SaveDraft method redo.

@Override
public void redo() throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(getMailboxId());
    StoreManager sm = StoreManager.getInstance();
    Blob blob = null;
    InputStream in = null;
    try {
        in = mData.getInputStream();
        if (mData.getLength() != mMsgSize)
            in = new GZIPInputStream(in);
        blob = sm.storeIncoming(in);
        ParsedMessage pm = new ParsedMessage(blob.getFile(), getTimestamp(), mbox.attachmentsIndexingEnabled());
        mbox.saveDraft(getOperationContext(), pm, getMessageId());
    } finally {
        ByteUtil.closeStream(in);
        sm.quietDelete(blob);
    }
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) Blob(com.zimbra.cs.store.Blob) Mailbox(com.zimbra.cs.mailbox.Mailbox) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) StoreManager(com.zimbra.cs.store.StoreManager)

Example 29 with StoreManager

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

the class VerifyStoreManager method basicPerfTest.

private Stats basicPerfTest(int numBlobs, int blobSize, boolean checkBlobs) throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(AccountTestUtil.getAccount(USER_NAME));
    StoreManager sm = StoreManager.getInstance();
    List<ParsedMessage> msgs = new ArrayList<ParsedMessage>();
    int count = numBlobs;
    for (int i = 0; i < count; i++) {
        msgs.add(getMessage(blobSize));
    }
    List<Blob> incoming = new ArrayList<Blob>();
    ZimbraLog.store.info("starting store incoming loop");
    long start = System.currentTimeMillis();
    for (ParsedMessage msg : msgs) {
        incoming.add(sm.storeIncoming(msg.getRawInputStream()));
    }
    long incomingTime = System.currentTimeMillis() - start;
    List<StagedBlob> staged = new ArrayList<StagedBlob>();
    ZimbraLog.store.info("starting stage loop");
    start = System.currentTimeMillis();
    for (Blob blob : incoming) {
        staged.add(sm.stage(blob, mbox));
    }
    long stageTime = System.currentTimeMillis() - start;
    List<MailboxBlob> linked = new ArrayList<MailboxBlob>();
    ZimbraLog.store.info("starting link loop");
    start = System.currentTimeMillis();
    //fake itemId, never use this test with real userid
    int i = 0;
    for (StagedBlob blob : staged) {
        linked.add(sm.link(blob, mbox, i++, 1));
    }
    long linkTime = System.currentTimeMillis() - start;
    List<MailboxBlob> fetched = new ArrayList<MailboxBlob>();
    ZimbraLog.store.info("starting fetch loop");
    start = System.currentTimeMillis();
    i = 0;
    for (MailboxBlob mblob : linked) {
        fetched.add(sm.getMailboxBlob(mbox, i++, 1, mblob.getLocator()));
    }
    long fetchTime = System.currentTimeMillis() - start;
    if (checkBlobs) {
        for (i = 0; i < count; i++) {
            checkBlob(msgs.get(i), incoming.get(i), staged.get(i), linked.get(i), fetched.get(i), mbox);
        }
    }
    ZimbraLog.store.info("starting delete loop");
    start = System.currentTimeMillis();
    for (MailboxBlob mblob : fetched) {
        sm.delete(mblob);
    }
    long deleteTime = System.currentTimeMillis() - start;
    Stats stats = new Stats(numBlobs, incomingTime, stageTime, linkTime, fetchTime, deleteTime);
    return stats;
}
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) MailboxBlob(com.zimbra.cs.store.MailboxBlob) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) ArrayList(java.util.ArrayList) StoreManager(com.zimbra.cs.store.StoreManager) Mailbox(com.zimbra.cs.mailbox.Mailbox)

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