1
0
mirror of https://github.com/google/nomulus synced 2026-04-25 18:51:40 +00:00

Fix BigDecimal precision of PremiumList.getLabelsToPrices() (#1221)

* Fix BigDecimal precision of PremiumList.getLabelsToPrices()

Different currencies have different numbers of decimal places (e.g. USD has 2,
JPY has 0, and some even have 3). Thus, when loading the contents of a premium
list, we need to set the precision correctly on all of the BigDecimal prices.

This issue was introduced as part of the Registry 3.0 database migration when we
changed each PremiumEntry to being a Money to a BigDecimal (to remove the
redundancy of storing the same currency value over and over).
This commit is contained in:
Ben McIlwain
2021-06-25 19:10:21 -04:00
committed by GitHub
parent a3e8bf219f
commit b7ce08dfdc
4 changed files with 83 additions and 24 deletions

View File

@@ -44,6 +44,7 @@ import google.registry.schema.tld.PremiumListDao;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -183,11 +184,22 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
.createQueryComposer(PremiumEntry.class)
.where("revisionId", EQ, revisionId)
.stream()
.collect(toImmutableMap(PremiumEntry::getDomainLabel, PremiumEntry::getPrice));
.collect(
toImmutableMap(
PremiumEntry::getDomainLabel,
// Set the correct amount of precision for the premium list's currency.
entry -> convertAmountToMoney(entry.getPrice()).getAmount()));
}
return labelsToPrices;
}
/**
* Converts a raw {@link BigDecimal} amount to a {@link Money} by applying the list's currency.
*/
public Money convertAmountToMoney(BigDecimal amount) {
return Money.of(currency, amount.setScale(currency.getDecimalPlaces(), RoundingMode.HALF_EVEN));
}
/**
* Returns a Bloom filter to determine whether a label might be premium, or is definitely not.
*

View File

@@ -143,12 +143,7 @@ public class PremiumListDao {
RevisionIdAndLabel revisionIdAndLabel =
RevisionIdAndLabel.create(loadedList.getRevisionId(), label);
try {
Optional<BigDecimal> price = premiumEntryCache.get(revisionIdAndLabel);
return price.map(
p ->
Money.of(
loadedList.getCurrency(),
p.setScale(loadedList.getCurrency().getDecimalPlaces())));
return premiumEntryCache.get(revisionIdAndLabel).map(loadedList::convertAmountToMoney);
} catch (InvalidCacheLoadException | ExecutionException e) {
throw new RuntimeException(
String.format(