use of com.google.gerrit.mail.MailMessage in project gerrit by GerritCodeReview.
the class Pop3MailReceiver method handleEmails.
/**
* Opens a connection to the mail server, removes emails where deletion is pending, reads new
* email and closes the connection.
*
* @param async determines if processing messages should happen asynchronously
* @throws MailTransferException in case of a known transport failure
* @throws IOException in case of a low-level transport failure
*/
@Override
public synchronized void handleEmails(boolean async) throws MailTransferException, IOException {
POP3Client pop3;
if (mailSettings.encryption != Encryption.NONE) {
pop3 = new POP3SClient(mailSettings.encryption.name(), true);
} else {
pop3 = new POP3Client();
}
if (mailSettings.port > 0) {
pop3.setDefaultPort(mailSettings.port);
}
pop3.connect(mailSettings.host);
try {
if (!pop3.login(mailSettings.username, mailSettings.password)) {
throw new MailTransferException("Could not login to POP3 email server. Check username and password");
}
try {
POP3MessageInfo[] messages = pop3.listMessages();
if (messages == null) {
throw new MailTransferException("Could not retrieve message list via POP3");
}
logger.atInfo().log("Received %d messages via POP3", messages.length);
// Fetch messages
List<MailMessage> mailMessages = new ArrayList<>();
for (POP3MessageInfo msginfo : messages) {
if (msginfo == null) {
// Message was deleted
continue;
}
try (BufferedReader reader = (BufferedReader) pop3.retrieveMessage(msginfo.number)) {
if (reader == null) {
throw new MailTransferException("Could not retrieve POP3 message header for message " + msginfo.identifier);
}
int[] message = fetchMessage(reader);
MailMessage mailMessage = RawMailParser.parse(message);
// 822 and delete the message if deletion is pending.
if (pendingDeletion.contains(mailMessage.id())) {
if (pop3.deleteMessage(msginfo.number)) {
pendingDeletion.remove(mailMessage.id());
} else {
logger.atSevere().log("Could not delete message %d", msginfo.number);
}
} else {
// Process message further
mailMessages.add(mailMessage);
}
} catch (MailParsingException e) {
logger.atSevere().log("Could not parse message %d", msginfo.number);
}
}
dispatchMailProcessor(mailMessages, async);
} finally {
pop3.logout();
}
} finally {
pop3.disconnect();
}
}
use of com.google.gerrit.mail.MailMessage in project gerrit by GerritCodeReview.
the class MailProcessor method persistComments.
private void persistComments(BatchUpdate.Factory buf, MailMessage message, MailMetadata metadata, Account.Id sender) throws UpdateException, RestApiException {
try (ManualRequestContext ctx = oneOffRequestContext.openAs(sender)) {
List<ChangeData> changeDataList = queryProvider.get().enforceVisibility(true).byLegacyChangeId(Change.id(metadata.changeNumber));
if (changeDataList.isEmpty()) {
sendRejectionEmail(message, InboundEmailError.CHANGE_NOT_FOUND);
return;
}
if (changeDataList.size() != 1) {
logger.atSevere().log("Message %s references unique change %s," + " but there are %d matching changes in the index." + " Will delete message.", message.id(), metadata.changeNumber, changeDataList.size());
sendRejectionEmail(message, InboundEmailError.INTERNAL_EXCEPTION);
return;
}
ChangeData cd = Iterables.getOnlyElement(changeDataList);
if (existingMessageIds(cd).contains(message.id())) {
logger.atInfo().log("Message %s was already processed. Will delete message.", message.id());
return;
}
// Get all comments; filter and sort them to get the original list of
// comments from the outbound email.
// TODO(hiesel) Also filter by original comment author.
Collection<HumanComment> comments = cd.publishedComments().stream().filter(c -> (c.writtenOn.getTime() / 1000) == (metadata.timestamp.getTime() / 1000)).sorted(CommentsUtil.COMMENT_ORDER).collect(toList());
Project.NameKey project = cd.project();
// If URL is not defined, we won't be able to parse line comments. We still attempt to get the
// other ones.
String changeUrl = urlFormatter.get().getChangeViewUrl(cd.project(), cd.getId()).orElse("http://gerrit.invalid/");
List<MailComment> parsedComments;
if (useHtmlParser(message)) {
parsedComments = HtmlParser.parse(message, comments, changeUrl);
} else {
parsedComments = TextParser.parse(message, comments, changeUrl);
}
if (parsedComments.isEmpty()) {
logger.atWarning().log("Could not parse any comments from %s. Will delete message.", message.id());
sendRejectionEmail(message, InboundEmailError.PARSING_ERROR);
return;
}
ImmutableList<CommentForValidation> parsedCommentsForValidation = parsedComments.stream().map(comment -> CommentForValidation.create(CommentForValidation.CommentSource.HUMAN, MAIL_COMMENT_TYPE_TO_VALIDATION_TYPE.get(comment.getType()), comment.getMessage(), comment.getMessage().length())).collect(ImmutableList.toImmutableList());
CommentValidationContext commentValidationCtx = CommentValidationContext.create(cd.change().getChangeId(), cd.change().getProject().get(), cd.change().getDest().branch());
ImmutableList<CommentValidationFailure> commentValidationFailures = PublishCommentUtil.findInvalidComments(commentValidationCtx, commentValidators, parsedCommentsForValidation);
if (!commentValidationFailures.isEmpty()) {
sendRejectionEmail(message, InboundEmailError.COMMENT_REJECTED);
return;
}
Op o = new Op(PatchSet.id(cd.getId(), metadata.patchSet), parsedComments, message.id());
BatchUpdate batchUpdate = buf.create(project, ctx.getUser(), TimeUtil.now());
batchUpdate.addOp(cd.getId(), o);
batchUpdate.execute();
}
}
Aggregations