use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.
the class Mailbox method emptyDumpster.
public int emptyDumpster(OperationContext octxt) throws ServiceException {
if (!hasFullAdminAccess(octxt)) {
throw ServiceException.PERM_DENIED("only admins can delete from dumpster");
}
int numDeleted = 0;
int batchSize = Provisioning.getInstance().getLocalServer().getMailEmptyFolderBatchSize();
ZimbraLog.mailbox.info("Emptying dumpster with batchSize=" + batchSize);
QueryParams params = new QueryParams();
// +1 to catch items put into dumpster in the same second
params.setChangeDateBefore((int) (System.currentTimeMillis() / 1000 + 1)).setRowLimit(batchSize);
while (true) {
lock.lock();
try {
Set<Integer> itemIds = null;
// XXX: should we be in a txn and using getOperationConnection() instead?
DbConnection conn = DbPool.getConnection(this);
try {
itemIds = DbMailItem.getIds(this, conn, params, true);
} finally {
conn.closeQuietly();
}
if (itemIds.isEmpty()) {
break;
}
numDeleted += deleteFromDumpster(octxt, ArrayUtil.toIntArray(itemIds));
} finally {
lock.release();
}
}
return numDeleted;
}
use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.
the class MailboxIndex method upgradeMailboxTo1_2.
/**
* Mailbox version (1.0,1.1)->1.2 Re-Index all contacts.
*/
void upgradeMailboxTo1_2() throws ServiceException {
DbConnection conn = DbPool.getConnection(mailbox);
try {
List<Integer> ids = DbMailItem.getReIndexIds(conn, mailbox, EnumSet.of(MailItem.Type.CONTACT));
if (ids.isEmpty()) {
return;
}
ReIndexTask task = new ReIndexTask(mailbox, ids) {
@Override
protected void onCompletion() throws ServiceException {
mailbox.lock.lock();
try {
if (!mailbox.getVersion().atLeast(1, 2)) {
try {
mailbox.updateVersion(new MailboxVersion((short) 1, (short) 2));
} catch (ServiceException e) {
ZimbraLog.mailbox.warn("Failed to update mbox version after " + "reindex contacts on mailbox upgrade initialization.", e);
}
}
} finally {
mailbox.lock.release();
}
}
};
startReIndex(task);
} catch (ServiceException e) {
ZimbraLog.mailbox.warn("Failed to reindex contacts on mailbox upgrade initialization." + " Skipping (you will have to manually reindex contacts for this mailbox)");
} finally {
conn.closeQuietly();
}
}
use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.
the class MailboxManager method getMailboxById.
protected Mailbox getMailboxById(int mailboxId, FetchMode fetchMode, boolean skipMailHostCheck) throws ServiceException {
// we need the Mailbox instantiation code to run w/o the lock held.
assert (fetchMode == FetchMode.ONLY_IF_CACHED || !Thread.holdsLock(this));
if (mailboxId <= 0)
throw MailServiceException.NO_SUCH_MBOX(mailboxId);
long startTime = ZimbraPerf.STOPWATCH_MBOX_GET.start();
Mailbox mbox = null;
synchronized (this) {
// check to see if the mailbox has already been cached
Object cached = retrieveFromCache(mailboxId, true);
if (cached instanceof Mailbox) {
ZimbraPerf.COUNTER_MBOX_CACHE.increment(100);
mbox = (Mailbox) cached;
}
}
if (fetchMode == FetchMode.ONLY_IF_CACHED && (mbox == null || !mbox.isOpen())) {
// if the mailbox is in the middle of opening, deem it not cached rather than waiting.
return null;
}
if (mbox == null) {
// not found in cache
ZimbraPerf.COUNTER_MBOX_CACHE.increment(0);
MailboxData data;
DbConnection conn = DbPool.getConnection();
try {
// fetch the Mailbox data from the database
data = DbMailbox.getMailboxStats(conn, mailboxId);
if (data == null) {
throw MailServiceException.NO_SUCH_MBOX(mailboxId);
}
} finally {
conn.closeQuietly();
}
mbox = instantiateMailbox(data);
Account account = mbox.getAccount();
boolean isGalSyncAccount = AccountUtil.isGalSyncAccount(account);
mbox.setGalSyncMailbox(isGalSyncAccount);
if (!skipMailHostCheck) {
// server.
if (!Provisioning.onLocalServer(account))
throw ServiceException.WRONG_HOST(account.getMailHost(), null);
}
synchronized (this) {
// avoid the race condition by re-checking the cache and using that data (if any)
Object cached = retrieveFromCache(mailboxId, false);
if (cached instanceof Mailbox) {
mbox = (Mailbox) cached;
} else {
// cache the newly-created Mailbox object
if (cached instanceof MailboxMaintenance) {
((MailboxMaintenance) cached).setMailbox(mbox);
} else {
cacheMailbox(mbox);
}
}
}
}
// and other longer operations don't block the system.
if (mbox.open()) {
// if TRUE, then the mailbox is actually opened, so we need to notify listeners of the mailbox being loaded
notifyMailboxLoaded(mbox);
}
ZimbraPerf.STOPWATCH_MBOX_GET.stop(startTime);
if (maintenanceLocks.containsKey(mbox.getAccountId()) && mbox.getMaintenance() == null) {
//case here where mailbox was unloaded (due to memory pressure or similar) but
//it was in maintenance before so needs to be in maintenance now that it is reloaded
MailboxMaintenance oldMaint = maintenanceLocks.get(mbox.getAccountId());
MailboxMaintenance maint = null;
synchronized (mbox) {
maint = mbox.beginMaintenance();
synchronized (this) {
cache.put(mailboxId, maint);
}
}
if (oldMaint.isNestedAllowed()) {
maint.setNestedAllowed(true);
}
maint.removeAllowedThread(Thread.currentThread());
maintenanceLocks.put(mbox.getAccountId(), maint);
}
return mbox;
}
use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.
the class MailboxManager method createMailboxInternal.
private synchronized Mailbox createMailboxInternal(OperationContext octxt, Account account, boolean isGalSyncAccount) throws ServiceException {
CreateMailbox redoRecorder = new CreateMailbox(account.getId());
Mailbox mbox = null;
boolean success = false;
DbConnection conn = DbPool.getConnection();
try {
CreateMailbox redoPlayer = (octxt == null ? null : (CreateMailbox) octxt.getPlayer());
int id = (redoPlayer == null ? Mailbox.ID_AUTO_INCREMENT : redoPlayer.getMailboxId());
// create the mailbox row and the mailbox database
MailboxData data;
boolean created = false;
try {
data = DbMailbox.createMailbox(conn, id, account.getId(), account.getName(), -1);
ZimbraLog.mailbox.info("Creating mailbox with id %d and group id %d for %s.", data.id, data.schemaGroupId, account.getName());
created = true;
} catch (ServiceException se) {
if (MailServiceException.ALREADY_EXISTS.equals(se.getCode())) {
// mailbox for the account may be created by other server, re-fetch now.
id = DbMailbox.getMailboxId(conn, account.getId());
if (id > 0) {
data = DbMailbox.getMailboxStats(conn, id);
} else {
throw ServiceException.FAILURE("could not create mailbox", se);
}
} else {
throw se;
}
}
mbox = account.isIsExternalVirtualAccount() ? instantiateExternalVirtualMailbox(data) : instantiateMailbox(data);
mbox.setGalSyncMailbox(isGalSyncAccount);
// the existing Connection is used for the rest of this transaction...
mbox.beginTransaction("createMailbox", octxt, redoRecorder, conn);
if (created) {
// create the default folders
mbox.initialize();
}
// cache the accountID-to-mailboxID and mailboxID-to-Mailbox relationships
cacheAccount(data.accountId, data.id);
cacheMailbox(mbox);
redoRecorder.setMailboxId(mbox.getId());
success = true;
} catch (ServiceException e) {
// Log exception here, just in case. If badness happens during rollback
// the original exception will be lost.
ZimbraLog.mailbox.error("Error during mailbox creation", e);
throw e;
} catch (OutOfMemoryError e) {
Zimbra.halt("out of memory", e);
} catch (Throwable t) {
ZimbraLog.mailbox.error("Error during mailbox creation", t);
throw ServiceException.FAILURE("createMailbox", t);
} finally {
try {
if (mbox != null) {
mbox.endTransaction(success);
} else {
conn.rollback();
}
} finally {
conn.closeQuietly();
}
}
return mbox;
}
use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.
the class MailboxManager method getMailboxSizes.
/** Returns the zimbra IDs and approximate sizes for all mailboxes on
* the system. Note that mailboxes are created lazily, so there may be
* accounts homed on this system for whom there is is not yet a mailbox
* and hence are not included in the returned <code>Map</code>.
*
* @throws ServiceException The following error codes are possible:<ul>
* <li><code>service.FAILURE</code> - an error occurred while accessing
* the database; a SQLException is encapsulated</ul> */
public Map<String, Long> getMailboxSizes(List<NamedEntry> accounts) throws ServiceException {
List<Integer> requested;
synchronized (this) {
if (accounts == null) {
requested = new ArrayList<Integer>(mailboxIds.values());
} else {
requested = new ArrayList<Integer>(accounts.size());
for (NamedEntry account : accounts) {
Integer mailboxId = mailboxIds.get(account.getId());
if (mailboxId != null)
requested.add(mailboxId);
}
}
}
DbConnection conn = null;
try {
conn = DbPool.getConnection();
return DbMailbox.getMailboxSizes(conn, requested);
} finally {
if (conn != null)
DbPool.quietClose(conn);
}
}
Aggregations