use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.
the class ZMailbox method invoke.
public Element invoke(Element request, String requestedAccountId) throws ServiceException {
lock();
try {
try {
boolean nosession = mNotifyPreference == SessionPreference.nosession;
if (nosession) {
return mTransport.invoke(request, false, nosession, requestedAccountId);
} else {
return mTransport.invoke(request, nosession, requestedAccountId, this.mNotificationFormat, this.mCurWaitSetID);
}
} catch (SoapFaultException e) {
// for now, later, try to map to more specific exception
throw e;
} catch (IOException e) {
doConnectionAndSSLFailures(e);
throw ZClientException.IO_ERROR(e.getMessage(), e);
} catch (Exception e) {
doConnectionAndSSLFailures(e);
throw ServiceException.FAILURE(e.getMessage(), e);
} finally {
Element context = mTransport.getZimbraContext();
mTransport.clearZimbraContext();
handleResponseContext(context);
}
} finally {
unlock();
}
}
use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.
the class ZMailbox method populateTagCache.
private void populateTagCache() throws ServiceException {
if (mNameToTag != null) {
return;
}
if (mNotifyPreference == null || mNotifyPreference == SessionPreference.full) {
noOp();
if (mNameToTag != null) {
return;
}
}
List<ZTag> tagList = new ArrayList<ZTag>();
if (!mNoTagCache) {
try {
Element response = invoke(newRequestElement(MailConstants.GET_TAG_REQUEST));
for (Element t : response.listElements(MailConstants.E_TAG)) {
tagList.add(new ZTag(t, this));
}
} catch (SoapFaultException sfe) {
if (!sfe.getCode().equals(ServiceException.PERM_DENIED)) {
throw sfe;
}
}
}
ZRefreshEvent event = new ZRefreshEvent(mSize, null, tagList);
for (ZEventHandler handler : mHandlers) {
handler.handleRefresh(event, this);
}
}
use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.
the class Soap12Protocol method soapFault.
/**
* Given an Element that represents a fault (i.e,. isFault returns
* true on it), construct a SoapFaultException from it.
*
* @return new SoapFaultException
* @throws ServiceException
*/
public SoapFaultException soapFault(Element fault) {
if (!isFault(fault))
return new SoapFaultException("not a soap fault ", fault);
boolean isReceiversFault = false;
Element code = fault.getOptionalElement(CODE);
if (code != null) {
Element value = code.getOptionalElement(VALUE);
isReceiversFault = RECEIVER_CODE.getQualifiedName().equals(value == null ? null : value.getTextTrim());
}
String reasonValue;
Element reason = fault.getOptionalElement(REASON);
Element reasonText = (reason == null ? null : reason.getOptionalElement(TEXT));
if (reasonText != null)
reasonValue = reasonText.getTextTrim();
else
reasonValue = "unknown reason";
Element detail = fault.getOptionalElement(DETAIL);
return new SoapFaultException(reasonValue, detail, isReceiversFault, fault);
}
use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.
the class ImapHandler method fetch.
private boolean fetch(String tag, String sequenceSet, int attributes, List<ImapPartSpecifier> parts, boolean byUID, int changedSince, boolean standalone, boolean allowOutOfRangeMsgSeq) throws IOException, ImapException {
if (!checkState(tag, State.SELECTED)) {
return true;
}
ImapFolder i4folder = getSelectedFolder();
if (i4folder == null) {
throw new ImapSessionClosedException();
}
// of whether a UID was specified as a message data item to the FETCH."
if (byUID) {
attributes |= FETCH_UID;
}
String command = (byUID ? "UID FETCH" : "FETCH");
boolean markRead = i4folder.isWritable() && (attributes & FETCH_MARK_READ) != 0;
// the CHANGEDSINCE UID FETCH modifier."
if ((attributes & FETCH_VANISHED) != 0 && (!byUID || changedSince < 0)) {
throw new ImapParseException(tag, "cannot specify VANISHED without CHANGEDSINCE");
}
if (changedSince >= 0) {
attributes |= FETCH_MODSEQ;
}
if ((attributes & FETCH_MODSEQ) != 0) {
activateExtension(ImapExtension.CONDSTORE);
}
boolean modseqEnabled = sessionActivated(ImapExtension.CONDSTORE);
// MUST reject any such command with the tagged BAD response."
if (!modseqEnabled && (attributes & FETCH_MODSEQ) != 0) {
throw new ImapParseException(tag, "NOMODSEQ", "cannot FETCH MODSEQ in this mailbox", true);
}
List<ImapPartSpecifier> fullMessage = new ArrayList<ImapPartSpecifier>();
if (parts != null && !parts.isEmpty()) {
for (Iterator<ImapPartSpecifier> it = parts.iterator(); it.hasNext(); ) {
ImapPartSpecifier pspec = it.next();
if (pspec.isEntireMessage()) {
it.remove();
fullMessage.add(pspec);
}
}
}
ImapMessageSet i4set;
MailboxStore mbox = i4folder.getMailbox();
mbox.lock(false);
try {
i4set = i4folder.getSubsequence(tag, sequenceSet, byUID, allowOutOfRangeMsgSeq, true);
i4set.remove(null);
} finally {
mbox.unlock();
}
// if VANISHED was requested, we need to return the set of UIDs that *don't* exist in the folder
if (byUID && (attributes & FETCH_VANISHED) != 0) {
int highwater = Integer.MAX_VALUE;
try {
highwater = i4folder.getCurrentMODSEQ();
} catch (ServiceException e) {
}
if (highwater > changedSince) {
String vanished = i4folder.invertSubsequence(sequenceSet, true, i4set);
if (!vanished.isEmpty()) {
sendUntagged("VANISHED (EARLIER) " + vanished);
}
}
}
// make sure it's not just a set of nothing but expunged messages
if (!byUID && !i4set.isEmpty()) {
boolean nonePresent = true;
for (ImapMessage i4msg : i4set) {
if (!i4msg.isExpunged()) {
nonePresent = false;
break;
}
}
if (nonePresent) {
// expunged, the server SHOULD return only a tagged NO."
if (standalone) {
sendNO(tag, "all of the requested messages have been expunged");
}
return true;
}
}
// if a CHANGEDSINCE sequence number was specified, narrow the message set before iterating over the messages
if (changedSince >= 0) {
try {
// get a list of all the messages modified since the checkpoint
ImapMessageSet modified = new ImapMessageSet();
for (int id : mbox.getIdsOfModifiedItemsInFolder(getContext(), changedSince, i4folder.getId())) {
ImapMessage i4msg = i4folder.getById(id);
if (i4msg != null) {
modified.add(i4msg);
}
}
// and intersect those "modified" messages with the set of requested messages
i4set.retainAll(modified);
} catch (ServiceException e) {
if (standalone) {
ZimbraLog.imap.warn(command + " failed", e);
sendNO(tag, command + " failed");
return canContinue(e);
}
}
}
mbox.lock(true);
try {
if (i4folder.areTagsDirty()) {
sendUntagged("FLAGS (" + StringUtil.join(" ", i4folder.getFlagList(false)) + ')');
i4folder.setTagsDirty(false);
}
} finally {
mbox.unlock();
}
ReentrantLock lock = null;
try {
for (ImapMessage i4msg : i4set) {
PrintStream result = new PrintStream(output, false, Charsets.UTF_8.name());
try {
result.print("* " + i4msg.sequence + " FETCH (");
if (i4msg.isExpunged()) {
fetchStub(i4msg, i4folder, attributes, parts, fullMessage, result);
continue;
}
boolean markMessage = markRead && (i4msg.flags & Flag.BITMASK_UNREAD) != 0;
boolean empty = true;
ZimbraMailItem item = null;
MimeMessage mm;
if (!fullMessage.isEmpty() || (parts != null && !parts.isEmpty()) || (attributes & ~FETCH_FROM_CACHE) != 0) {
if (lock == null && LC.imap_throttle_fetch.booleanValue()) {
lock = commandThrottle.lock(credentials.getAccountId());
}
try {
String folderOwner = i4folder.getFolder().getFolderItemIdentifier().accountId;
ItemIdentifier iid = ItemIdentifier.fromAccountIdAndItemId((folderOwner != null) ? folderOwner : mbox.getAccountId(), i4msg.msgId);
item = mbox.getItemById(getContext(), iid, i4msg.getType().toCommon());
} catch (NoSuchItemException nsie) {
// just in case we're out of sync, force this message back into sync
i4folder.markMessageExpunged(i4msg);
fetchStub(i4msg, i4folder, attributes, parts, fullMessage, result);
continue;
}
}
if ((attributes & FETCH_UID) != 0) {
result.print((empty ? "" : " ") + "UID " + i4msg.imapUid);
empty = false;
}
if ((attributes & FETCH_INTERNALDATE) != 0) {
result.print((empty ? "" : " ") + "INTERNALDATE \"" + DateUtil.toImapDateTime(new Date(item.getDate())) + '"');
empty = false;
}
if ((attributes & FETCH_RFC822_SIZE) != 0) {
result.print((empty ? "" : " ") + "RFC822.SIZE " + i4msg.getSize(item));
empty = false;
}
if ((attributes & FETCH_BINARY_SIZE) != 0) {
result.print((empty ? "" : " ") + "BINARY.SIZE[] " + i4msg.getSize(item));
empty = false;
}
if (!fullMessage.isEmpty()) {
for (ImapPartSpecifier pspec : fullMessage) {
result.print(empty ? "" : " ");
pspec.write(result, output, item);
empty = false;
}
}
if ((parts != null && !parts.isEmpty()) || (attributes & FETCH_FROM_MIME) != 0) {
mm = ImapMessage.getMimeMessage(item);
if ((attributes & FETCH_BODY) != 0) {
result.print(empty ? "" : " ");
result.print("BODY ");
ImapMessage.serializeStructure(result, mm, false);
empty = false;
}
if ((attributes & FETCH_BODYSTRUCTURE) != 0) {
result.print(empty ? "" : " ");
result.print("BODYSTRUCTURE ");
ImapMessage.serializeStructure(result, mm, true);
empty = false;
}
if ((attributes & FETCH_ENVELOPE) != 0) {
result.print(empty ? "" : " ");
result.print("ENVELOPE ");
ImapMessage.serializeEnvelope(result, mm);
empty = false;
}
if (parts != null) {
for (ImapPartSpecifier pspec : parts) {
result.print(empty ? "" : " ");
pspec.write(result, output, mm);
empty = false;
}
}
}
// FIXME: optimize by doing a single mark-read op on multiple messages
if (markMessage) {
String folderOwner = i4folder.getFolder().getFolderItemIdentifier().accountId;
ItemIdentifier iid = ItemIdentifier.fromAccountIdAndItemId((folderOwner != null) ? folderOwner : mbox.getAccountId(), i4msg.msgId);
mbox.flagItemAsRead(getContext(), iid, i4msg.getMailItemType());
}
ImapFolder.DirtyMessage unsolicited = i4folder.undirtyMessage(i4msg);
if ((attributes & FETCH_FLAGS) != 0 || unsolicited != null) {
result.print(empty ? "" : " ");
result.print(i4msg.getFlags(i4folder));
empty = false;
}
// data items in all subsequent unsolicited FETCH responses."
if ((attributes & FETCH_MODSEQ) != 0 || (modseqEnabled && unsolicited != null)) {
int modseq = unsolicited == null ? item.getModifiedSequence() : unsolicited.modseq;
result.print((empty ? "" : " ") + "MODSEQ (" + modseq + ')');
empty = false;
}
} catch (ImapPartSpecifier.BinaryDecodingException e) {
// don't write this response line if we're returning NO
result = null;
throw new ImapParseException(tag, "UNKNOWN-CTE", command + "failed: unknown content-type-encoding", false);
} catch (SoapFaultException e) {
fetchException(e);
} catch (ServiceException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) {
fetchException(cause);
} else {
ZimbraLog.imap.warn("ignoring error during " + command + ": ", e);
continue;
}
} catch (MessagingException e) {
ZimbraLog.imap.warn("ignoring error during " + command + ": ", e);
continue;
} catch (IOException ioe) {
fetchException(ioe);
} finally {
if (result != null) {
result.write(')');
output.write(LINE_SEPARATOR_BYTES, 0, LINE_SEPARATOR_BYTES.length);
output.flush();
}
}
}
} finally {
if (lock != null) {
lock.unlock();
}
}
if (standalone) {
sendNotifications(byUID, false);
sendOK(tag, command + " completed");
}
return true;
}
use of com.zimbra.common.soap.SoapFaultException in project zm-mailbox by Zimbra.
the class ImapServerListener method initWaitSet.
private synchronized void initWaitSet(String accountId, boolean alreadyListening) throws ServiceException {
if (wsID == null && this.sessionMap.containsKey(accountId)) {
AdminCreateWaitSetRequest req = new AdminCreateWaitSetRequest("all", false);
checkAuth();
AdminCreateWaitSetResponse resp;
resp = soapProv.invokeJaxbAsAdminWithRetry(req, server);
if (resp == null) {
throw ServiceException.FAILURE("Received null response from AdminCreateWaitSetRequest", null);
}
wsID = resp.getWaitSetId();
setWaitSetIdOnMailboxes();
lastSequence.set(resp.getSequence());
} else {
cancelPendingRequest();
}
ZimbraLog.imap.debug("Current waitset ID is %s", wsID);
// send non-blocking synchronous WaitSetRequest. This way the caller has certainty that listener was added on remote server
AdminWaitSetRequest waitSetReq = new AdminWaitSetRequest(wsID, lastSequence.toString());
waitSetReq.setBlock(false);
waitSetReq.setExpand(true);
if (!this.sessionMap.containsKey(accountId) || this.sessionMap.get(accountId).isEmpty()) {
ZimbraLog.imap.debug("Removing accout %s from waitset %s", accountId, wsID);
waitSetReq.addRemoveAccount(new Id(accountId));
} else {
WaitSetAddSpec updateOrAdd = new WaitSetAddSpec();
updateOrAdd.setId(accountId);
Enumeration<Integer> folderIDs = this.sessionMap.get(accountId).keys();
while (folderIDs.hasMoreElements()) {
updateOrAdd.addFolderInterest(folderIDs.nextElement());
}
if (alreadyListening) {
ZimbraLog.imap.debug("Updating folder interests for account %s in waitset %s", accountId, wsID);
waitSetReq.addUpdateAccount(updateOrAdd);
} else {
ZimbraLog.imap.debug("Adding account %s to waitset %s", accountId, wsID);
waitSetReq.addAddAccount(updateOrAdd);
}
}
try {
ZimbraLog.imap.debug("Sending initial AdminWaitSetRequest. WaitSet ID: %s", wsID);
AdminWaitSetResponse wsResp = soapProv.invokeJaxbAsAdminWithRetry(waitSetReq, server);
processAdminWaitSetResponse(wsResp);
} catch (SoapFaultException e) {
if (AdminServiceException.NO_SUCH_WAITSET.equalsIgnoreCase(e.getCode())) {
// waitset is gone. Create a new one
ZimbraLog.imap.warn("AdminWaitSet %s does not exist anymore", wsID);
wsID = null;
unsetWaitSetIdOnMailboxes();
lastSequence.set(0);
restoreWaitSet();
} else {
throw ServiceException.FAILURE("Failed to process initial AdminWaitSetResponse", e);
}
} catch (Exception e) {
throw ServiceException.FAILURE("Failed to process initial AdminWaitSetResponse", e);
}
}
Aggregations