Search in sources :

Example 81 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class Notification method outOfOfficeIfNecessary.

/**
     * If the recipient's account requires out of office notification,
     * send it out.  We send these out based on users' setting, and
     * the incoming message meeting certain criteria.
     */
private void outOfOfficeIfNecessary(Account account, Mailbox mbox, MimeMessage mm, Integer msgId, String rcpt, String envSenderString) throws ServiceException, MessagingException {
    boolean replyEnabled = account.isPrefOutOfOfficeReplyEnabled();
    if (ZimbraLog.mailbox.isDebugEnabled()) {
        ZimbraLog.mailbox.debug("outofoffice reply enabled=" + replyEnabled + " rcpt='" + rcpt + "' mid=" + msgId);
    }
    if (!replyEnabled) {
        return;
    }
    // Check if we are in any configured out of office interval
    Date now = new Date();
    Date fromDate = account.getGeneralizedTimeAttr(Provisioning.A_zimbraPrefOutOfOfficeFromDate, null);
    if (fromDate != null && now.before(fromDate)) {
        ofailed("from date not reached", null, rcpt, msgId);
        return;
    }
    Date untilDate = account.getGeneralizedTimeAttr(Provisioning.A_zimbraPrefOutOfOfficeUntilDate, null);
    if (untilDate != null && now.after(untilDate)) {
        ofailed("until date reached", null, rcpt, msgId);
        return;
    }
    // If envelope sender is empty
    if (envSenderString == null) {
        ofailed("envelope sender null", null, rcpt, msgId);
        return;
    }
    if (envSenderString.length() < 1) {
        // be conservative
        ofailed("envelope sender empty", null, rcpt, msgId);
        return;
    }
    InternetAddress envSender;
    try {
        // NB: 'strict' being 'true' causes <> to except
        envSender = new JavaMailInternetAddress(envSenderString, true);
    } catch (AddressException ae) {
        ofailed("envelope sender invalid", envSenderString, rcpt, msgId, ae);
        return;
    }
    String destination = envSender.getAddress();
    if (Mime.isAutoSubmitted(mm)) {
        ofailed("auto-submitted not no", destination, rcpt, msgId);
        return;
    }
    // If precedence is bulk, junk or list
    String[] precedence = mm.getHeader("Precedence");
    if (hasPrecedence(precedence, "bulk")) {
        ofailed("precedence bulk", destination, rcpt, msgId);
        return;
    } else if (hasPrecedence(precedence, "junk")) {
        ofailed("precedence junk", destination, rcpt, msgId);
        return;
    } else if (hasPrecedence(precedence, "list")) {
        ofailed("precedence list", destination, rcpt, msgId);
        return;
    }
    // Check if the envelope sender indicates a mailing list owner and such
    String[] envSenderAddrParts = EmailUtil.getLocalPartAndDomain(destination);
    if (envSenderAddrParts == null) {
        ofailed("envelope sender invalid", destination, rcpt, msgId);
        return;
    }
    String envSenderLocalPart = envSenderAddrParts[0];
    envSenderLocalPart = envSenderLocalPart.toLowerCase();
    if (envSenderLocalPart.startsWith("owner-") || envSenderLocalPart.endsWith("-owner")) {
        ofailed("envelope sender has owner- or -owner", destination, rcpt, msgId);
        return;
    }
    if (envSenderLocalPart.contains("-request")) {
        ofailed("envelope sender contains -request", destination, rcpt, msgId);
        return;
    }
    if (envSenderLocalPart.equals("mailer-daemon")) {
        ofailed("envelope sender is mailer-daemon", destination, rcpt, msgId);
        return;
    }
    if (envSenderLocalPart.equals("majordomo")) {
        ofailed("envelope sender is majordomo", destination, rcpt, msgId);
        return;
    }
    if (envSenderLocalPart.equals("listserv")) {
        ofailed("envelope sender is listserv", destination, rcpt, msgId);
        return;
    }
    // multipart/report is also machine generated
    String ct = mm.getContentType();
    if (ct != null && ct.equalsIgnoreCase("multipart/report")) {
        ofailed("content-type multipart/report", destination, rcpt, msgId);
        return;
    }
    // Check if recipient was directly mentioned in to/cc of this message
    String[] otherAccountAddrs = account.getMultiAttr(Provisioning.A_zimbraPrefOutOfOfficeDirectAddress);
    if (!AccountUtil.isDirectRecipient(account, otherAccountAddrs, mm, OUT_OF_OFFICE_DIRECT_CHECK_NUM_RECIPIENTS)) {
        ofailed("not direct", destination, rcpt, msgId);
        return;
    }
    // If we've already sent to this user, do not send again
    DbConnection conn = null;
    try {
        conn = DbPool.getConnection(mbox);
        if (DbOutOfOffice.alreadySent(conn, mbox, destination, account.getTimeInterval(Provisioning.A_zimbraPrefOutOfOfficeCacheDuration, DEFAULT_OUT_OF_OFFICE_CACHE_DURATION_MILLIS))) {
            ofailed("already sent", destination, rcpt, msgId);
            return;
        }
    } finally {
        DbPool.quietClose(conn);
    }
    // Send the message
    try {
        SMTPMessage out = new SMTPMessage(JMSession.getSmtpSession());
        // Set From and Reply-To.
        out.setFrom(AccountUtil.getFromAddress(account));
        InternetAddress replyTo = AccountUtil.getReplyToAddress(account);
        if (replyTo != null) {
            out.setReplyTo(new Address[] { replyTo });
        }
        // To
        out.setRecipient(javax.mail.Message.RecipientType.TO, envSender);
        // Date
        out.setSentDate(new Date());
        // Subject
        String subject = Mime.getSubject(mm);
        String replySubjectPrefix = L10nUtil.getMessage(L10nUtil.MsgKey.replySubjectPrefix, account.getLocale());
        if (subject == null) {
            subject = replySubjectPrefix;
        } else if (!subject.toLowerCase().startsWith(replySubjectPrefix.toLowerCase())) {
            subject = replySubjectPrefix + " " + subject;
        }
        String charset = getCharset(account, subject);
        out.setSubject(subject, charset);
        // In-Reply-To
        String messageId = mm.getMessageID();
        if (messageId != null && !messageId.trim().equals("")) {
            out.setHeader("In-Reply-To", messageId);
        }
        // Auto-Submitted
        out.setHeader("Auto-Submitted", "auto-replied (zimbra; vacation)");
        // Precedence (discourage older systems from responding)
        out.setHeader("Precedence", "bulk");
        // check whether to send "external" OOO reply
        if (account.isPrefOutOfOfficeSuppressExternalReply() && isOfExternalSenderType(destination, account, mbox) && !isInternalSender(destination, account)) {
            ZimbraLog.mailbox.info(destination + " is external user and no external reply option is set, so no OOO will be sent. ");
            return;
        }
        boolean sendExternalReply = account.isPrefOutOfOfficeExternalReplyEnabled() && !isInternalSender(destination, account) && isOfExternalSenderType(destination, account, mbox);
        String body = account.getAttr(sendExternalReply ? Provisioning.A_zimbraPrefOutOfOfficeExternalReply : Provisioning.A_zimbraPrefOutOfOfficeReply, "");
        charset = getCharset(account, body);
        out.setText(body, charset);
        if (Provisioning.getInstance().getConfig().getBooleanAttr(Provisioning.A_zimbraAutoSubmittedNullReturnPath, true)) {
            out.setEnvelopeFrom("<>");
        } else {
            out.setEnvelopeFrom(account.getName());
        }
        MailSender sender = mbox.getMailSender();
        sender.setSaveToSent(false);
        sender.setDsnNotifyOptions(MailSender.DsnNotifyOption.NEVER);
        sender.sendMimeMessage(null, mbox, out);
        ZimbraLog.mailbox.info("outofoffice sent dest='" + destination + "' rcpt='" + rcpt + "' mid=" + msgId);
        // Save so we will not send to again
        try {
            conn = DbPool.getConnection(mbox);
            DbOutOfOffice.setSentTime(conn, mbox, destination);
            conn.commit();
        } finally {
            DbPool.quietClose(conn);
        }
    } catch (MessagingException me) {
        ofailed("send failed", destination, rcpt, msgId, me);
    }
}
Also used : InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) SMTPMessage(com.sun.mail.smtp.SMTPMessage) MessagingException(javax.mail.MessagingException) AddressException(javax.mail.internet.AddressException) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Date(java.util.Date) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 82 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class BlobDeduper method markBlobAsProcessed.

private void markBlobAsProcessed(BlobReference blob) throws ServiceException {
    DbConnection conn = null;
    try {
        conn = DbPool.getConnection();
        DbVolumeBlobs.updateProcessed(conn, blob.getId(), true);
        conn.commit();
    } finally {
        DbPool.quietClose(conn);
    }
}
Also used : DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 83 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class BlobConsistencyChecker method check.

public Results check(Collection<Short> volumeIds, int mboxId, boolean checkSize, boolean reportUsedBlobs) throws ServiceException {
    StoreManager sm = StoreManager.getInstance();
    if (!(sm instanceof FileBlobStore)) {
        throw ServiceException.INVALID_REQUEST(sm.getClass().getSimpleName() + " is not supported", null);
    }
    mailboxId = mboxId;
    this.checkSize = checkSize;
    this.reportUsedBlobs = reportUsedBlobs;
    results = new Results();
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(mailboxId);
    DbConnection conn = null;
    try {
        conn = DbPool.getConnection();
        for (short volumeId : volumeIds) {
            Volume vol = VolumeManager.getInstance().getVolume(volumeId);
            if (vol.getType() == Volume.TYPE_INDEX) {
                log.warn("Skipping index volume %d.  Only message volumes are supported.", vol.getId());
                continue;
            }
            int numGroups = 1 << vol.getFileGroupBits();
            int filesPerGroup = 1 << vol.getFileBits();
            // Maximum id for the entire mailbox
            int mailboxMaxId = DbBlobConsistency.getMaxId(conn, mbox);
            // Iterate group directories one at a time, looking up all item id's
            // that have blobs in each directory.  Each group can have multiple blocks
            // of id's if we wrap from group 255 back to group 0.
            // Minimum id for the current block
            int minId = 0;
            // Current group number
            int group = 0;
            int maxId = 0;
            while (minId <= mailboxMaxId && group < numGroups) {
                // We used Multimap to make sure we store multiple BlobInfo objects for the same itemId
                // multiple BlobInfo objects are created when there are multiple revisions of the same file
                Multimap<Integer, BlobInfo> blobsById = HashMultimap.create();
                String blobDir = vol.getBlobDir(mbox.getId(), minId);
                while (minId <= mailboxMaxId) {
                    // Maximum id for the current block
                    maxId = minId + filesPerGroup - 1;
                    for (BlobInfo blob : DbBlobConsistency.getBlobInfo(conn, mbox, minId, maxId, volumeId)) {
                        blobsById.put(blob.itemId, blob);
                    }
                    minId += (numGroups * filesPerGroup);
                }
                try {
                    check(volumeId, blobDir, blobsById);
                } catch (IOException e) {
                    throw ServiceException.FAILURE("Unable to check " + blobDir, e);
                }
                group++;
                // Set minId to the smallest id in the next group
                minId = group * filesPerGroup;
            }
        }
    } finally {
        DbPool.quietClose(conn);
    }
    return results;
}
Also used : IOException(java.io.IOException) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) StoreManager(com.zimbra.cs.store.StoreManager) Mailbox(com.zimbra.cs.mailbox.Mailbox) Volume(com.zimbra.cs.volume.Volume)

Example 84 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class BlobDeduper method processDigest.

private Pair<Integer, Long> processDigest(String digest, Volume volume) throws ServiceException {
    // get the blobs
    DbConnection conn = null;
    List<BlobReference> blobs;
    try {
        conn = DbPool.getConnection();
        blobs = DbVolumeBlobs.getBlobReferences(conn, digest, volume);
    } finally {
        DbPool.quietClose(conn);
    }
    // dedupe the paths
    if (blobs.size() > 1) {
        ZimbraLog.misc.debug("Deduping " + blobs.size() + " files for digest " + digest + " volume " + volume.getId());
        return deDupe(blobs);
    } else if (blobs.size() == 1) {
        // mark the blob as processed if there is only one blob for given digest.
        markBlobAsProcessed(blobs.get(0));
    }
    return new Pair<Integer, Long>(0, Long.valueOf(0));
}
Also used : DbConnection(com.zimbra.cs.db.DbPool.DbConnection) Pair(com.zimbra.common.util.Pair)

Example 85 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DbUtil method executeUpdate.

/**
     * Executes the specified update using a connection from the connection pool.
     *
     * @return the number of rows affected
     * @throws ServiceException if the update cannot be executed
     */
public static int executeUpdate(String sql, Object... params) throws ServiceException {
    DbConnection conn = DbPool.getConnection();
    try {
        int numRows = executeUpdate(conn, sql, params);
        conn.commit();
        return numRows;
    } finally {
        DbPool.quietClose(conn);
    }
}
Also used : DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Aggregations

DbConnection (com.zimbra.cs.db.DbPool.DbConnection)218 PreparedStatement (java.sql.PreparedStatement)165 SQLException (java.sql.SQLException)162 ResultSet (java.sql.ResultSet)85 Mailbox (com.zimbra.cs.mailbox.Mailbox)71 ArrayList (java.util.ArrayList)36 ServiceException (com.zimbra.common.service.ServiceException)23 UnderlyingData (com.zimbra.cs.mailbox.MailItem.UnderlyingData)18 HashMap (java.util.HashMap)10 Metadata (com.zimbra.cs.mailbox.Metadata)9 IOException (java.io.IOException)9 MailItem (com.zimbra.cs.mailbox.MailItem)8 TypedIdList (com.zimbra.cs.mailbox.util.TypedIdList)8 AccountServiceException (com.zimbra.cs.account.AccountServiceException)7 Folder (com.zimbra.cs.mailbox.Folder)7 List (java.util.List)6 DbVolume (com.zimbra.cs.db.DbVolume)5 PendingDelete (com.zimbra.cs.mailbox.MailItem.PendingDelete)5 VirtualConversation (com.zimbra.cs.mailbox.VirtualConversation)5 CreateVolume (com.zimbra.cs.redolog.op.CreateVolume)5