diff options
Diffstat (limited to 'java/com/google/gerrit/server/submit/EmailMerge.java')
-rw-r--r-- | java/com/google/gerrit/server/submit/EmailMerge.java | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/java/com/google/gerrit/server/submit/EmailMerge.java b/java/com/google/gerrit/server/submit/EmailMerge.java new file mode 100644 index 0000000000..a6b7344719 --- /dev/null +++ b/java/com/google/gerrit/server/submit/EmailMerge.java @@ -0,0 +1,148 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.submit; + +import com.google.common.collect.ListMultimap; +import com.google.common.flogger.FluentLogger; +import com.google.gerrit.common.Nullable; +import com.google.gerrit.extensions.api.changes.NotifyHandling; +import com.google.gerrit.extensions.api.changes.RecipientType; +import com.google.gerrit.reviewdb.client.Account; +import com.google.gerrit.reviewdb.client.Change; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.config.SendEmailExecutor; +import com.google.gerrit.server.mail.send.MergedSender; +import com.google.gerrit.server.util.RequestContext; +import com.google.gerrit.server.util.ThreadLocalRequestContext; +import com.google.gwtorm.server.OrmException; +import com.google.gwtorm.server.SchemaFactory; +import com.google.inject.Inject; +import com.google.inject.OutOfScopeException; +import com.google.inject.Provider; +import com.google.inject.ProvisionException; +import com.google.inject.assistedinject.Assisted; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +class EmailMerge implements Runnable, RequestContext { + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + + interface Factory { + EmailMerge create( + Project.NameKey project, + Change.Id changeId, + Account.Id submitter, + NotifyHandling notifyHandling, + ListMultimap<RecipientType, Account.Id> accountsToNotify); + } + + private final ExecutorService sendEmailsExecutor; + private final MergedSender.Factory mergedSenderFactory; + private final SchemaFactory<ReviewDb> schemaFactory; + private final ThreadLocalRequestContext requestContext; + private final IdentifiedUser.GenericFactory identifiedUserFactory; + + private final Project.NameKey project; + private final Change.Id changeId; + private final Account.Id submitter; + private final NotifyHandling notifyHandling; + private final ListMultimap<RecipientType, Account.Id> accountsToNotify; + + private ReviewDb db; + + @Inject + EmailMerge( + @SendEmailExecutor ExecutorService executor, + MergedSender.Factory mergedSenderFactory, + SchemaFactory<ReviewDb> schemaFactory, + ThreadLocalRequestContext requestContext, + IdentifiedUser.GenericFactory identifiedUserFactory, + @Assisted Project.NameKey project, + @Assisted Change.Id changeId, + @Assisted @Nullable Account.Id submitter, + @Assisted NotifyHandling notifyHandling, + @Assisted ListMultimap<RecipientType, Account.Id> accountsToNotify) { + this.sendEmailsExecutor = executor; + this.mergedSenderFactory = mergedSenderFactory; + this.schemaFactory = schemaFactory; + this.requestContext = requestContext; + this.identifiedUserFactory = identifiedUserFactory; + this.project = project; + this.changeId = changeId; + this.submitter = submitter; + this.notifyHandling = notifyHandling; + this.accountsToNotify = accountsToNotify; + } + + void sendAsync() { + @SuppressWarnings("unused") + Future<?> possiblyIgnoredError = sendEmailsExecutor.submit(this); + } + + @Override + public void run() { + RequestContext old = requestContext.setContext(this); + try { + MergedSender cm = mergedSenderFactory.create(project, changeId); + if (submitter != null) { + cm.setFrom(submitter); + } + cm.setNotify(notifyHandling); + cm.setAccountsToNotify(accountsToNotify); + cm.send(); + } catch (Exception e) { + logger.atSevere().withCause(e).log("Cannot email merged notification for %s", changeId); + } finally { + requestContext.setContext(old); + if (db != null) { + db.close(); + db = null; + } + } + } + + @Override + public String toString() { + return "send-email merged"; + } + + @Override + public CurrentUser getUser() { + if (submitter != null) { + return identifiedUserFactory.create(submitter).getRealUser(); + } + throw new OutOfScopeException("No user on email thread"); + } + + @Override + public Provider<ReviewDb> getReviewDbProvider() { + return new Provider<ReviewDb>() { + @Override + public ReviewDb get() { + if (db == null) { + try { + db = schemaFactory.open(); + } catch (OrmException e) { + throw new ProvisionException("Cannot open ReviewDb", e); + } + } + return db; + } + }; + } +} |