use of com.zimbra.cs.redolog.op.CreateMailbox 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.redolog.op.CreateMailbox in project zm-mailbox by Zimbra.
the class MailboxManager method createMailbox.
private Mailbox createMailbox(OperationContext octxt, Account account, boolean skipMailHostCheck) throws ServiceException {
if (account == null)
throw ServiceException.FAILURE("createMailbox: must specify an account", null);
if (!skipMailHostCheck && !Provisioning.onLocalServer(account))
throw ServiceException.WRONG_HOST(account.getMailHost(), null);
// the awkward structure here is to avoid calling getMailboxById while holding the lock
Mailbox mbox = null;
Integer mailboxKey = null;
do {
if (mailboxKey != null)
return getMailboxById(mailboxKey);
boolean isGalSyncAccount = AccountUtil.isGalSyncAccount(account);
synchronized (this) {
// check to make sure the mailbox doesn't already exist
mailboxKey = mailboxIds.get(account.getId().toLowerCase());
if (mailboxKey != null)
continue;
// check if the mailbox is created by other server after this server's startup
DbConnection conn = null;
try {
conn = DbPool.getConnection();
mailboxKey = DbMailbox.getMailboxId(conn, account.getId());
if (mailboxKey != null && mailboxKey > 0) {
cacheAccount(account.getId(), mailboxKey);
continue;
}
} finally {
DbPool.quietClose(conn);
}
// didn't have the mailbox in the database; need to create one now
mbox = createMailboxInternal(octxt, account, isGalSyncAccount);
}
} while (mbox == null);
// IO and other longer operations don't block the system.
if (mbox.open())
notifyMailboxCreated(mbox);
return mbox;
}
Aggregations