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);
}
}
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);
}
}
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;
}
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));
}
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);
}
}
Aggregations