mirror of
https://github.com/google/nomulus.git
synced 2025-06-01 10:14:04 +02:00
Move invoice generation to billing bucket and improve emailing
This moves the new pipeline's invoice generation to the billing bucket, under the 'invoices/yyyy-MM' subdirectory. This also changes the invoice e-mail to use a multipart message that attaches the invoice to the e-mail, to guarantee the correct MIME type and download. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=181746191
This commit is contained in:
parent
5726f1dc4e
commit
a42f18798e
16 changed files with 477 additions and 133 deletions
|
@ -22,11 +22,11 @@ import com.google.appengine.tools.cloudstorage.GcsFilename;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.billing.BillingModule.InvoiceDirectoryPrefix;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.gcs.GcsUtils;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.storage.drive.DriveConnection;
|
||||
|
@ -45,39 +45,39 @@ public final class CopyDetailReportsAction implements Runnable {
|
|||
|
||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||
|
||||
// TODO(larryruili): Replace this bucket with the billing bucket after verifying 2017-12 output.
|
||||
private final String beamBucketUrl;
|
||||
private final String folderPrefix;
|
||||
private final String billingBucket;
|
||||
private final String invoiceDirectoryPrefix;
|
||||
private final DriveConnection driveConnection;
|
||||
private final GcsUtils gcsUtils;
|
||||
private final Retrier retrier;
|
||||
private final Response response;
|
||||
private final BillingEmailUtils emailUtils;
|
||||
|
||||
@Inject
|
||||
CopyDetailReportsAction(
|
||||
@Config("apacheBeamBucketUrl") String beamBucketUrl,
|
||||
@Parameter(BillingModule.PARAM_DIRECTORY_PREFIX) String folderPrefix,
|
||||
@Config("billingBucket") String billingBucket,
|
||||
@InvoiceDirectoryPrefix String invoiceDirectoryPrefix,
|
||||
DriveConnection driveConnection,
|
||||
GcsUtils gcsUtils,
|
||||
Retrier retrier,
|
||||
Response response) {
|
||||
this.beamBucketUrl = beamBucketUrl;
|
||||
this.folderPrefix = folderPrefix;
|
||||
Response response,
|
||||
BillingEmailUtils emailUtils) {
|
||||
this.billingBucket = billingBucket;
|
||||
this.invoiceDirectoryPrefix = invoiceDirectoryPrefix;
|
||||
this.driveConnection = driveConnection;
|
||||
this.gcsUtils = gcsUtils;
|
||||
this.retrier = retrier;
|
||||
this.response = response;
|
||||
this.emailUtils = emailUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Strip the URL prefix from the beam bucket
|
||||
String beamBucket = beamBucketUrl.replace("gs://", "");
|
||||
ImmutableList<String> detailReportObjectNames;
|
||||
try {
|
||||
detailReportObjectNames =
|
||||
gcsUtils
|
||||
.listFolderObjects(beamBucket, folderPrefix)
|
||||
.listFolderObjects(billingBucket, invoiceDirectoryPrefix)
|
||||
.stream()
|
||||
.filter(objectName -> objectName.startsWith(BillingModule.DETAIL_REPORT_PREFIX))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
|
@ -93,7 +93,6 @@ public final class CopyDetailReportsAction implements Runnable {
|
|||
// TODO(larryruili): Determine a safer way of enforcing this.
|
||||
String registrarId = detailReportName.split("_")[3];
|
||||
Optional<Registrar> registrar = Registrar.loadByClientId(registrarId);
|
||||
// TODO(larryruili): Send an email alert if any report fails to be copied for any reason.
|
||||
if (!registrar.isPresent()) {
|
||||
logger.warningfmt(
|
||||
"Registrar %s not found in database for file %s", registrar, detailReportName);
|
||||
|
@ -109,7 +108,7 @@ public final class CopyDetailReportsAction implements Runnable {
|
|||
() -> {
|
||||
try (InputStream input =
|
||||
gcsUtils.openInputStream(
|
||||
new GcsFilename(beamBucket, folderPrefix + detailReportName))) {
|
||||
new GcsFilename(billingBucket, invoiceDirectoryPrefix + detailReportName))) {
|
||||
driveConnection.createFile(
|
||||
detailReportName,
|
||||
MediaType.CSV_UTF_8,
|
||||
|
@ -117,7 +116,19 @@ public final class CopyDetailReportsAction implements Runnable {
|
|||
ByteStreams.toByteArray(input));
|
||||
logger.infofmt(
|
||||
"Published detail report for %s to folder %s using GCS file gs://%s/%s.",
|
||||
registrarId, driveFolderId, beamBucket, detailReportName);
|
||||
registrarId, driveFolderId, billingBucket, detailReportName);
|
||||
}
|
||||
},
|
||||
new Retrier.FailureReporter() {
|
||||
@Override
|
||||
public void beforeRetry(Throwable thrown, int failures, int maxAttempts) {}
|
||||
|
||||
@Override
|
||||
public void afterFinalFailure(Throwable thrown, int failures) {
|
||||
emailUtils.sendAlertEmail(
|
||||
String.format(
|
||||
"Warning: CopyDetailReportsAction failed.\nEncountered: %s on file: %s",
|
||||
thrown.getMessage(), detailReportName));
|
||||
}
|
||||
},
|
||||
IOException.class);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue