Export billing account map to registrar sheet

The billing account map will be serialized in the following format:

{currency1=id1, currency2=id2, ...}

In order for the output to be deterministic, the billing account map is stored as a sorted map.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=161075814
This commit is contained in:
jianglai 2017-07-06 07:09:33 -07:00 committed by Ben McIlwain
parent 80f8f5ac7f
commit 0013312f5c
5 changed files with 39 additions and 25 deletions

View file

@ -78,8 +78,7 @@ class SyncRegistrarsSheet {
final DateTime executionTime = clock.nowUtc(); final DateTime executionTime = clock.nowUtc();
sheetSynchronizer.synchronize( sheetSynchronizer.synchronize(
spreadsheetId, spreadsheetId,
FluentIterable FluentIterable.from(
.from(
new Ordering<Registrar>() { new Ordering<Registrar>() {
@Override @Override
public int compare(Registrar left, Registrar right) { public int compare(Registrar left, Registrar right) {
@ -128,6 +127,7 @@ class SyncRegistrarsSheet {
builder.put("state", convert(registrar.getState())); builder.put("state", convert(registrar.getState()));
builder.put("ianaIdentifier", convert(registrar.getIanaIdentifier())); builder.put("ianaIdentifier", convert(registrar.getIanaIdentifier()));
builder.put("billingIdentifier", convert(registrar.getBillingIdentifier())); builder.put("billingIdentifier", convert(registrar.getBillingIdentifier()));
builder.put("billingAccountMap", convert(registrar.getBillingAccountMap()));
builder.put("primaryContacts", convertContacts(contacts, byType(ADMIN))); builder.put("primaryContacts", convertContacts(contacts, byType(ADMIN)));
builder.put("techContacts", convertContacts(contacts, byType(TECH))); builder.put("techContacts", convertContacts(contacts, byType(TECH)));
builder.put("marketingContacts", convertContacts(contacts, byType(MARKETING))); builder.put("marketingContacts", convertContacts(contacts, byType(MARKETING)));

View file

@ -81,7 +81,7 @@ public class SyncRegistrarsSheetAction implements Runnable {
private final int statusCode; private final int statusCode;
protected final String message; protected final String message;
private Result(int statusCode, String message) { Result(int statusCode, String message) {
this.statusCode = statusCode; this.statusCode = statusCode;
this.message = message; this.message = message;
} }

View file

@ -43,7 +43,9 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.re2j.Pattern; import com.google.re2j.Pattern;
@ -336,7 +338,9 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
* Map of currency-to-billing account for the registrar. * Map of currency-to-billing account for the registrar.
* *
* <p>A registrar can have different billing accounts that are denoted in different currencies. * <p>A registrar can have different billing accounts that are denoted in different currencies.
* This provides flexibility for billing systems that require such distinction. * This provides flexibility for billing systems that require such distinction. When this field is
* accessed by {@link #getBillingAccountMap}, a sorted map is returned to guarantee deterministic
* behavior when serializing the map, for display purpose for instance.
*/ */
@Nullable @Nullable
@Mapify(CurrencyMapper.class) @Mapify(CurrencyMapper.class)
@ -448,8 +452,8 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
if (billingAccountMap == null) { if (billingAccountMap == null) {
return ImmutableMap.of(); return ImmutableMap.of();
} }
ImmutableMap.Builder<CurrencyUnit, String> billingAccountMapBuilder = ImmutableSortedMap.Builder<CurrencyUnit, String> billingAccountMapBuilder =
new ImmutableMap.Builder<>(); new ImmutableSortedMap.Builder<>(Ordering.natural());
for (Map.Entry<CurrencyUnit, BillingAccountEntry> entry : billingAccountMap.entrySet()) { for (Map.Entry<CurrencyUnit, BillingAccountEntry> entry : billingAccountMap.entrySet()) {
billingAccountMapBuilder.put(entry.getKey(), entry.getValue().accountId); billingAccountMapBuilder.put(entry.getKey(), entry.getValue().accountId);
} }

View file

@ -22,6 +22,7 @@ java_library(
"@javax_servlet_api", "@javax_servlet_api",
"@joda_time", "@joda_time",
"@junit", "@junit",
"@org_joda_money",
"@org_mockito_all", "@org_mockito_all",
], ],
) )

View file

@ -25,6 +25,8 @@ import static google.registry.testing.DatastoreHelper.deleteResource;
import static google.registry.testing.DatastoreHelper.persistNewRegistrar; import static google.registry.testing.DatastoreHelper.persistNewRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource; import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResources; import static google.registry.testing.DatastoreHelper.persistSimpleResources;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.joda.time.DateTimeZone.UTC; import static org.joda.time.DateTimeZone.UTC;
import static org.joda.time.Duration.standardMinutes; import static org.joda.time.Duration.standardMinutes;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@ -135,7 +137,8 @@ public class SyncRegistrarsSheetTest {
.setIcannReferralEmail("jim@example.net") .setIcannReferralEmail("jim@example.net")
.build()); .build());
Registrar registrar = new Registrar.Builder() Registrar registrar =
new Registrar.Builder()
.setClientId("aaaregistrar") .setClientId("aaaregistrar")
.setRegistrarName("AAA Registrar Inc.") .setRegistrarName("AAA Registrar Inc.")
.setType(Registrar.Type.REAL) .setType(Registrar.Type.REAL)
@ -143,8 +146,10 @@ public class SyncRegistrarsSheetTest {
.setState(Registrar.State.SUSPENDED) .setState(Registrar.State.SUSPENDED)
.setPassword("pa$$word") .setPassword("pa$$word")
.setEmailAddress("nowhere@example.org") .setEmailAddress("nowhere@example.org")
.setInternationalizedAddress(new RegistrarAddress.Builder() .setInternationalizedAddress(
.setStreet(ImmutableList.of("I get fallen back upon since there's no l10n addr")) new RegistrarAddress.Builder()
.setStreet(
ImmutableList.of("I get fallen back upon since there's no l10n addr"))
.setCity("Williamsburg") .setCity("Williamsburg")
.setState("NY") .setState("NY")
.setZip("11211") .setZip("11211")
@ -153,6 +158,7 @@ public class SyncRegistrarsSheetTest {
.setAllowedTlds(ImmutableSet.of("example")) .setAllowedTlds(ImmutableSet.of("example"))
.setPhoneNumber("+1.2223334444") .setPhoneNumber("+1.2223334444")
.setUrl("http://www.example.org/aaa_registrar") .setUrl("http://www.example.org/aaa_registrar")
.setBillingAccountMap(ImmutableMap.of(USD, "USD1234", JPY, "JPY7890"))
.build(); .build();
ImmutableList<RegistrarContact> contacts = ImmutableList.of( ImmutableList<RegistrarContact> contacts = ImmutableList.of(
new RegistrarContact.Builder() new RegistrarContact.Builder()
@ -281,6 +287,7 @@ public class SyncRegistrarsSheetTest {
assertThat(row).containsEntry("icannReferralEmail", ""); assertThat(row).containsEntry("icannReferralEmail", "");
assertThat(row).containsEntry("whoisServer", getDefaultRegistrarWhoisServer()); assertThat(row).containsEntry("whoisServer", getDefaultRegistrarWhoisServer());
assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl()); assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl());
assertThat(row).containsEntry("billingAccountMap", "{JPY=JPY7890, USD=USD1234}");
row = rows.get(1); row = rows.get(1);
assertThat(row).containsEntry("clientIdentifier", "anotherregistrar"); assertThat(row).containsEntry("clientIdentifier", "anotherregistrar");
@ -314,6 +321,7 @@ public class SyncRegistrarsSheetTest {
assertThat(row).containsEntry("url", "http://www.example.org/another_registrar"); assertThat(row).containsEntry("url", "http://www.example.org/another_registrar");
assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl()); assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl());
assertThat(row).containsEntry("icannReferralEmail", "jim@example.net"); assertThat(row).containsEntry("icannReferralEmail", "jim@example.net");
assertThat(row).containsEntry("billingAccountMap", "{}");
Cursor cursor = ofy().load().key(Cursor.createGlobalKey(SYNC_REGISTRAR_SHEET)).now(); Cursor cursor = ofy().load().key(Cursor.createGlobalKey(SYNC_REGISTRAR_SHEET)).now();
assertThat(cursor).isNotNull(); assertThat(cursor).isNotNull();
@ -357,5 +365,6 @@ public class SyncRegistrarsSheetTest {
assertThat(row).containsEntry("url", ""); assertThat(row).containsEntry("url", "");
assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl()); assertThat(row).containsEntry("referralUrl", getDefaultRegistrarReferralUrl());
assertThat(row).containsEntry("icannReferralEmail", ""); assertThat(row).containsEntry("icannReferralEmail", "");
assertThat(row).containsEntry("billingAccountMap", "{}");
} }
} }