mirror of
https://github.com/google/nomulus.git
synced 2025-07-09 04:33:28 +02:00
Remove ofy support from BillingEvent (#1710)
This PR turns out to be more massive than I would have liked but it deals with all billing event related stuff, which are more or link all intertwined: * Remove all billing events as Ofy entities. * Add a temporary annotation to allow BillingEvent's ID to be auto-allocated by ofy while not lacking the Ofy @Id annotation. * Remove Modification, which is only used in ofy. * Remove BillingVKey, as we do not need to store the ofy key parent information anymore. The VKey for a billing event now just contain its primary key, and can be converted by VKeyConverter. * Remove BigQuery related code in the billing pipeline. Note that after BillingVKey is removed, several columns in BillingCancellation are no longer needed. The change to database schema will be handled in https://github.com/google/nomulus/pull/1721 after this PR is deployed to production. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1710) <!-- Reviewable:end -->
This commit is contained in:
parent
7824185070
commit
d5be4dcc3b
65 changed files with 472 additions and 1242 deletions
|
@ -253,9 +253,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
|||
final ImmutableSet<DateTime> billingTimes =
|
||||
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
||||
|
||||
VKey<DomainBase> domainKey =
|
||||
VKey.create(
|
||||
DomainBase.class, recurring.getDomainRepoId(), recurring.getParentKey().getParent());
|
||||
VKey<DomainBase> domainKey = VKey.createSql(DomainBase.class, recurring.getDomainRepoId());
|
||||
Iterable<OneTime> oneTimesForDomain;
|
||||
oneTimesForDomain =
|
||||
tm().createQueryComposer(OneTime.class)
|
||||
|
@ -311,11 +309,11 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
|||
.getRenewCost())
|
||||
.setEventTime(eventTime)
|
||||
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setPeriodYears(1)
|
||||
.setReason(recurring.getReason())
|
||||
.setSyntheticCreationTime(executeTime)
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.setTargetId(recurring.getTargetId())
|
||||
.build());
|
||||
}
|
||||
|
|
|
@ -14,47 +14,38 @@
|
|||
|
||||
package google.registry.beam.invoicing;
|
||||
|
||||
import static google.registry.beam.BeamUtils.checkFieldsNotNull;
|
||||
import static google.registry.beam.BeamUtils.extractField;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.reporting.billing.BillingModule;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.avro.generic.GenericRecord;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.beam.sdk.coders.AtomicCoder;
|
||||
import org.apache.beam.sdk.coders.Coder;
|
||||
import org.apache.beam.sdk.coders.StringUtf8Coder;
|
||||
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}.
|
||||
*
|
||||
* <p>This is a trivially serializable class that allows Beam to transform the results of a Bigquery
|
||||
* query into a standard Java representation, giving us the type guarantees and ease of manipulation
|
||||
* Bigquery lacks, while localizing any Bigquery-side failures to the {@link #parseFromRecord}
|
||||
* function.
|
||||
* <p>This is a trivially serializable class that allows Beam to transform the results of a Cloud
|
||||
* SQL query into a standard Java representation, giving us the type guarantees and ease of
|
||||
* manipulation Cloud SQL lacks.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract class BillingEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3593088371541450077L;
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
||||
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz");
|
||||
|
||||
/** The amount we multiply the price for sunrise creates. This is currently a 15% discount. */
|
||||
private static final double SUNRISE_DISCOUNT_PRICE_MODIFIER = 0.85;
|
||||
private static final Pattern SYNTHETIC_REGEX = Pattern.compile("SYNTHETIC", Pattern.LITERAL);
|
||||
|
||||
private static final ImmutableList<String> FIELD_NAMES =
|
||||
ImmutableList.of(
|
||||
|
@ -115,67 +106,7 @@ public abstract class BillingEvent implements Serializable {
|
|||
/** Returns a list of space-delimited flags associated with the event. */
|
||||
abstract String flags();
|
||||
|
||||
/**
|
||||
* Constructs a {@code BillingEvent} from a {@code SchemaAndRecord}.
|
||||
*
|
||||
* @see <a
|
||||
* href=http://avro.apache.org/docs/1.7.7/api/java/org/apache/avro/generic/GenericData.Record.html>
|
||||
* Apache AVRO GenericRecord</a>
|
||||
*/
|
||||
static BillingEvent parseFromRecord(SchemaAndRecord schemaAndRecord) {
|
||||
checkFieldsNotNull(FIELD_NAMES, schemaAndRecord);
|
||||
GenericRecord record = schemaAndRecord.getRecord();
|
||||
String flags = extractField(record, "flags");
|
||||
double amount = getDiscountedAmount(Double.parseDouble(extractField(record, "amount")), flags);
|
||||
return create(
|
||||
// We need to chain parsers off extractField because GenericRecord only returns
|
||||
// Objects, which contain a string representation of their underlying types.
|
||||
Long.parseLong(extractField(record, "id")),
|
||||
// Bigquery provides UNIX timestamps with microsecond precision.
|
||||
new DateTime(Long.parseLong(extractField(record, "billingTime")) / 1000, DateTimeZone.UTC),
|
||||
new DateTime(Long.parseLong(extractField(record, "eventTime")) / 1000, DateTimeZone.UTC),
|
||||
extractField(record, "registrarId"),
|
||||
extractField(record, "billingId"),
|
||||
extractField(record, "poNumber"),
|
||||
extractField(record, "tld"),
|
||||
extractField(record, "action"),
|
||||
extractField(record, "domain"),
|
||||
extractField(record, "repositoryId"),
|
||||
Integer.parseInt(extractField(record, "years")),
|
||||
extractField(record, "currency"),
|
||||
amount,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a discount to sunrise creates and anchor tenant creates if applicable.
|
||||
*
|
||||
* Currently sunrise creates are discounted 15% and anchor tenant creates are free for 2 years.
|
||||
* All anchor tenant creates are enforced to be 2 years in
|
||||
* {@link google.registry.flows.domain.DomainCreateFlow#verifyAnchorTenantValidPeriod}.
|
||||
*/
|
||||
private static double getDiscountedAmount(double amount, String flags) {
|
||||
// Apply a configurable discount to sunrise creates.
|
||||
if (flags.contains(Flag.SUNRISE.name())) {
|
||||
amount =
|
||||
Double.parseDouble(
|
||||
new DecimalFormat("#.##").format(amount * SUNRISE_DISCOUNT_PRICE_MODIFIER));
|
||||
}
|
||||
// Anchor tenant creates are free for the initial create. This is enforced to be a 2 year period
|
||||
// upon domain create.
|
||||
if (flags.contains(Flag.ANCHOR_TENANT.name())) {
|
||||
amount = 0;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a concrete {@code BillingEvent}.
|
||||
*
|
||||
* <p>This should only be used outside this class for testing- instances of {@code BillingEvent}
|
||||
* should otherwise come from {@link #parseFromRecord}.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
/** Creates a concrete {@link BillingEvent}. */
|
||||
static BillingEvent create(
|
||||
long id,
|
||||
DateTime billingTime,
|
||||
|
@ -209,7 +140,7 @@ public abstract class BillingEvent implements Serializable {
|
|||
}
|
||||
|
||||
static String getHeader() {
|
||||
return FIELD_NAMES.stream().collect(Collectors.joining(","));
|
||||
return String.join(",", FIELD_NAMES);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +173,7 @@ public abstract class BillingEvent implements Serializable {
|
|||
currency(),
|
||||
String.format("%.2f", amount()),
|
||||
// Strip out the 'synthetic' flag, which is internal only.
|
||||
flags().replace("SYNTHETIC", "").trim()));
|
||||
SYNTHETIC_REGEX.matcher(flags()).replaceAll("").trim()));
|
||||
}
|
||||
|
||||
/** Returns the grouping key for this {@code BillingEvent}, to generate the overall invoice. */
|
||||
|
@ -274,6 +205,8 @@ public abstract class BillingEvent implements Serializable {
|
|||
@AutoValue
|
||||
abstract static class InvoiceGroupingKey implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -151561764235256205L;
|
||||
|
||||
private static final ImmutableList<String> INVOICE_HEADERS =
|
||||
ImmutableList.of(
|
||||
"StartDate",
|
||||
|
@ -345,6 +278,8 @@ public abstract class BillingEvent implements Serializable {
|
|||
/** Coder that provides deterministic (de)serialization for {@code InvoiceGroupingKey}. */
|
||||
static class InvoiceGroupingKeyCoder extends AtomicCoder<InvoiceGroupingKey> {
|
||||
|
||||
private static final long serialVersionUID = 6680701524304107547L;
|
||||
|
||||
@Override
|
||||
public void encode(InvoiceGroupingKey value, OutputStream outStream) throws IOException {
|
||||
Coder<String> stringCoder = StringUtf8Coder.of();
|
||||
|
|
|
@ -24,16 +24,14 @@ import google.registry.beam.common.RegistryJpaIO.Read;
|
|||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey;
|
||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||
import google.registry.reporting.billing.BillingModule;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import google.registry.util.SqlTemplate;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.YearMonth;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -66,8 +64,7 @@ import org.joda.money.CurrencyUnit;
|
|||
*/
|
||||
public class InvoicingPipeline implements Serializable {
|
||||
|
||||
private static final DateTimeFormatter TIMESTAMP_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
|
||||
private static final long serialVersionUID = 5386330443625580081L;
|
||||
|
||||
private static final Pattern SQL_COMMENT_REGEX =
|
||||
Pattern.compile("^\\s*--.*\\n", Pattern.MULTILINE);
|
||||
|
@ -107,8 +104,7 @@ public class InvoicingPipeline implements Serializable {
|
|||
}
|
||||
|
||||
private static Optional<BillingEvent> parseRow(Object[] row) {
|
||||
google.registry.model.billing.BillingEvent.OneTime oneTime =
|
||||
(google.registry.model.billing.BillingEvent.OneTime) row[0];
|
||||
OneTime oneTime = (OneTime) row[0];
|
||||
Registrar registrar = (Registrar) row[1];
|
||||
CurrencyUnit currency = oneTime.getCost().getCurrencyUnit();
|
||||
if (!registrar.getBillingAccountMap().containsKey(currency)) {
|
||||
|
@ -140,6 +136,9 @@ public class InvoicingPipeline implements Serializable {
|
|||
/** Transform that converts a {@code BillingEvent} into an invoice CSV row. */
|
||||
private static class GenerateInvoiceRows
|
||||
extends PTransform<PCollection<BillingEvent>, PCollection<String>> {
|
||||
|
||||
private static final long serialVersionUID = -8090619008258393728L;
|
||||
|
||||
@Override
|
||||
public PCollection<String> expand(PCollection<BillingEvent> input) {
|
||||
return input
|
||||
|
@ -203,32 +202,13 @@ public class InvoicingPipeline implements Serializable {
|
|||
TextIO.sink().withHeader(BillingEvent.getHeader())));
|
||||
}
|
||||
|
||||
/** Create the Bigquery query for a given project and yearMonth at runtime. */
|
||||
static String makeQuery(String yearMonth, String projectId) {
|
||||
// Get the timestamp endpoints capturing the entire month with microsecond precision
|
||||
YearMonth reportingMonth = YearMonth.parse(yearMonth);
|
||||
LocalDateTime firstMoment = reportingMonth.atDay(1).atTime(LocalTime.MIDNIGHT);
|
||||
LocalDateTime lastMoment = reportingMonth.atEndOfMonth().atTime(LocalTime.MAX);
|
||||
// Construct the month's query by filling in the billing_events.sql template
|
||||
return SqlTemplate.create(getQueryFromFile(InvoicingPipeline.class, "billing_events.sql"))
|
||||
.put("FIRST_TIMESTAMP_OF_MONTH", firstMoment.format(TIMESTAMP_FORMATTER))
|
||||
.put("LAST_TIMESTAMP_OF_MONTH", lastMoment.format(TIMESTAMP_FORMATTER))
|
||||
.put("PROJECT_ID", projectId)
|
||||
.put("DATASTORE_EXPORT_DATA_SET", "latest_datastore_export")
|
||||
.put("ONETIME_TABLE", "OneTime")
|
||||
.put("REGISTRY_TABLE", "Registry")
|
||||
.put("REGISTRAR_TABLE", "Registrar")
|
||||
.put("CANCELLATION_TABLE", "Cancellation")
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Create the Cloud SQL query for a given yearMonth at runtime. */
|
||||
static String makeCloudSqlQuery(String yearMonth) {
|
||||
YearMonth endMonth = YearMonth.parse(yearMonth).plusMonths(1);
|
||||
String queryWithComments =
|
||||
SqlTemplate.create(
|
||||
getQueryFromFile(InvoicingPipeline.class, "cloud_sql_billing_events.sql"))
|
||||
.put("FIRST_TIMESTAMP_OF_MONTH", yearMonth.concat("-01"))
|
||||
.put("FIRST_TIMESTAMP_OF_MONTH", yearMonth + "-01")
|
||||
.put(
|
||||
"LAST_TIMESTAMP_OF_MONTH",
|
||||
String.format("%d-%d-01", endMonth.getYear(), endMonth.getMonthValue()))
|
||||
|
|
|
@ -333,9 +333,9 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||
DateTime registrationExpirationTime = leapSafeAddYears(now, years);
|
||||
String repoId = createDomainRepoId(allocateId(), registry.getTldStr());
|
||||
Key<DomainHistory> domainHistoryKey =
|
||||
Key.create(Key.create(DomainBase.class, repoId), DomainHistory.class, allocateId());
|
||||
historyBuilder.setId(domainHistoryKey.getId());
|
||||
long historyRevisionId = allocateId();
|
||||
DomainHistoryId domainHistoryId = new DomainHistoryId(repoId, historyRevisionId);
|
||||
historyBuilder.setId(historyRevisionId);
|
||||
// Bill for the create.
|
||||
BillingEvent.OneTime createBillingEvent =
|
||||
createOneTimeBillingEvent(
|
||||
|
@ -345,17 +345,17 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
isReserved(domainName, isSunriseCreate),
|
||||
years,
|
||||
feesAndCredits,
|
||||
domainHistoryKey,
|
||||
domainHistoryId,
|
||||
allocationToken,
|
||||
now);
|
||||
// Create a new autorenew billing event and poll message starting at the expiration time.
|
||||
BillingEvent.Recurring autorenewBillingEvent =
|
||||
createAutorenewBillingEvent(
|
||||
domainHistoryKey,
|
||||
domainHistoryId,
|
||||
registrationExpirationTime,
|
||||
getRenewalPriceInfo(isAnchorTenant, allocationToken, feesAndCredits));
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
createAutorenewPollMessage(domainHistoryKey, registrationExpirationTime);
|
||||
createAutorenewPollMessage(domainHistoryId, registrationExpirationTime);
|
||||
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
||||
entitiesToSave.add(createBillingEvent, autorenewBillingEvent, autorenewPollMessage);
|
||||
// Bill for EAP cost, if any.
|
||||
|
@ -552,7 +552,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
boolean isReserved,
|
||||
int years,
|
||||
FeesAndCredits feesAndCredits,
|
||||
Key<DomainHistory> domainHistoryKey,
|
||||
DomainHistoryId domainHistoryId,
|
||||
Optional<AllocationToken> allocationToken,
|
||||
DateTime now) {
|
||||
ImmutableSet.Builder<Flag> flagsBuilder = new ImmutableSet.Builder<>();
|
||||
|
@ -581,12 +581,12 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
? registry.getAnchorTenantAddGracePeriodLength()
|
||||
: registry.getAddGracePeriodLength()))
|
||||
.setFlags(flagsBuilder.build())
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(domainHistoryId)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Recurring createAutorenewBillingEvent(
|
||||
Key<DomainHistory> domainHistoryKey,
|
||||
DomainHistoryId domainHistoryId,
|
||||
DateTime registrationExpirationTime,
|
||||
RenewalPriceInfo renewalpriceInfo) {
|
||||
return new BillingEvent.Recurring.Builder()
|
||||
|
@ -596,21 +596,20 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
.setRegistrarId(registrarId)
|
||||
.setEventTime(registrationExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(domainHistoryId)
|
||||
.setRenewalPriceBehavior(renewalpriceInfo.renewalPriceBehavior())
|
||||
.setRenewalPrice(renewalpriceInfo.renewalPrice())
|
||||
.build();
|
||||
}
|
||||
|
||||
private Autorenew createAutorenewPollMessage(
|
||||
Key<DomainHistory> domainHistoryKey, DateTime registrationExpirationTime) {
|
||||
DomainHistoryId domainHistoryId, DateTime registrationExpirationTime) {
|
||||
return new PollMessage.Autorenew.Builder()
|
||||
.setTargetId(targetId)
|
||||
.setRegistrarId(registrarId)
|
||||
.setEventTime(registrationExpirationTime)
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.setDomainHistoryId(domainHistoryId)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -625,7 +624,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
|||
.setEventTime(createBillingEvent.getEventTime())
|
||||
.setBillingTime(createBillingEvent.getBillingTime())
|
||||
.setFlags(createBillingEvent.getFlags())
|
||||
.setParent(createBillingEvent.getParentKey())
|
||||
.setDomainHistoryId(createBillingEvent.getDomainHistoryId())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -233,7 +233,12 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
|||
// No cancellation is written if the grace period was not for a billable event.
|
||||
if (gracePeriod.hasBillingEvent()) {
|
||||
entitiesToSave.add(
|
||||
BillingEvent.Cancellation.forGracePeriod(gracePeriod, now, domainHistoryKey, targetId));
|
||||
BillingEvent.Cancellation.forGracePeriod(
|
||||
gracePeriod,
|
||||
now,
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()),
|
||||
targetId));
|
||||
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
||||
// Take the amount of amount of registration time being refunded off the expiration time.
|
||||
// This can be either add grace periods or renew grace periods.
|
||||
|
|
|
@ -210,7 +210,9 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
|||
.setEventTime(newExpirationTime)
|
||||
.setRenewalPrice(existingRecurringBillingEvent.getRenewalPrice().orElse(null))
|
||||
.setRenewalPriceBehavior(existingRecurringBillingEvent.getRenewalPriceBehavior())
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build();
|
||||
PollMessage.Autorenew newAutorenewPollMessage =
|
||||
newAutorenewPollMessage(existingDomain)
|
||||
|
@ -332,7 +334,8 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
|||
.setEventTime(now)
|
||||
.setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null))
|
||||
.setBillingTime(now.plus(Registry.get(tld).getRenewGracePeriodLength()))
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
|||
verifyRestoreAllowed(command, existingDomain, feeUpdate, feesAndCredits, now);
|
||||
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
||||
historyBuilder.setId(domainHistoryKey.getId());
|
||||
DomainHistoryId domainHistoryId =
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId());
|
||||
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
||||
|
||||
DateTime newExpirationTime =
|
||||
|
@ -158,17 +160,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
|||
// a year and bill for it immediately, with no grace period.
|
||||
if (isExpired) {
|
||||
entitiesToSave.add(
|
||||
createRenewBillingEvent(domainHistoryKey, feesAndCredits.getRenewCost(), now));
|
||||
createRenewBillingEvent(domainHistoryId, feesAndCredits.getRenewCost(), now));
|
||||
}
|
||||
// Always bill for the restore itself.
|
||||
entitiesToSave.add(
|
||||
createRestoreBillingEvent(domainHistoryKey, feesAndCredits.getRestoreCost(), now));
|
||||
createRestoreBillingEvent(domainHistoryId, feesAndCredits.getRestoreCost(), now));
|
||||
|
||||
BillingEvent.Recurring autorenewEvent =
|
||||
newAutorenewBillingEvent(existingDomain)
|
||||
.setEventTime(newExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(domainHistoryId)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
newAutorenewPollMessage(existingDomain)
|
||||
|
@ -259,19 +261,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
|||
}
|
||||
|
||||
private OneTime createRenewBillingEvent(
|
||||
Key<DomainHistory> domainHistoryKey, Money renewCost, DateTime now) {
|
||||
return prepareBillingEvent(domainHistoryKey, renewCost, now).setReason(Reason.RENEW).build();
|
||||
DomainHistoryId domainHistoryId, Money renewCost, DateTime now) {
|
||||
return prepareBillingEvent(domainHistoryId, renewCost, now).setReason(Reason.RENEW).build();
|
||||
}
|
||||
|
||||
private BillingEvent.OneTime createRestoreBillingEvent(
|
||||
Key<DomainHistory> domainHistoryKey, Money restoreCost, DateTime now) {
|
||||
return prepareBillingEvent(domainHistoryKey, restoreCost, now)
|
||||
.setReason(Reason.RESTORE)
|
||||
.build();
|
||||
DomainHistoryId domainHistoryId, Money restoreCost, DateTime now) {
|
||||
return prepareBillingEvent(domainHistoryId, restoreCost, now).setReason(Reason.RESTORE).build();
|
||||
}
|
||||
|
||||
private OneTime.Builder prepareBillingEvent(
|
||||
Key<DomainHistory> domainHistoryKey, Money cost, DateTime now) {
|
||||
DomainHistoryId domainHistoryId, Money cost, DateTime now) {
|
||||
return new BillingEvent.OneTime.Builder()
|
||||
.setTargetId(targetId)
|
||||
.setRegistrarId(registrarId)
|
||||
|
@ -279,7 +279,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
|||
.setBillingTime(now)
|
||||
.setPeriodYears(1)
|
||||
.setCost(cost)
|
||||
.setParent(domainHistoryKey);
|
||||
.setDomainHistoryId(domainHistoryId);
|
||||
}
|
||||
|
||||
private static ImmutableList<FeeTransformResponseExtension> createResponseExtensions(
|
||||
|
|
|
@ -123,7 +123,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
|||
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
||||
historyBuilder.setId(domainHistoryKey.getId());
|
||||
Optional<BillingEvent.OneTime> billingEvent =
|
||||
(transferData.getTransferPeriod().getValue() == 0)
|
||||
transferData.getTransferPeriod().getValue() == 0
|
||||
? Optional.empty()
|
||||
: Optional.of(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
|
@ -134,7 +134,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
|||
.setCost(getDomainRenewCost(targetId, transferData.getTransferRequestTime(), 1))
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build());
|
||||
ImmutableList.Builder<ImmutableObject> entitiesToSave = new ImmutableList.Builder<>();
|
||||
// If we are within an autorenew grace period, cancel the autorenew billing event and don't
|
||||
|
@ -150,7 +152,11 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
|||
if (billingEvent.isPresent()) {
|
||||
entitiesToSave.add(
|
||||
BillingEvent.Cancellation.forGracePeriod(
|
||||
autorenewGrace, now, domainHistoryKey, targetId));
|
||||
autorenewGrace,
|
||||
now,
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()),
|
||||
targetId));
|
||||
}
|
||||
}
|
||||
// Close the old autorenew event and poll message at the transfer time (aka now). This may end
|
||||
|
@ -167,7 +173,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
|||
.setRegistrarId(gainingRegistrarId)
|
||||
.setEventTime(newExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build();
|
||||
// Create a new autorenew poll message.
|
||||
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
||||
|
|
|
@ -250,7 +250,8 @@ public final class DomainTransferUtils {
|
|||
.setRegistrarId(gainingRegistrarId)
|
||||
.setEventTime(serverApproveNewExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -285,7 +286,11 @@ public final class DomainTransferUtils {
|
|||
if (autorenewGracePeriod != null && transferCost.isPresent()) {
|
||||
return Optional.of(
|
||||
BillingEvent.Cancellation.forGracePeriod(
|
||||
autorenewGracePeriod, now, domainHistoryKey, targetId)
|
||||
autorenewGracePeriod,
|
||||
now,
|
||||
new DomainHistoryId(
|
||||
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()),
|
||||
targetId)
|
||||
.asBuilder()
|
||||
.setEventTime(automaticTransferTime)
|
||||
.build());
|
||||
|
@ -308,7 +313,8 @@ public final class DomainTransferUtils {
|
|||
.setPeriodYears(1)
|
||||
.setEventTime(automaticTransferTime)
|
||||
.setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength()))
|
||||
.setParent(domainHistoryKey)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
|
|||
.setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost())
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import static google.registry.model.IdService.allocateId;
|
|||
import static google.registry.model.ModelUtils.getAllFields;
|
||||
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import google.registry.model.annotations.OfyIdAllocation;
|
||||
import google.registry.util.TypeUtils.TypeInstantiator;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Optional;
|
||||
|
@ -59,7 +60,10 @@ public interface Buildable {
|
|||
// any entity it has one and only one @Id field in its class hierarchy.
|
||||
Field idField =
|
||||
getAllFields(instance.getClass()).values().stream()
|
||||
.filter(field -> field.isAnnotationPresent(Id.class))
|
||||
.filter(
|
||||
field ->
|
||||
field.isAnnotationPresent(Id.class)
|
||||
|| field.isAnnotationPresent(OfyIdAllocation.class))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (idField != null
|
||||
|
|
|
@ -16,7 +16,6 @@ package google.registry.model;
|
|||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.annotations.DeleteAfterMigration;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.common.GaeUserIdConverter;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
|
@ -44,10 +43,6 @@ public final class EntityClasses {
|
|||
public static final ImmutableSet<Class<? extends ImmutableObject>> ALL_CLASSES =
|
||||
ImmutableSet.of(
|
||||
AllocationToken.class,
|
||||
BillingEvent.Cancellation.class,
|
||||
BillingEvent.Modification.class,
|
||||
BillingEvent.OneTime.class,
|
||||
BillingEvent.Recurring.class,
|
||||
ContactHistory.class,
|
||||
ContactResource.class,
|
||||
DomainBase.class,
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 google.registry.model.annotations;
|
||||
|
||||
import google.registry.model.IdService;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to indicate an ID field that needs to be allocated by Ofy.
|
||||
*
|
||||
* <p>This annotation is only used for the field of a {@link google.registry.model.Buildable} class
|
||||
* that was previously annotated by both Ofy's and JPA's {@code @Id} annotations, of which the Ofy
|
||||
* annotation has been removed. The field still needs to be allocated automatically by the builder,
|
||||
* via the {@link IdService#allocateId()}.
|
||||
*
|
||||
* <p>It should be removed after we switch to using SQL to directly allocate IDs.
|
||||
*/
|
||||
@DeleteAfterMigration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface OfyIdAllocation {}
|
|
@ -18,7 +18,6 @@ import static com.google.common.base.MoreObjects.firstNonNull;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.forceEmptyToNull;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
|
@ -26,31 +25,21 @@ import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import com.googlecode.objectify.condition.IfNull;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.OfyIdAllocation;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.common.TimeOfYear;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
|
||||
import google.registry.persistence.BillingVKey.BillingEventVKey;
|
||||
import google.registry.persistence.BillingVKey.BillingRecurrenceVKey;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithLongVKey;
|
||||
import google.registry.persistence.converter.JodaMoneyType;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -58,11 +47,13 @@ import javax.persistence.AttributeOverride;
|
|||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Table;
|
||||
import org.hibernate.annotations.Columns;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.joda.money.Money;
|
||||
|
@ -76,7 +67,7 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
/** The reason for the bill, which maps 1:1 to skus in go/registry-billing-skus. */
|
||||
public enum Reason {
|
||||
CREATE(true),
|
||||
@Deprecated // TODO(b/31676071): remove this legacy value once old data is cleaned up.
|
||||
@Deprecated // DO NOT USE THIS REASON. IT REMAINS BECAUSE OF HISTORICAL DATA. SEE b/31676071.
|
||||
ERROR(false),
|
||||
FEE_EARLY_ACCESS(true),
|
||||
RENEW(true),
|
||||
|
@ -105,9 +96,7 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
ALLOCATION,
|
||||
ANCHOR_TENANT,
|
||||
AUTO_RENEW,
|
||||
/**
|
||||
* Landrush billing events are historical only and are no longer created.
|
||||
*/
|
||||
/** Landrush billing events are historical only and are no longer created. */
|
||||
LANDRUSH,
|
||||
/**
|
||||
* This flag is used on create {@link OneTime} billing events for domains that were reserved.
|
||||
|
@ -122,7 +111,7 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* This flag will be added to any {@link OneTime} events that are created via, e.g., an
|
||||
* automated process to expand {@link Recurring} events.
|
||||
*/
|
||||
SYNTHETIC;
|
||||
SYNTHETIC
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,37 +138,30 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
*/
|
||||
NONPREMIUM,
|
||||
/**
|
||||
* This indicates that the renewalPrice in {@link BillingEvent.Recurring} will be used for
|
||||
* domain renewal.
|
||||
* This indicates that the renewalPrice in {@link Recurring} will be used for domain renewal.
|
||||
*
|
||||
* <p>The renewalPrice has a non-null value iff the price behavior is set to "SPECIFIED". This
|
||||
* behavior is used with internal registrations.
|
||||
*/
|
||||
SPECIFIED;
|
||||
SPECIFIED
|
||||
}
|
||||
|
||||
/** Entity id. */
|
||||
@Id @javax.persistence.Id Long id;
|
||||
|
||||
@Parent @DoNotHydrate @Transient Key<DomainHistory> parent;
|
||||
@OfyIdAllocation @Id Long id;
|
||||
|
||||
/** The registrar to bill. */
|
||||
@Index
|
||||
@Column(name = "registrarId", nullable = false)
|
||||
String clientId;
|
||||
|
||||
/** Revision id of the entry in DomainHistory table that ths bill belongs to. */
|
||||
@Ignore
|
||||
@Column(nullable = false)
|
||||
Long domainHistoryRevisionId;
|
||||
|
||||
/** ID of the EPP resource that the bill is for. */
|
||||
@Ignore
|
||||
@Column(nullable = false)
|
||||
String domainRepoId;
|
||||
|
||||
/** When this event was created. For recurring events, this is also the recurrence start time. */
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
DateTime eventTime;
|
||||
|
||||
|
@ -192,17 +174,7 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
@Column(name = "domain_name", nullable = false)
|
||||
String targetId;
|
||||
|
||||
@Nullable
|
||||
Set<Flag> flags;
|
||||
|
||||
@PostLoad
|
||||
void postLoad() {
|
||||
parent =
|
||||
Key.create(
|
||||
Key.create(DomainBase.class, domainRepoId),
|
||||
DomainHistory.class,
|
||||
domainHistoryRevisionId);
|
||||
}
|
||||
@Nullable Set<Flag> flags;
|
||||
|
||||
public String getRegistrarId() {
|
||||
return clientId;
|
||||
|
@ -232,8 +204,8 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
return targetId;
|
||||
}
|
||||
|
||||
public Key<DomainHistory> getParentKey() {
|
||||
return parent;
|
||||
public DomainHistoryId getDomainHistoryId() {
|
||||
return new DomainHistoryId(domainRepoId, domainHistoryRevisionId);
|
||||
}
|
||||
|
||||
public ImmutableSet<Flag> getFlags() {
|
||||
|
@ -269,16 +241,6 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setDomainHistoryRevisionId(long domainHistoryRevisionId) {
|
||||
getInstance().domainHistoryRevisionId = domainHistoryRevisionId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setDomainRepoId(String domainRepoId) {
|
||||
getInstance().domainRepoId = domainRepoId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setEventTime(DateTime eventTime) {
|
||||
getInstance().eventTime = eventTime;
|
||||
return thisCastToDerived();
|
||||
|
@ -294,14 +256,14 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setParent(DomainHistory parent) {
|
||||
getInstance().parent = Key.create(parent);
|
||||
public B setDomainHistoryId(DomainHistoryId domainHistoryId) {
|
||||
getInstance().domainHistoryRevisionId = domainHistoryId.getId();
|
||||
getInstance().domainRepoId = domainHistoryId.getDomainRepoId();
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setParent(Key<DomainHistory> parentKey) {
|
||||
getInstance().parent = parentKey;
|
||||
return thisCastToDerived();
|
||||
public B setDomainHistory(DomainHistory domainHistory) {
|
||||
return setDomainHistoryId(domainHistory.getDomainHistoryId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -311,29 +273,23 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
checkNotNull(instance.clientId, "Registrar ID must be set");
|
||||
checkNotNull(instance.eventTime, "Event time must be set");
|
||||
checkNotNull(instance.targetId, "Target ID must be set");
|
||||
checkNotNull(instance.parent, "Parent must be set");
|
||||
checkNotNull(instance.parent.getParent(), "parent.getParent() must be set");
|
||||
checkNotNull(
|
||||
instance.parent.getParent().getName(), "parent.getParent().getName() must be set");
|
||||
instance.domainHistoryRevisionId = instance.parent.getId();
|
||||
instance.domainRepoId = instance.parent.getParent().getName();
|
||||
checkNotNull(instance.domainHistoryRevisionId, "Domain History Revision ID must be set");
|
||||
checkNotNull(instance.domainRepoId, "Domain Repo ID must be set");
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** A one-time billable event. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingEvent")
|
||||
@javax.persistence.Table(
|
||||
@Entity(name = "BillingEvent")
|
||||
@Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrarId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "billingTime"),
|
||||
@javax.persistence.Index(columnList = "syntheticCreationTime"),
|
||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
||||
@javax.persistence.Index(columnList = "allocationToken"),
|
||||
@javax.persistence.Index(columnList = "cancellation_matching_billing_recurrence_id")
|
||||
@Index(columnList = "registrarId"),
|
||||
@Index(columnList = "eventTime"),
|
||||
@Index(columnList = "billingTime"),
|
||||
@Index(columnList = "syntheticCreationTime"),
|
||||
@Index(columnList = "domainRepoId"),
|
||||
@Index(columnList = "allocationToken"),
|
||||
@Index(columnList = "cancellation_matching_billing_recurrence_id")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_event_id"))
|
||||
@WithLongVKey(compositeKey = true)
|
||||
|
@ -345,15 +301,13 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
Money cost;
|
||||
|
||||
/** When the cost should be billed. */
|
||||
@Index
|
||||
DateTime billingTime;
|
||||
|
||||
/**
|
||||
* The period in years of the action being billed for, if applicable, otherwise null. Used for
|
||||
* financial reporting.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
Integer periodYears = null;
|
||||
Integer periodYears;
|
||||
|
||||
/**
|
||||
* For {@link Flag#SYNTHETIC} events, when this event was persisted to Datastore (i.e. the
|
||||
|
@ -361,11 +315,10 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* needs to be undone, a query on this field will return the complete set of potentially bad
|
||||
* events.
|
||||
*/
|
||||
@Index
|
||||
DateTime syntheticCreationTime;
|
||||
|
||||
/**
|
||||
* For {@link Flag#SYNTHETIC} events, a {@link Key} to the {@link Recurring} from which this
|
||||
* For {@link Flag#SYNTHETIC} events, a {@link VKey} to the {@link Recurring} from which this
|
||||
* {@link OneTime} was created. This is needed in order to properly match billing events against
|
||||
* {@link Cancellation}s.
|
||||
*/
|
||||
|
@ -373,20 +326,17 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
VKey<Recurring> cancellationMatchingBillingEvent;
|
||||
|
||||
/**
|
||||
* For {@link Flag#SYNTHETIC} events, the {@link DomainHistory} revision ID of the the {@link
|
||||
* For {@link Flag#SYNTHETIC} events, the {@link DomainHistory} revision ID of the {@link
|
||||
* Recurring} from which this {@link OneTime} was created. This is needed in order to recreate
|
||||
* the {@link VKey} when reading from SQL.
|
||||
*/
|
||||
@Ignore
|
||||
@Column(name = "recurrence_history_revision_id")
|
||||
Long recurringEventHistoryRevisionId;
|
||||
|
||||
/**
|
||||
* The {@link AllocationToken} used in the creation of this event, or null if one was not used.
|
||||
*/
|
||||
@Index
|
||||
@Nullable
|
||||
VKey<AllocationToken> allocationToken;
|
||||
@Nullable VKey<AllocationToken> allocationToken;
|
||||
|
||||
public Money getCost() {
|
||||
return cost;
|
||||
|
@ -418,11 +368,11 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
|
||||
@Override
|
||||
public VKey<OneTime> createVKey() {
|
||||
return VKey.create(OneTime.class, getId(), Key.create(this));
|
||||
return createVKey(getId());
|
||||
}
|
||||
|
||||
public static VKey<OneTime> createVKey(Key<OneTime> key) {
|
||||
return VKey.create(OneTime.class, key.getId(), key);
|
||||
public static VKey<OneTime> createVKey(long id) {
|
||||
return VKey.createSql(OneTime.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -430,19 +380,6 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
void postLoad() {
|
||||
super.postLoad();
|
||||
if (cancellationMatchingBillingEvent != null) {
|
||||
cancellationMatchingBillingEvent =
|
||||
cancellationMatchingBillingEvent.restoreOfy(
|
||||
DomainBase.class,
|
||||
domainRepoId,
|
||||
DomainHistory.class,
|
||||
recurringEventHistoryRevisionId);
|
||||
}
|
||||
}
|
||||
|
||||
/** A builder for {@link OneTime} since it is immutable. */
|
||||
public static class Builder extends BillingEvent.Builder<OneTime, Builder> {
|
||||
|
||||
|
@ -475,11 +412,11 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
}
|
||||
|
||||
public Builder setCancellationMatchingBillingEvent(
|
||||
VKey<Recurring> cancellationMatchingBillingEvent) {
|
||||
getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent;
|
||||
// getOfyKey() here is safe, recurring billing event VKeys have a valid ofy key.
|
||||
Recurring cancellationMatchingBillingEvent) {
|
||||
getInstance().cancellationMatchingBillingEvent =
|
||||
cancellationMatchingBillingEvent.createVKey();
|
||||
getInstance().recurringEventHistoryRevisionId =
|
||||
cancellationMatchingBillingEvent.getOfyKey().getParent().getId();
|
||||
cancellationMatchingBillingEvent.getDomainHistoryRevisionId();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -511,12 +448,6 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
== (instance.cancellationMatchingBillingEvent != null),
|
||||
"Cancellation matching billing event must be set if and only if the SYNTHETIC flag "
|
||||
+ "is set.");
|
||||
// getOfyKey() here is safe, billing event VKeys have a valid ofy key.
|
||||
checkState(
|
||||
!instance.getFlags().contains(Flag.SYNTHETIC)
|
||||
|| (instance.cancellationMatchingBillingEvent.getOfyKey().getParent().getId()
|
||||
== instance.recurringEventHistoryRevisionId),
|
||||
"Cancellation matching billing event and its history revision ID does not match.");
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
|
@ -526,29 +457,26 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* A recurring billable event.
|
||||
*
|
||||
* <p>Unlike {@link OneTime} events, these do not store an explicit cost, since the cost of the
|
||||
* recurring event might change and each time we bill for it we need to bill at the current cost,
|
||||
* recurring event might change and each time we bill for it, we need to bill at the current cost,
|
||||
* not the value that was in use at the time the recurrence was created.
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingRecurrence")
|
||||
@javax.persistence.Table(
|
||||
@Entity(name = "BillingRecurrence")
|
||||
@Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrarId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
||||
@javax.persistence.Index(columnList = "recurrenceEndTime"),
|
||||
@javax.persistence.Index(columnList = "recurrence_time_of_year")
|
||||
@Index(columnList = "registrarId"),
|
||||
@Index(columnList = "eventTime"),
|
||||
@Index(columnList = "domainRepoId"),
|
||||
@Index(columnList = "recurrenceEndTime"),
|
||||
@Index(columnList = "recurrence_time_of_year")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id"))
|
||||
@WithLongVKey(compositeKey = true)
|
||||
public static class Recurring extends BillingEvent {
|
||||
|
||||
/**
|
||||
* The billing event recurs every year between {@link #eventTime} and this time on the
|
||||
* [month, day, time] specified in {@link #recurrenceTimeOfYear}.
|
||||
* The billing event recurs every year between {@link #eventTime} and this time on the [month,
|
||||
* day, time] specified in {@link #recurrenceTimeOfYear}.
|
||||
*/
|
||||
@Index
|
||||
DateTime recurrenceEndTime;
|
||||
|
||||
/**
|
||||
|
@ -564,11 +492,9 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* (same day of year, which can be 365 or 366 days later) which is what {@link TimeOfYear} can
|
||||
* model, whereas the billing time is a fixed {@link org.joda.time.Duration} later.
|
||||
*/
|
||||
@Index
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year"))
|
||||
})
|
||||
@AttributeOverrides(
|
||||
@AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year")))
|
||||
TimeOfYear recurrenceTimeOfYear;
|
||||
|
||||
/**
|
||||
|
@ -605,11 +531,11 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
|
||||
@Override
|
||||
public VKey<Recurring> createVKey() {
|
||||
return VKey.create(Recurring.class, getId(), Key.create(this));
|
||||
return createVKey(getId());
|
||||
}
|
||||
|
||||
public static VKey<Recurring> createVKey(Key<Recurring> key) {
|
||||
return VKey.create(Recurring.class, key.getId(), key);
|
||||
public static VKey<Recurring> createVKey(Long id) {
|
||||
return VKey.createSql(Recurring.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -647,8 +573,8 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
checkNotNull(instance.eventTime);
|
||||
checkNotNull(instance.reason);
|
||||
checkArgument(
|
||||
(instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED)
|
||||
^ (instance.renewalPrice == null),
|
||||
instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED
|
||||
^ instance.renewalPrice == null,
|
||||
"Renewal price can have a value if and only if the renewal price behavior is"
|
||||
+ " SPECIFIED");
|
||||
instance.recurrenceTimeOfYear = TimeOfYear.fromDateTime(instance.eventTime);
|
||||
|
@ -666,47 +592,45 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* preserve the immutability of billing events.
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingCancellation")
|
||||
@javax.persistence.Table(
|
||||
@Entity(name = "BillingCancellation")
|
||||
@Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrarId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
||||
@javax.persistence.Index(columnList = "billingTime"),
|
||||
@javax.persistence.Index(columnList = "billing_event_id"),
|
||||
@javax.persistence.Index(columnList = "billing_recurrence_id")
|
||||
@Index(columnList = "registrarId"),
|
||||
@Index(columnList = "eventTime"),
|
||||
@Index(columnList = "domainRepoId"),
|
||||
@Index(columnList = "billingTime"),
|
||||
@Index(columnList = "billing_event_id"),
|
||||
@Index(columnList = "billing_recurrence_id")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id"))
|
||||
@WithLongVKey(compositeKey = true)
|
||||
public static class Cancellation extends BillingEvent {
|
||||
|
||||
/** The billing time of the charge that is being cancelled. */
|
||||
@Index
|
||||
DateTime billingTime;
|
||||
|
||||
/**
|
||||
* The one-time billing event to cancel, or null for autorenew cancellations.
|
||||
*
|
||||
* <p>Although the type is {@link Key} the name "ref" is preserved for historical reasons.
|
||||
* <p>Although the type is {@link VKey} the name "ref" is preserved for historical reasons.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
BillingEventVKey refOneTime = null;
|
||||
@Column(name = "billing_event_id")
|
||||
VKey<OneTime> refOneTime;
|
||||
|
||||
/**
|
||||
* The recurring billing event to cancel, or null for non-autorenew cancellations.
|
||||
*
|
||||
* <p>Although the type is {@link Key} the name "ref" is preserved for historical reasons.
|
||||
* <p>Although the type is {@link VKey} the name "ref" is preserved for historical reasons.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
BillingRecurrenceVKey refRecurring = null;
|
||||
@Column(name = "billing_recurrence_id")
|
||||
VKey<Recurring> refRecurring;
|
||||
|
||||
public DateTime getBillingTime() {
|
||||
return billingTime;
|
||||
}
|
||||
|
||||
public VKey<? extends BillingEvent> getEventKey() {
|
||||
return firstNonNull(refOneTime, refRecurring).createVKey();
|
||||
return firstNonNull(refOneTime, refRecurring);
|
||||
}
|
||||
|
||||
/** The mapping from billable grace period types to originating billing event reasons. */
|
||||
|
@ -723,22 +647,23 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
* using the supplied targetId and deriving other metadata (clientId, billing time, and the
|
||||
* cancellation reason) from the grace period.
|
||||
*/
|
||||
public static BillingEvent.Cancellation forGracePeriod(
|
||||
public static Cancellation forGracePeriod(
|
||||
GracePeriod gracePeriod,
|
||||
DateTime eventTime,
|
||||
Key<DomainHistory> domainHistoryKey,
|
||||
DomainHistoryId domainHistoryId,
|
||||
String targetId) {
|
||||
checkArgument(gracePeriod.hasBillingEvent(),
|
||||
checkArgument(
|
||||
gracePeriod.hasBillingEvent(),
|
||||
"Cannot create cancellation for grace period without billing event");
|
||||
BillingEvent.Cancellation.Builder builder =
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
Builder builder =
|
||||
new Builder()
|
||||
.setReason(checkNotNull(GRACE_PERIOD_TO_REASON.get(gracePeriod.getType())))
|
||||
.setTargetId(targetId)
|
||||
.setRegistrarId(gracePeriod.getRegistrarId())
|
||||
.setEventTime(eventTime)
|
||||
// The charge being cancelled will take place at the grace period's expiration time.
|
||||
.setBillingTime(gracePeriod.getExpirationTime())
|
||||
.setParent(domainHistoryKey);
|
||||
.setDomainHistoryId(domainHistoryId);
|
||||
// Set the grace period's billing event using the appropriate Cancellation builder method.
|
||||
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
||||
builder.setOneTimeEventKey(gracePeriod.getOneTimeBillingEvent());
|
||||
|
@ -750,11 +675,11 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
|
||||
@Override
|
||||
public VKey<Cancellation> createVKey() {
|
||||
return VKey.create(Cancellation.class, getId(), Key.create(this));
|
||||
return createVKey(getId());
|
||||
}
|
||||
|
||||
public static VKey<Cancellation> createVKey(Key<Cancellation> key) {
|
||||
return VKey.create(Cancellation.class, key.getId(), key);
|
||||
public static VKey<Cancellation> createVKey(long id) {
|
||||
return VKey.createSql(Cancellation.class, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -776,13 +701,13 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setOneTimeEventKey(VKey<BillingEvent.OneTime> eventKey) {
|
||||
getInstance().refOneTime = BillingEventVKey.create(eventKey);
|
||||
public Builder setOneTimeEventKey(VKey<OneTime> eventKey) {
|
||||
getInstance().refOneTime = eventKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRecurringEventKey(VKey<BillingEvent.Recurring> eventKey) {
|
||||
getInstance().refRecurring = BillingRecurrenceVKey.create(eventKey);
|
||||
public Builder setRecurringEventKey(VKey<Recurring> eventKey) {
|
||||
getInstance().refRecurring = eventKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -791,115 +716,11 @@ public abstract class BillingEvent extends ImmutableObject
|
|||
Cancellation instance = getInstance();
|
||||
checkNotNull(instance.billingTime, "Must set billing time");
|
||||
checkNotNull(instance.reason, "Must set reason");
|
||||
checkState((instance.refOneTime == null) != (instance.refRecurring == null),
|
||||
checkState(
|
||||
(instance.refOneTime == null) != (instance.refRecurring == null),
|
||||
"Cancellations must have exactly one billing event key set");
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** An event representing a modification of an existing one-time billing event. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@WithLongVKey(compositeKey = true)
|
||||
public static class Modification extends BillingEvent {
|
||||
|
||||
/** The change in cost that should be applied to the original billing event. */
|
||||
Money cost;
|
||||
|
||||
/** The one-time billing event to modify. */
|
||||
Key<BillingEvent.OneTime> eventRef;
|
||||
|
||||
/**
|
||||
* Description of the modification (and presumably why it was issued). This text may appear as a
|
||||
* line item on an invoice or report about such modifications.
|
||||
*/
|
||||
String description;
|
||||
|
||||
public Money getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public Key<BillingEvent.OneTime> getEventKey() {
|
||||
return eventRef;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VKey<Modification> createVKey() {
|
||||
return VKey.create(Modification.class, getId(), Key.create(this));
|
||||
}
|
||||
|
||||
public static VKey<Modification> createVKey(Key<Modification> key) {
|
||||
return VKey.create(Modification.class, key.getId(), key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Modification billing event which is a refund of the given OneTime billing event
|
||||
* and that is parented off the given HistoryEntry.
|
||||
*
|
||||
* <p>Note that this method may appear to be unused most of the time, but it is kept around
|
||||
* because it is needed by one-off scrap tools that need to make billing adjustments.
|
||||
*/
|
||||
public static Modification createRefundFor(
|
||||
OneTime billingEvent, DomainHistory historyEntry, String description) {
|
||||
return new Builder()
|
||||
.setRegistrarId(billingEvent.getRegistrarId())
|
||||
.setFlags(billingEvent.getFlags())
|
||||
.setReason(billingEvent.getReason())
|
||||
.setTargetId(billingEvent.getTargetId())
|
||||
.setEventKey(Key.create(billingEvent))
|
||||
.setEventTime(historyEntry.getModificationTime())
|
||||
.setDescription(description)
|
||||
.setCost(billingEvent.getCost().negated())
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
}
|
||||
|
||||
/** A builder for {@link Modification} since it is immutable. */
|
||||
public static class Builder extends BillingEvent.Builder<Modification, Builder> {
|
||||
|
||||
public Builder() {}
|
||||
|
||||
private Builder(Modification instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
public Builder setCost(Money cost) {
|
||||
getInstance().cost = cost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setEventKey(Key<BillingEvent.OneTime> eventKey) {
|
||||
getInstance().eventRef = eventKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDescription(String description) {
|
||||
getInstance().description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modification build() {
|
||||
Modification instance = getInstance();
|
||||
checkNotNull(instance.reason);
|
||||
checkNotNull(instance.eventRef);
|
||||
BillingEvent.OneTime billingEvent =
|
||||
tm().transact(() -> tm().loadByKey(VKey.from(instance.eventRef)));
|
||||
checkArgument(
|
||||
Objects.equals(instance.cost.getCurrencyUnit(), billingEvent.cost.getCurrencyUnit()),
|
||||
"Referenced billing event is in a different currency");
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,12 +53,16 @@ public class ClassPathManager {
|
|||
}
|
||||
|
||||
public static <T> Class<T> getClass(String className) {
|
||||
checkArgument(CLASS_REGISTRY.containsKey(className), "Class not found in class registry");
|
||||
checkArgument(
|
||||
CLASS_REGISTRY.containsKey(className), "Class %s not found in class registry", className);
|
||||
return (Class<T>) CLASS_REGISTRY.get(className);
|
||||
}
|
||||
|
||||
public static <T> String getClassName(Class<T> clazz) {
|
||||
checkArgument(CLASS_NAME_REGISTRY.containsKey(clazz), "Class not found in class name registry");
|
||||
checkArgument(
|
||||
CLASS_NAME_REGISTRY.containsKey(clazz),
|
||||
"Class %s not found in class name registry",
|
||||
clazz.getSimpleName());
|
||||
return CLASS_NAME_REGISTRY.get(clazz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ public class DomainContent extends EppResource
|
|||
* should be created, and this field should be updated to point to the new one.
|
||||
*/
|
||||
@Column(name = "billing_recurrence_id")
|
||||
@Ignore
|
||||
VKey<BillingEvent.Recurring> autorenewBillingEvent;
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,6 +65,7 @@ public class GracePeriodBase extends ImmutableObject implements UnsafeSerializab
|
|||
// NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections.
|
||||
@Access(AccessType.FIELD)
|
||||
@Column(name = "billing_event_id")
|
||||
@Ignore
|
||||
VKey<BillingEvent.OneTime> billingEventOneTime = null;
|
||||
|
||||
/**
|
||||
|
@ -74,6 +75,7 @@ public class GracePeriodBase extends ImmutableObject implements UnsafeSerializab
|
|||
// NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections.
|
||||
@Access(AccessType.FIELD)
|
||||
@Column(name = "billing_recurrence_id")
|
||||
@Ignore
|
||||
VKey<BillingEvent.Recurring> billingEventRecurring = null;
|
||||
|
||||
public long getGracePeriodId() {
|
||||
|
|
|
@ -168,6 +168,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
|||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "renewalPriceBehavior", nullable = false)
|
||||
@Ignore
|
||||
RenewalPriceBehavior renewalPriceBehavior = RenewalPriceBehavior.DEFAULT;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
|
|
|
@ -85,8 +85,8 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
|
|||
* <p>This field should be null if there is not currently a pending transfer or if the object
|
||||
* being transferred is not a domain.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@Column(name = "transfer_billing_event_id")
|
||||
@Ignore
|
||||
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
|
||||
|
||||
/**
|
||||
|
@ -95,8 +95,8 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
|
|||
* <p>This field should be null if there is not currently a pending transfer or if the object
|
||||
* being transferred is not a domain.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@Column(name = "transfer_billing_recurrence_id")
|
||||
@Ignore
|
||||
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,8 +21,6 @@ import com.google.appengine.api.datastore.Key;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.persistence.BillingVKey.BillingEventVKey;
|
||||
import google.registry.persistence.BillingVKey.BillingRecurrenceVKey;
|
||||
import google.registry.persistence.DomainHistoryVKey;
|
||||
import google.registry.persistence.EppHistoryVKey;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
@ -45,8 +43,7 @@ public class EppHistoryVKeyTranslatorFactory
|
|||
// key, e.g. the map key for ContactPollMessageVKey is "ContactResource/HistoryEntry/PollMessage".
|
||||
@VisibleForTesting
|
||||
static final ImmutableMap<String, Class<? extends EppHistoryVKey>> kindPathToVKeyClass =
|
||||
ImmutableSet.of(DomainHistoryVKey.class, BillingEventVKey.class, BillingRecurrenceVKey.class)
|
||||
.stream()
|
||||
ImmutableSet.of(DomainHistoryVKey.class).stream()
|
||||
.collect(toImmutableMap(EppHistoryVKeyTranslatorFactory::getKindPath, identity()));
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 google.registry.persistence;
|
||||
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import java.io.Serializable;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
/** Base class for {@link BillingEvent}'s {@link VKey}. */
|
||||
@MappedSuperclass
|
||||
public abstract class BillingVKey<K> extends EppHistoryVKey<K, DomainBase> {
|
||||
Long billingId;
|
||||
|
||||
// Hibernate requires a default constructor.
|
||||
BillingVKey() {}
|
||||
|
||||
BillingVKey(String repoId, long historyRevisionId, long billingId) {
|
||||
super(repoId, historyRevisionId);
|
||||
this.billingId = billingId;
|
||||
}
|
||||
|
||||
Key<HistoryEntry> createHistoryEntryKey() {
|
||||
return Key.create(Key.create(DomainBase.class, repoId), HistoryEntry.class, historyRevisionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable createSqlKey() {
|
||||
return billingId;
|
||||
}
|
||||
|
||||
/** VKey class for {@link BillingEvent.OneTime} that belongs to a {@link DomainBase} entity. */
|
||||
@Embeddable
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "repoId", column = @Column(name = "billing_event_domain_repo_id")),
|
||||
@AttributeOverride(
|
||||
name = "historyRevisionId",
|
||||
column = @Column(name = "billing_event_history_id")),
|
||||
@AttributeOverride(name = "billingId", column = @Column(name = "billing_event_id"))
|
||||
})
|
||||
public static class BillingEventVKey extends BillingVKey<OneTime> {
|
||||
|
||||
// Hibernate requires this default constructor
|
||||
private BillingEventVKey() {}
|
||||
|
||||
private BillingEventVKey(String repoId, long historyRevisionId, long billingEventId) {
|
||||
super(repoId, historyRevisionId, billingEventId);
|
||||
}
|
||||
|
||||
/** Creates a {@link BillingEventVKey} instance from the given {@link Key} instance. */
|
||||
public static BillingEventVKey create(@Nullable Key<BillingEvent.OneTime> ofyKey) {
|
||||
if (ofyKey == null) {
|
||||
return null;
|
||||
}
|
||||
long billingEventId = ofyKey.getId();
|
||||
long historyRevisionId = ofyKey.getParent().getId();
|
||||
String repoId = ofyKey.getParent().getParent().getName();
|
||||
return new BillingEventVKey(repoId, historyRevisionId, billingEventId);
|
||||
}
|
||||
|
||||
/** Creates a {@link BillingEventVKey} instance from the given {@link VKey} instance. */
|
||||
public static BillingEventVKey create(@Nullable VKey<BillingEvent.OneTime> vKey) {
|
||||
return vKey == null ? null : new BillingEventVKey(null, 0, (Long) vKey.getSqlKey());
|
||||
}
|
||||
}
|
||||
|
||||
/** VKey class for {@link BillingEvent.Recurring} that belongs to a {@link DomainBase} entity. */
|
||||
@Embeddable
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
name = "repoId",
|
||||
column = @Column(name = "billing_recurrence_domain_repo_id")),
|
||||
@AttributeOverride(
|
||||
name = "historyRevisionId",
|
||||
column = @Column(name = "billing_recurrence_history_id")),
|
||||
@AttributeOverride(name = "billingId", column = @Column(name = "billing_recurrence_id"))
|
||||
})
|
||||
public static class BillingRecurrenceVKey extends BillingVKey<Recurring> {
|
||||
|
||||
// Hibernate requires this default constructor
|
||||
private BillingRecurrenceVKey() {}
|
||||
|
||||
private BillingRecurrenceVKey(String repoId, long historyRevisionId, long billingEventId) {
|
||||
super(repoId, historyRevisionId, billingEventId);
|
||||
}
|
||||
|
||||
/** Creates a {@link BillingRecurrenceVKey} instance from the given {@link Key} instance. */
|
||||
public static BillingRecurrenceVKey create(@Nullable Key<BillingEvent.Recurring> ofyKey) {
|
||||
if (ofyKey == null) {
|
||||
return null;
|
||||
}
|
||||
long billingEventId = ofyKey.getId();
|
||||
long historyRevisionId = ofyKey.getParent().getId();
|
||||
String repoId = ofyKey.getParent().getParent().getName();
|
||||
return new BillingRecurrenceVKey(repoId, historyRevisionId, billingEventId);
|
||||
}
|
||||
|
||||
/** Creates a {@link BillingRecurrenceVKey} instance from the given {@link VKey} instance. */
|
||||
public static BillingRecurrenceVKey create(@Nullable VKey<BillingEvent.Recurring> vKey) {
|
||||
return vKey == null ? null : new BillingRecurrenceVKey(null, 0, (Long) vKey.getSqlKey());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,11 +20,12 @@ import java.io.Serializable;
|
|||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeConverter;
|
||||
|
||||
/** Converts VKey to a string column. */
|
||||
/** Converts VKey to a string or long column. */
|
||||
public abstract class VKeyConverter<T, C extends Serializable>
|
||||
implements AttributeConverter<VKey<? extends T>, C> {
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public C convertToDatabaseColumn(@Nullable VKey<? extends T> attribute) {
|
||||
return attribute == null ? null : (C) attribute.getSqlKey();
|
||||
}
|
||||
|
@ -35,8 +36,8 @@ public abstract class VKeyConverter<T, C extends Serializable>
|
|||
if (dbData == null) {
|
||||
return null;
|
||||
}
|
||||
Class<? extends T> clazz = getAttributeClass();
|
||||
Key ofyKey = null;
|
||||
Class<T> clazz = getAttributeClass();
|
||||
Key<T> ofyKey;
|
||||
if (!hasCompositeOfyKey()) {
|
||||
// If this isn't a composite key, we can create the Ofy key from the SQL key.
|
||||
ofyKey =
|
||||
|
|
|
@ -415,7 +415,7 @@ public final class DomainLockUtils {
|
|||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now)
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build();
|
||||
tm().insert(oneTime);
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot
|
|||
BillingEvent.Recurring newAutorenewEvent =
|
||||
newAutorenewBillingEvent(domain)
|
||||
.setEventTime(newExpirationTime)
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build();
|
||||
PollMessage.Autorenew newAutorenewPollMessage =
|
||||
newAutorenewPollMessage(domain)
|
||||
|
|
|
@ -99,7 +99,6 @@
|
|||
|
||||
<!-- Generated converters for VKey -->
|
||||
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_Modification</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_OneTime</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_Recurring</class>
|
||||
<class>google.registry.model.contact.VKeyConverter_ContactResource</class>
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
#standardSQL
|
||||
-- Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- 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.
|
||||
|
||||
-- This query gathers all non-canceled billing events for a given
|
||||
-- YEAR_MONTH in yyyy-MM format.
|
||||
|
||||
SELECT
|
||||
__key__.id AS id,
|
||||
billingTime,
|
||||
eventTime,
|
||||
BillingEvent.clientId AS registrarId,
|
||||
RegistrarData.accountId AS billingId,
|
||||
RegistrarData.poNumber AS poNumber,
|
||||
tld,
|
||||
reason as action,
|
||||
targetId as domain,
|
||||
BillingEvent.domainRepoId as repositoryId,
|
||||
IFNULL(periodYears, 0) as years,
|
||||
BillingEvent.currency AS currency,
|
||||
BillingEvent.amount as amount,
|
||||
-- We'll strip out non-useful flags downstream
|
||||
ARRAY_TO_STRING(flags, " ") AS flags
|
||||
FROM (
|
||||
SELECT
|
||||
*,
|
||||
-- We store cost as "CURRENCY AMOUNT" such as "JPY 800" or "USD 20.00"
|
||||
SPLIT(cost, ' ')[OFFSET(0)] AS currency,
|
||||
SPLIT(cost, ' ')[OFFSET(1)] AS amount,
|
||||
-- Extract everything after the first dot in the domain as the TLD
|
||||
REGEXP_EXTRACT(targetId, r'[.](.+)') AS tld,
|
||||
-- __key__.path looks like '"DomainBase", "<repoId>", ...'
|
||||
REGEXP_REPLACE(SPLIT(__key__.path, ', ')[OFFSET(1)], '"', '')
|
||||
AS domainRepoId,
|
||||
COALESCE(cancellationMatchingBillingEvent.path,
|
||||
__key__.path) AS cancellationMatchingPath
|
||||
FROM
|
||||
`%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%ONETIME_TABLE%`
|
||||
-- Only include real TLDs (filter prober data)
|
||||
WHERE
|
||||
REGEXP_EXTRACT(targetId, r'[.](.+)') IN (
|
||||
SELECT
|
||||
tldStr
|
||||
FROM
|
||||
`%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%REGISTRY_TABLE%`
|
||||
WHERE
|
||||
invoicingEnabled IS TRUE) ) AS BillingEvent
|
||||
-- Gather billing ID from registrar table
|
||||
-- This is a 'JOIN' as opposed to 'LEFT JOIN' to filter out
|
||||
-- non-billable registrars
|
||||
JOIN (
|
||||
SELECT
|
||||
__key__.name AS clientId,
|
||||
billingIdentifier,
|
||||
IFNULL(poNumber, '') AS poNumber,
|
||||
r.billingAccountMap.currency[SAFE_OFFSET(index)] AS currency,
|
||||
r.billingAccountMap.accountId[SAFE_OFFSET(index)] AS accountId
|
||||
FROM
|
||||
`%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%REGISTRAR_TABLE%` AS r,
|
||||
UNNEST(GENERATE_ARRAY(0, ARRAY_LENGTH(r.billingAccountMap.currency) - 1))
|
||||
AS index
|
||||
WHERE billingAccountMap IS NOT NULL
|
||||
AND type = 'REAL') AS RegistrarData
|
||||
ON
|
||||
BillingEvent.clientId = RegistrarData.clientId
|
||||
AND BillingEvent.currency = RegistrarData.currency
|
||||
-- Gather cancellations
|
||||
LEFT JOIN (
|
||||
SELECT __key__.id AS cancellationId,
|
||||
COALESCE(refOneTime.path, refRecurring.path) AS cancelledEventPath,
|
||||
eventTime as cancellationTime,
|
||||
billingTime as cancellationBillingTime
|
||||
FROM
|
||||
(SELECT
|
||||
*,
|
||||
-- Count everything after first dot as TLD (to support multi-part TLDs).
|
||||
REGEXP_EXTRACT(targetId, r'[.](.+)') AS tld
|
||||
FROM
|
||||
`%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%CANCELLATION_TABLE%`)
|
||||
) AS Cancellation
|
||||
ON BillingEvent.cancellationMatchingPath = Cancellation.cancelledEventPath
|
||||
AND BillingEvent.billingTime = Cancellation.cancellationBillingTime
|
||||
WHERE billingTime BETWEEN TIMESTAMP('%FIRST_TIMESTAMP_OF_MONTH%')
|
||||
AND TIMESTAMP('%LAST_TIMESTAMP_OF_MONTH%')
|
||||
-- Filter out canceled events
|
||||
AND Cancellation.cancellationId IS NULL
|
||||
ORDER BY
|
||||
billingTime DESC,
|
||||
id,
|
||||
tld
|
|
@ -29,8 +29,8 @@ SELECT b, r FROM BillingEvent b
|
|||
JOIN Registrar r ON b.clientId = r.clientIdentifier
|
||||
JOIN Domain d ON b.domainRepoId = d.repoId
|
||||
JOIN Tld t ON t.tldStr = d.tld
|
||||
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId
|
||||
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring.billingId
|
||||
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime
|
||||
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring
|
||||
WHERE r.billingAccountMap IS NOT NULL
|
||||
AND r.type = 'REAL'
|
||||
AND t.invoicingEnabled IS TRUE
|
||||
|
|
|
@ -200,7 +200,7 @@ class DeleteExpiredDomainsActionTest {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(clock.nowUtc().plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(createHistoryEntry);
|
||||
.setDomainHistory(createHistoryEntry);
|
||||
}
|
||||
|
||||
private PollMessage.Autorenew.Builder createAutorenewPollMessage(
|
||||
|
|
|
@ -296,7 +296,7 @@ class DeleteProberDataActionTest {
|
|||
BillingEvent.OneTime billingEvent =
|
||||
persistSimpleResource(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setBillingTime(DELETION_TIME.plusYears(1))
|
||||
.setCost(Money.parse("USD 10"))
|
||||
.setPeriodYears(1)
|
||||
|
|
|
@ -105,7 +105,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.build());
|
||||
recurring =
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
|
@ -171,7 +171,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setPeriodYears(1)
|
||||
.setReason(Reason.RENEW)
|
||||
.setSyntheticCreationTime(currentTestTime)
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.setTargetId(domain.getDomainName());
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -204,7 +205,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
recurring =
|
||||
persistResource(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setRegistrarId(deletedDomain.getCreationRegistrarId())
|
||||
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
|
@ -225,7 +226,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.setTargetId(deletedDomain.getDomainName())
|
||||
.build();
|
||||
assertBillingEventsForResource(deletedDomain, expected, recurring);
|
||||
|
@ -241,7 +242,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertCursorAt(currentTestTime);
|
||||
DateTime beginningOfSecondRun = clock.nowUtc();
|
||||
action.response = new FakeResponse();
|
||||
|
@ -254,7 +256,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
void testSuccess_expandSingleEvent_idempotentForExistingOneTime() throws Exception {
|
||||
persistResource(recurring);
|
||||
BillingEvent.OneTime persisted =
|
||||
persistResource(defaultOneTimeBuilder().setParent(historyEntry).build());
|
||||
persistResource(defaultOneTimeBuilder().setDomainHistory(historyEntry).build());
|
||||
action.cursorTimeParam = Optional.of(START_OF_TIME);
|
||||
runAction();
|
||||
// No new history entries should be generated
|
||||
|
@ -273,7 +275,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
// Persist an otherwise identical billing event that differs only in billing time (and ID).
|
||||
BillingEvent.OneTime persisted =
|
||||
persistResource(
|
||||
|
@ -301,13 +304,13 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
}
|
||||
assertThat(persistedEntries).hasSize(2);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setParent(persistedEntries.get(0)).build();
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntries.get(0)).build();
|
||||
// Persist an otherwise identical billing event that differs only in recurring event key.
|
||||
BillingEvent.OneTime persisted =
|
||||
expected
|
||||
.asBuilder()
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2)
|
||||
.build();
|
||||
assertCursorAt(currentTestTime);
|
||||
assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2);
|
||||
|
@ -350,7 +353,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -364,7 +368,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -401,7 +406,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2002-02-19T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2002-01-05T00:00:00Z"))
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -416,7 +421,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -482,7 +488,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(billingDate.plusYears(year))
|
||||
.setEventTime(eventDate.plusYears(year))
|
||||
.setParent(persistedEntries.get(year))
|
||||
.setDomainHistory(persistedEntries.get(year))
|
||||
.build());
|
||||
}
|
||||
assertBillingEventsForResource(domain, Iterables.toArray(expectedEvents, BillingEvent.class));
|
||||
|
@ -508,7 +514,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
expectedEvents.add(
|
||||
defaultOneTimeBuilder()
|
||||
.setBillingTime(billingDate.plusYears(year))
|
||||
.setParent(persistedEntries.get(year))
|
||||
.setDomainHistory(persistedEntries.get(year))
|
||||
.setEventTime(eventDate.plusYears(year))
|
||||
.build());
|
||||
}
|
||||
|
@ -554,7 +560,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, recurring, expected);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -583,7 +589,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, recurring, expected);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -604,7 +610,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-02-29T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-01-15T00:00:00Z"))
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -626,7 +632,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2001-03-01T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2001-01-15T00:00:00Z"))
|
||||
.setParent(persistedEntry)
|
||||
.setDomainHistory(persistedEntry)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -652,7 +658,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
BillingEvent.Recurring recurring2 =
|
||||
persistResource(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry2)
|
||||
.setDomainHistory(historyEntry2)
|
||||
.setRegistrarId(domain2.getCreationRegistrarId())
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
|
@ -677,7 +683,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
BillingEvent.Recurring recurring3 =
|
||||
persistResource(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry3)
|
||||
.setDomainHistory(historyEntry3)
|
||||
.setRegistrarId(domain3.getCreationRegistrarId())
|
||||
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
|
@ -694,8 +700,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
domain, persistedHistory1, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setParent(persistedHistory1)
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setDomainHistory(persistedHistory1)
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.build();
|
||||
DomainHistory persistedHistory2 =
|
||||
getOnlyHistoryEntryOfType(domain2, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
|
@ -705,9 +711,9 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setParent(persistedHistory2)
|
||||
.setDomainHistory(persistedHistory2)
|
||||
.setTargetId(domain2.getDomainName())
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring2)
|
||||
.build();
|
||||
DomainHistory persistedHistory3 =
|
||||
getOnlyHistoryEntryOfType(domain3, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
|
@ -718,8 +724,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setBillingTime(DateTime.parse("2000-07-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
||||
.setTargetId(domain3.getDomainName())
|
||||
.setParent(persistedHistory3)
|
||||
.setCancellationMatchingBillingEvent(recurring3.createVKey())
|
||||
.setDomainHistory(persistedHistory3)
|
||||
.setCancellationMatchingBillingEvent(recurring3)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertBillingEventsForResource(domain2, expected2, recurring2);
|
||||
|
@ -755,8 +761,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setDomainHistory(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
domain,
|
||||
|
@ -768,8 +774,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -812,8 +818,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setCost(Money.of(USD, 4))
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setDomainHistory(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
domain,
|
||||
|
@ -826,8 +832,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setCost(Money.of(USD, 4))
|
||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2)
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -848,7 +854,10 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 100)).build();
|
||||
defaultOneTimeBuilder()
|
||||
.setDomainHistory(persistedEntry)
|
||||
.setCost(Money.of(USD, 100))
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -868,7 +877,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 11)).build();
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 11)).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -882,7 +891,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -908,7 +918,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 20)).build();
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 20)).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -929,7 +939,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
assertHistoryEntryMatches(
|
||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 2)).build();
|
||||
defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 2)).build();
|
||||
assertBillingEventsForResource(domain, expected, recurring);
|
||||
assertCursorAt(currentTestTime);
|
||||
}
|
||||
|
@ -961,7 +971,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(billingDate)
|
||||
.setEventTime(eventDate)
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setDomainHistory(persistedEntries.get(0))
|
||||
.setCost(Money.of(USD, 8))
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
|
@ -972,7 +982,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setCost(Money.of(USD, 10))
|
||||
.setBillingTime(billingDate.plusYears(1))
|
||||
.setEventTime(eventDate.plusYears(1))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -1006,7 +1016,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(billingDate)
|
||||
.setEventTime(eventDate)
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setDomainHistory(persistedEntries.get(0))
|
||||
.setCost(Money.of(USD, 8))
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
|
@ -1017,7 +1027,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setCost(Money.of(USD, 10))
|
||||
.setBillingTime(billingDate.plusYears(1))
|
||||
.setEventTime(eventDate.plusYears(1))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
@ -1057,7 +1067,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
defaultOneTimeBuilder()
|
||||
.setBillingTime(billingDate)
|
||||
.setEventTime(eventDate)
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setDomainHistory(persistedEntries.get(0))
|
||||
.setCost(Money.of(USD, 5))
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
|
@ -1068,7 +1078,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
|||
.setCost(Money.of(USD, 5))
|
||||
.setBillingTime(billingDate.plusYears(1))
|
||||
.setEventTime(eventDate.plusYears(1))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setDomainHistory(persistedEntries.get(1))
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||
assertCursorAt(currentTestTime);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
package google.registry.beam.invoicing;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey;
|
||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
||||
|
@ -23,108 +22,41 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import org.apache.avro.Schema;
|
||||
import org.apache.avro.generic.GenericData;
|
||||
import org.apache.avro.generic.GenericRecord;
|
||||
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link BillingEvent} */
|
||||
class BillingEventTest {
|
||||
|
||||
private static final String BILLING_EVENT_SCHEMA =
|
||||
"{\"name\": \"BillingEvent\", "
|
||||
+ "\"type\": \"record\", "
|
||||
+ "\"fields\": ["
|
||||
+ "{\"name\": \"id\", \"type\": \"long\"},"
|
||||
+ "{\"name\": \"billingTime\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"eventTime\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"registrarId\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"billingId\", \"type\": \"long\"},"
|
||||
+ "{\"name\": \"poNumber\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"tld\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"action\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"domain\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"repositoryId\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"years\", \"type\": \"int\"},"
|
||||
+ "{\"name\": \"currency\", \"type\": \"string\"},"
|
||||
+ "{\"name\": \"amount\", \"type\": \"float\"},"
|
||||
+ "{\"name\": \"flags\", \"type\": \"string\"}"
|
||||
+ "]}";
|
||||
|
||||
private SchemaAndRecord schemaAndRecord;
|
||||
private BillingEvent event;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
// Create a record with a given JSON schema.
|
||||
schemaAndRecord = new SchemaAndRecord(createRecord(), null);
|
||||
event = createBillingEvent("", 5);
|
||||
}
|
||||
|
||||
private GenericRecord createRecord() {
|
||||
GenericRecord record = new GenericData.Record(new Schema.Parser().parse(BILLING_EVENT_SCHEMA));
|
||||
record.put("id", "1");
|
||||
record.put("billingTime", 1508835963000000L);
|
||||
record.put("eventTime", 1484870383000000L);
|
||||
record.put("registrarId", "myRegistrar");
|
||||
record.put("billingId", "12345-CRRHELLO");
|
||||
record.put("poNumber", "");
|
||||
record.put("tld", "test");
|
||||
record.put("action", "RENEW");
|
||||
record.put("domain", "example.test");
|
||||
record.put("repositoryId", "123456");
|
||||
record.put("years", 5);
|
||||
record.put("currency", "USD");
|
||||
record.put("amount", 20.5);
|
||||
record.put("flags", "AUTO_RENEW SYNTHETIC");
|
||||
return record;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseBillingEventFromRecord_success() {
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
assertThat(event.id()).isEqualTo(1);
|
||||
assertThat(event.billingTime()).isEqualTo(DateTime.parse("2017-10-24T09:06:03Z"));
|
||||
assertThat(event.eventTime()).isEqualTo(DateTime.parse("2017-01-19T23:59:43Z"));
|
||||
assertThat(event.registrarId()).isEqualTo("myRegistrar");
|
||||
assertThat(event.billingId()).isEqualTo("12345-CRRHELLO");
|
||||
assertThat(event.poNumber()).isEmpty();
|
||||
assertThat(event.tld()).isEqualTo("test");
|
||||
assertThat(event.action()).isEqualTo("RENEW");
|
||||
assertThat(event.domain()).isEqualTo("example.test");
|
||||
assertThat(event.repositoryId()).isEqualTo("123456");
|
||||
assertThat(event.years()).isEqualTo(5);
|
||||
assertThat(event.currency()).isEqualTo("USD");
|
||||
assertThat(event.amount()).isEqualTo(20.5);
|
||||
assertThat(event.flags()).isEqualTo("AUTO_RENEW SYNTHETIC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseBillingEventFromRecord_sunriseCreate_reducedPrice_success() {
|
||||
schemaAndRecord.getRecord().put("flags", "SUNRISE");
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
assertThat(event.amount()).isEqualTo(17.43);
|
||||
assertThat(event.flags()).isEqualTo("SUNRISE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseBillingEventFromRecord_anchorTenant_zeroPrice_success() {
|
||||
schemaAndRecord.getRecord().put("flags", "SUNRISE ANCHOR_TENANT");
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
assertThat(event.amount()).isZero();
|
||||
assertThat(event.flags()).isEqualTo("SUNRISE ANCHOR_TENANT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseBillingEventFromRecord_nullValue_throwsException() {
|
||||
schemaAndRecord.getRecord().put("tld", null);
|
||||
assertThrows(IllegalStateException.class, () -> BillingEvent.parseFromRecord(schemaAndRecord));
|
||||
private static BillingEvent createBillingEvent(String pONumber, int years) {
|
||||
return BillingEvent.create(
|
||||
1,
|
||||
new DateTime(1508835963000L, DateTimeZone.UTC),
|
||||
new DateTime(1484870383000L, DateTimeZone.UTC),
|
||||
"myRegistrar",
|
||||
"12345-CRRHELLO",
|
||||
pONumber,
|
||||
"test",
|
||||
"RENEW",
|
||||
"example.test",
|
||||
"123456",
|
||||
years,
|
||||
"USD",
|
||||
20.5,
|
||||
"AUTO_RENEW SYNTHETIC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvertBillingEvent_toCsv() {
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
assertThat(event.toCsv())
|
||||
.isEqualTo(
|
||||
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
||||
|
@ -133,9 +65,7 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void testConvertBillingEvent_nonNullPoNumber_toCsv() {
|
||||
GenericRecord record = createRecord();
|
||||
record.put("poNumber", "905610");
|
||||
BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null));
|
||||
event = createBillingEvent("905610", 5);
|
||||
assertThat(event.toCsv())
|
||||
.isEqualTo(
|
||||
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
||||
|
@ -144,13 +74,11 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void testGenerateBillingEventFilename() {
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
assertThat(event.toFilename("2017-10")).isEqualTo("invoice_details_2017-10_myRegistrar_test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetInvoiceGroupingKey_fromBillingEvent() {
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||
assertThat(invoiceKey.startDate()).isEqualTo("2017-10-01");
|
||||
assertThat(invoiceKey.endDate()).isEqualTo("2022-09-30");
|
||||
|
@ -164,9 +92,7 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void test_nonNullPoNumber() {
|
||||
GenericRecord record = createRecord();
|
||||
record.put("poNumber", "905610");
|
||||
BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null));
|
||||
event = createBillingEvent("905610", 5);
|
||||
assertThat(event.poNumber()).isEqualTo("905610");
|
||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||
assertThat(invoiceKey.poNumber()).isEqualTo("905610");
|
||||
|
@ -174,7 +100,6 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void testConvertInvoiceGroupingKey_toCsv() {
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||
assertThat(invoiceKey.toCsv(3L))
|
||||
.isEqualTo(
|
||||
|
@ -184,10 +109,7 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void testConvertInvoiceGroupingKey_zeroYears_toCsv() {
|
||||
GenericRecord record = schemaAndRecord.getRecord();
|
||||
record.put("years", 0);
|
||||
schemaAndRecord = new SchemaAndRecord(record, null);
|
||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||
event = createBillingEvent("", 0);
|
||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||
assertThat(invoiceKey.toCsv(3L))
|
||||
.isEqualTo(
|
||||
|
@ -197,8 +119,7 @@ class BillingEventTest {
|
|||
|
||||
@Test
|
||||
void testInvoiceGroupingKeyCoder_deterministicSerialization() throws IOException {
|
||||
InvoiceGroupingKey invoiceKey =
|
||||
BillingEvent.parseFromRecord(schemaAndRecord).getInvoiceGroupingKey();
|
||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||
InvoiceGroupingKeyCoder coder = new InvoiceGroupingKeyCoder();
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
coder.encode(invoiceKey, outStream);
|
||||
|
@ -217,8 +138,9 @@ class BillingEventTest {
|
|||
@Test
|
||||
void testGetOverallInvoiceHeader() {
|
||||
assertThat(InvoiceGroupingKey.invoiceHeader())
|
||||
.isEqualTo("StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode,"
|
||||
+ "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice,"
|
||||
+ "UnitPriceCurrency,PONumber");
|
||||
.isEqualTo(
|
||||
"StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode,"
|
||||
+ "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice,"
|
||||
+ "UnitPriceCurrency,PONumber");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
|||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
import google.registry.testing.DatastoreEntityExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestDataHelper;
|
||||
import google.registry.util.ResourceUtils;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
|
@ -67,7 +66,6 @@ import org.apache.beam.sdk.transforms.MapElements;
|
|||
import org.apache.beam.sdk.transforms.PTransform;
|
||||
import org.apache.beam.sdk.values.PCollection;
|
||||
import org.apache.beam.sdk.values.TypeDescriptor;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -81,8 +79,7 @@ class InvoicingPipelineTest {
|
|||
|
||||
@RegisterExtension
|
||||
@Order(Order.DEFAULT - 1)
|
||||
final transient DatastoreEntityExtension datastore =
|
||||
new DatastoreEntityExtension().allThreads(true);
|
||||
final DatastoreEntityExtension datastore = new DatastoreEntityExtension().allThreads(true);
|
||||
|
||||
@RegisterExtension
|
||||
final TestPipelineExtension pipeline =
|
||||
|
@ -263,15 +260,6 @@ class InvoicingPipelineTest {
|
|||
pipeline.apply(Create.of(INPUT_EVENTS).withCoder(SerializableCoder.of(BillingEvent.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_makeQuery() {
|
||||
String query = InvoicingPipeline.makeQuery("2017-10", "my-project-id");
|
||||
assertThat(query)
|
||||
.isEqualTo(TestDataHelper.loadFile(this.getClass(), "billing_events_test.sql"));
|
||||
// This is necessary because the TestPipelineExtension verifies that the pipeline is run.
|
||||
pipeline.run();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fullSqlPipeline() throws Exception {
|
||||
setupCloudSql();
|
||||
|
@ -365,14 +353,14 @@ class InvoicingPipelineTest {
|
|||
// Test that comments are removed from the .sql file correctly
|
||||
assertThat(InvoicingPipeline.makeCloudSqlQuery("2017-10"))
|
||||
.isEqualTo(
|
||||
"\n"
|
||||
'\n'
|
||||
+ "SELECT b, r FROM BillingEvent b\n"
|
||||
+ "JOIN Registrar r ON b.clientId = r.clientIdentifier\n"
|
||||
+ "JOIN Domain d ON b.domainRepoId = d.repoId\n"
|
||||
+ "JOIN Tld t ON t.tldStr = d.tld\n"
|
||||
+ "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId\n"
|
||||
+ "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime\n"
|
||||
+ "LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent ="
|
||||
+ " cr.refRecurring.billingId\n"
|
||||
+ " cr.refRecurring\n"
|
||||
+ "WHERE r.billingAccountMap IS NOT NULL\n"
|
||||
+ "AND r.type = 'REAL'\n"
|
||||
+ "AND t.invoicingEnabled IS TRUE\n"
|
||||
|
@ -386,13 +374,12 @@ class InvoicingPipelineTest {
|
|||
private ImmutableList<String> resultFileContents(String filename) throws Exception {
|
||||
File resultFile =
|
||||
new File(
|
||||
String.format(
|
||||
"%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath().toString(), filename));
|
||||
String.format("%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath(), filename));
|
||||
return ImmutableList.copyOf(
|
||||
ResourceUtils.readResourceUtf8(resultFile.toURI().toURL()).split("\n"));
|
||||
}
|
||||
|
||||
private void setupCloudSql() {
|
||||
private static void setupCloudSql() {
|
||||
// Populate billing events in Cloud SQL to match existing test data for Datastore
|
||||
persistNewRegistrar("NewRegistrar");
|
||||
persistNewRegistrar("TheRegistrar");
|
||||
|
@ -444,7 +431,7 @@ class InvoicingPipelineTest {
|
|||
registrar1,
|
||||
Reason.CREATE,
|
||||
5,
|
||||
Money.ofMajor(CurrencyUnit.JPY, 70),
|
||||
Money.ofMajor(JPY, 70),
|
||||
DateTime.parse("2017-09-29T00:00:00.0Z"),
|
||||
DateTime.parse("2017-10-02T00:00:00.0Z"));
|
||||
persistOneTimeBillingEvent(4, domain4, registrar2, Reason.RENEW, 1, Money.of(USD, 20.5));
|
||||
|
@ -495,7 +482,7 @@ class InvoicingPipelineTest {
|
|||
registrar1,
|
||||
Reason.CREATE,
|
||||
5,
|
||||
Money.ofMajor(CurrencyUnit.JPY, 70),
|
||||
Money.ofMajor(JPY, 70),
|
||||
DateTime.parse("2017-06-29T00:00:00.0Z"),
|
||||
DateTime.parse("2017-07-02T00:00:00.0Z"));
|
||||
|
||||
|
@ -510,13 +497,12 @@ class InvoicingPipelineTest {
|
|||
.asBuilder()
|
||||
.setId(1)
|
||||
.setRegistrarId(registrar1.getRegistrarId())
|
||||
.setDomainHistoryRevisionId(domainHistory.getId())
|
||||
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
||||
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||
.setOneTimeEventKey(oneTime.createVKey())
|
||||
.setTargetId(domain12.getDomainName())
|
||||
.setReason(Reason.RENEW)
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build();
|
||||
persistResource(cancellation);
|
||||
|
||||
|
@ -530,7 +516,7 @@ class InvoicingPipelineTest {
|
|||
.setRegistrarId(registrar1.getRegistrarId())
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setId(1)
|
||||
.setParent(domainHistoryRecurring)
|
||||
.setDomainHistory(domainHistoryRecurring)
|
||||
.setTargetId(domain13.getDomainName())
|
||||
.setEventTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||
.setReason(Reason.RENEW)
|
||||
|
@ -541,7 +527,7 @@ class InvoicingPipelineTest {
|
|||
oneTimeRecurring =
|
||||
oneTimeRecurring
|
||||
.asBuilder()
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.setFlags(ImmutableSet.of(Flag.SYNTHETIC))
|
||||
.setSyntheticCreationTime(DateTime.parse("2017-10-03T00:00:00.0Z"))
|
||||
.build();
|
||||
|
@ -552,18 +538,17 @@ class InvoicingPipelineTest {
|
|||
.asBuilder()
|
||||
.setId(2)
|
||||
.setRegistrarId(registrar1.getRegistrarId())
|
||||
.setDomainHistoryRevisionId(domainHistoryRecurring.getId())
|
||||
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
||||
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||
.setRecurringEventKey(recurring.createVKey())
|
||||
.setTargetId(domain13.getDomainName())
|
||||
.setReason(Reason.RENEW)
|
||||
.setParent(domainHistoryRecurring)
|
||||
.setDomainHistory(domainHistoryRecurring)
|
||||
.build();
|
||||
persistResource(cancellationRecurring);
|
||||
}
|
||||
|
||||
private DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) {
|
||||
private static DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) {
|
||||
DomainHistory domainHistory =
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_RENEW)
|
||||
|
@ -574,7 +559,7 @@ class InvoicingPipelineTest {
|
|||
return persistResource(domainHistory);
|
||||
}
|
||||
|
||||
private OneTime persistOneTimeBillingEvent(
|
||||
private static OneTime persistOneTimeBillingEvent(
|
||||
int id, DomainBase domainBase, Registrar registrar, Reason reason, int years, Money money) {
|
||||
return persistOneTimeBillingEvent(
|
||||
id,
|
||||
|
@ -587,7 +572,7 @@ class InvoicingPipelineTest {
|
|||
DateTime.parse("2017-10-04T00:00:00.0Z"));
|
||||
}
|
||||
|
||||
private OneTime persistOneTimeBillingEvent(
|
||||
private static OneTime persistOneTimeBillingEvent(
|
||||
int id,
|
||||
DomainBase domainBase,
|
||||
Registrar registrar,
|
||||
|
@ -597,7 +582,7 @@ class InvoicingPipelineTest {
|
|||
DateTime eventTime,
|
||||
DateTime billingTime,
|
||||
Flag... flags) {
|
||||
google.registry.model.billing.BillingEvent.OneTime.Builder billingEventBuilder =
|
||||
OneTime.Builder billingEventBuilder =
|
||||
new OneTime()
|
||||
.asBuilder()
|
||||
.setId(id)
|
||||
|
@ -606,10 +591,9 @@ class InvoicingPipelineTest {
|
|||
.setRegistrarId(registrar.getRegistrarId())
|
||||
.setReason(reason)
|
||||
.setTargetId(domainBase.getDomainName())
|
||||
.setDomainRepoId("REPO-ID")
|
||||
.setCost(money)
|
||||
.setFlags(Arrays.stream(flags).collect(toImmutableSet()))
|
||||
.setParent(persistDomainHistory(domainBase, registrar));
|
||||
.setDomainHistory(persistDomainHistory(domainBase, registrar));
|
||||
|
||||
if (years > 0) {
|
||||
billingEventBuilder.setPeriodYears(years);
|
||||
|
@ -620,6 +604,9 @@ class InvoicingPipelineTest {
|
|||
|
||||
private static class ChangeDomainRepo
|
||||
extends PTransform<PCollection<BillingEvent>, PCollection<BillingEvent>> {
|
||||
|
||||
private static final long serialVersionUID = 2695033474967615250L;
|
||||
|
||||
@Override
|
||||
public PCollection<BillingEvent> expand(PCollection<BillingEvent> input) {
|
||||
return input.apply(
|
||||
|
|
|
@ -544,7 +544,8 @@ class EppLifecycleDomainTest extends EppTestCase {
|
|||
.setCost(Money.parse("USD 100.00"))
|
||||
.setEventTime(createTime)
|
||||
.setBillingTime(createTime.plus(Registry.get("tld").getRenewGracePeriodLength()))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.build();
|
||||
|
||||
// The expected one-time billing event, that should have an associated Cancellation.
|
||||
|
|
|
@ -28,7 +28,6 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
|
@ -327,7 +326,8 @@ public class EppTestCase {
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(createTime)
|
||||
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ public class EppTestCase {
|
|||
.setPeriodYears(3)
|
||||
.setEventTime(renewTime)
|
||||
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class))
|
||||
.setDomainHistory(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ public class EppTestCase {
|
|||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setEventTime(eventTime)
|
||||
.setRecurrenceEndTime(endTime)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -386,10 +386,11 @@ public class EppTestCase {
|
|||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setEventTime(deleteTime)
|
||||
.setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
||||
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
||||
.setReason(Reason.CREATE)
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -400,10 +401,11 @@ public class EppTestCase {
|
|||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setEventTime(deleteTime)
|
||||
.setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
||||
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
||||
.setReason(Reason.RENEW)
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -412,11 +414,11 @@ public class EppTestCase {
|
|||
*
|
||||
* <p>This is used in the situation where we have created an expected billing event associated
|
||||
* with the domain's creation (which is passed as the parameter here), then need to locate the key
|
||||
* to the actual billing event in Datastore that would be seen on a Cancellation billing event.
|
||||
* to the actual billing event in the database that would be seen on a Cancellation billing event.
|
||||
* This is necessary because the ID will be different even though all the rest of the fields are
|
||||
* the same.
|
||||
*/
|
||||
private static Key<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
|
||||
private static VKey<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
|
||||
Optional<OneTime> actualCreateBillingEvent =
|
||||
loadAllOf(BillingEvent.OneTime.class).stream()
|
||||
.filter(
|
||||
|
@ -425,6 +427,6 @@ public class EppTestCase {
|
|||
stripBillingEventId(b), stripBillingEventId(expectedBillingEvent)))
|
||||
.findFirst();
|
||||
assertThat(actualCreateBillingEvent).isPresent();
|
||||
return Key.create(actualCreateBillingEvent.get());
|
||||
return actualCreateBillingEvent.get().createVKey();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1440,7 +1440,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(existingDomain.getCreationTime())
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
return persistResource(
|
||||
existingDomain.asBuilder().setAutorenewBillingEvent(renewEvent.createVKey()).build());
|
||||
|
|
|
@ -301,7 +301,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(billingTime)
|
||||
.setFlags(expectedBillingFlags)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setAllocationToken(allocationToken == null ? null : allocationToken.createVKey())
|
||||
.build();
|
||||
|
||||
|
@ -313,7 +313,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setRenewalPriceBehavior(renewalPriceInfo.renewalPriceBehavior())
|
||||
.setRenewalPrice(renewalPriceInfo.renewalPrice())
|
||||
.build();
|
||||
|
@ -334,7 +334,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
|||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(billingTime)
|
||||
.setFlags(expectedBillingFlags)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
expectedBillingEvents.add(eapBillingEvent);
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
|||
.setEventTime(eventTime)
|
||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||
.setOneTimeEventKey(graceBillingEvent.createVKey())
|
||||
.setParent(historyEntryDomainDelete)
|
||||
.setDomainHistory(historyEntryDomainDelete)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(TIME_BEFORE_FLOW.minusDays(4))
|
||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||
.setParent(earlierHistoryEntry)
|
||||
.setDomainHistory(earlierHistoryEntry)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
|||
.setRegistrarId(registrarId)
|
||||
.setEventTime(A_MONTH_FROM_NOW)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(earlierHistoryEntry);
|
||||
.setDomainHistory(earlierHistoryEntry);
|
||||
}
|
||||
|
||||
private PollMessage.Autorenew.Builder createAutorenewPollMessage(String registrarId) {
|
||||
|
|
|
@ -388,7 +388,7 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, DomainBase
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
VKey<BillingEvent.Recurring> recurringVKey = renewEvent.createVKey();
|
||||
// Add an AUTO_RENEW grace period to the saved resource.
|
||||
|
|
|
@ -112,7 +112,7 @@ public class DomainPricingLogicTest {
|
|||
Recurring recurring =
|
||||
persistResource(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
.setEventTime(DateTime.parse("1999-01-05T00:00:00Z"))
|
||||
.setFlags(ImmutableSet.of(AUTO_RENEW))
|
||||
|
|
|
@ -170,7 +170,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainCreate)
|
||||
.setDomainHistory(historyEntryDomainCreate)
|
||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||
.setRenewalPrice(renewalPrice)
|
||||
.build();
|
||||
|
@ -284,7 +284,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
|||
.setPeriodYears(renewalYears)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc().plus(Registry.get("tld").getRenewGracePeriodLength()))
|
||||
.setParent(historyEntryDomainRenew)
|
||||
.setDomainHistory(historyEntryDomainRenew)
|
||||
.build();
|
||||
assertBillingEvents(
|
||||
renewBillingEvent,
|
||||
|
@ -297,7 +297,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(clock.nowUtc())
|
||||
.setParent(
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(
|
||||
domain, HistoryEntry.Type.DOMAIN_CREATE, DomainHistory.class))
|
||||
.build(),
|
||||
|
@ -310,7 +310,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainRenew)
|
||||
.setDomainHistory(historyEntryDomainRenew)
|
||||
.build());
|
||||
// There should only be the new autorenew poll message, as the old one will have been deleted
|
||||
// since it had no messages left to deliver.
|
||||
|
|
|
@ -212,7 +212,7 @@ class DomainRestoreRequestFlowTest
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainRestore)
|
||||
.setDomainHistory(historyEntryDomainRestore)
|
||||
.build(),
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.RESTORE)
|
||||
|
@ -222,7 +222,7 @@ class DomainRestoreRequestFlowTest
|
|||
.setPeriodYears(1)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc())
|
||||
.setParent(historyEntryDomainRestore)
|
||||
.setDomainHistory(historyEntryDomainRestore)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,7 @@ class DomainRestoreRequestFlowTest
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(newExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainRestore)
|
||||
.setDomainHistory(historyEntryDomainRestore)
|
||||
.build(),
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.RESTORE)
|
||||
|
@ -291,7 +291,7 @@ class DomainRestoreRequestFlowTest
|
|||
.setPeriodYears(1)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc())
|
||||
.setParent(historyEntryDomainRestore)
|
||||
.setDomainHistory(historyEntryDomainRestore)
|
||||
.build(),
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
|
@ -301,7 +301,7 @@ class DomainRestoreRequestFlowTest
|
|||
.setPeriodYears(1)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc())
|
||||
.setParent(historyEntryDomainRestore)
|
||||
.setDomainHistory(historyEntryDomainRestore)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -265,13 +265,13 @@ class DomainTransferApproveFlowTest
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setCost(Money.of(USD, 11).multipliedBy(expectedYearsToCharge))
|
||||
.setPeriodYears(expectedYearsToCharge)
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.setDomainHistory(historyEntryTransferApproved)
|
||||
.build();
|
||||
assertBillingEventsForResource(
|
||||
domain,
|
||||
Streams.concat(
|
||||
Arrays.stream(expectedCancellationBillingEvents)
|
||||
.map(builder -> builder.setParent(historyEntryTransferApproved).build()),
|
||||
.map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()),
|
||||
Stream.of(
|
||||
transferBillingEvent,
|
||||
getLosingClientAutorenewEvent()
|
||||
|
@ -281,7 +281,7 @@ class DomainTransferApproveFlowTest
|
|||
getGainingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.setDomainHistory(historyEntryTransferApproved)
|
||||
.build()))
|
||||
.toArray(BillingEvent[]::new));
|
||||
// There should be a grace period for the new transfer billing event.
|
||||
|
@ -308,7 +308,7 @@ class DomainTransferApproveFlowTest
|
|||
domain,
|
||||
Streams.concat(
|
||||
Arrays.stream(expectedCancellationBillingEvents)
|
||||
.map(builder -> builder.setParent(historyEntryTransferApproved).build()),
|
||||
.map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()),
|
||||
Stream.of(
|
||||
getLosingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
|
@ -317,7 +317,7 @@ class DomainTransferApproveFlowTest
|
|||
getGainingClientAutorenewEvent()
|
||||
.asBuilder()
|
||||
.setEventTime(domain.getRegistrationExpirationTime())
|
||||
.setParent(historyEntryTransferApproved)
|
||||
.setDomainHistory(historyEntryTransferApproved)
|
||||
.build()))
|
||||
.toArray(BillingEvent[]::new));
|
||||
// There should be no grace period.
|
||||
|
|
|
@ -143,7 +143,7 @@ abstract class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(REGISTRATION_EXPIRATION_TIME)
|
||||
.setRecurrenceEndTime(TRANSFER_EXPIRATION_TIME)
|
||||
.setParent(historyEntryDomainCreate)
|
||||
.setDomainHistory(historyEntryDomainCreate)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ abstract class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(
|
||||
domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST, DomainHistory.class))
|
||||
.build();
|
||||
|
|
|
@ -262,7 +262,7 @@ class DomainTransferRequestFlowTest
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setCost(transferCost.orElse(Money.of(USD, 11)))
|
||||
.setPeriodYears(1)
|
||||
.setParent(historyEntryTransferRequest)
|
||||
.setDomainHistory(historyEntryTransferRequest)
|
||||
.build());
|
||||
} else {
|
||||
// Superuser transfers with no bundled renewal have no transfer billing event.
|
||||
|
@ -282,7 +282,7 @@ class DomainTransferRequestFlowTest
|
|||
// Construct extra billing events expected by the specific test.
|
||||
ImmutableSet<BillingEvent> extraBillingEvents =
|
||||
Stream.of(extraExpectedBillingEvents)
|
||||
.map(builder -> builder.setParent(historyEntryTransferRequest).build())
|
||||
.map(builder -> builder.setDomainHistory(historyEntryTransferRequest).build())
|
||||
.collect(toImmutableSet());
|
||||
// Assert that the billing events we constructed above actually exist in Datastore.
|
||||
ImmutableSet<BillingEvent> expectedBillingEvents =
|
||||
|
|
|
@ -815,7 +815,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
|||
.setCost(Money.of(USD, 19))
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc())
|
||||
.setParent(
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(
|
||||
reloadResourceByForeignKey(), DOMAIN_UPDATE, DomainHistory.class))
|
||||
.build());
|
||||
|
|
|
@ -30,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
|
@ -110,7 +109,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setReason(Reason.CREATE)
|
||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT))
|
||||
.setPeriodYears(2)
|
||||
|
@ -123,7 +122,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -132,13 +131,13 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setReason(Reason.CREATE)
|
||||
.setFlags(
|
||||
ImmutableSet.of(
|
||||
BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
|
||||
.setSyntheticCreationTime(now.plusDays(10))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.setPeriodYears(2)
|
||||
.setCost(Money.of(USD, 1))
|
||||
.setEventTime(now)
|
||||
|
@ -148,7 +147,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(domainHistory2)
|
||||
.setDomainHistory(domainHistory2)
|
||||
.setReason(Reason.CREATE)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusDays(5))
|
||||
|
@ -158,14 +157,15 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(domainHistory2)
|
||||
.setDomainHistory(domainHistory2)
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusYears(1).plusDays(45))
|
||||
.setRecurringEventKey(recurring.createVKey())));
|
||||
}
|
||||
|
||||
private <E extends BillingEvent, B extends BillingEvent.Builder<E, B>> E commonInit(B builder) {
|
||||
private static <E extends BillingEvent, B extends BillingEvent.Builder<E, B>> E commonInit(
|
||||
B builder) {
|
||||
return builder.setRegistrarId("TheRegistrar").setTargetId("foo.tld").build();
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
oneTime
|
||||
.asBuilder()
|
||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setCancellationMatchingBillingEvent(recurring)
|
||||
.build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
|
@ -248,11 +248,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
IllegalStateException thrown =
|
||||
assertThrows(
|
||||
IllegalStateException.class,
|
||||
() ->
|
||||
oneTime
|
||||
.asBuilder()
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.build());
|
||||
() -> oneTime.asBuilder().setCancellationMatchingBillingEvent(recurring).build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains(
|
||||
|
@ -266,7 +262,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
BillingEvent.Cancellation.forGracePeriod(
|
||||
GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), oneTime),
|
||||
domainHistory2.getModificationTime(),
|
||||
Key.create(domainHistory2),
|
||||
domainHistory2.getDomainHistoryId(),
|
||||
"foo.tld");
|
||||
// Set ID to be the same to ignore for the purposes of comparison.
|
||||
assertThat(newCancellation.asBuilder().setId(cancellationOneTime.getId()).build())
|
||||
|
@ -284,7 +280,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
"TheRegistrar",
|
||||
recurring.createVKey()),
|
||||
domainHistory2.getModificationTime(),
|
||||
Key.create(domainHistory2),
|
||||
domainHistory2.getDomainHistoryId(),
|
||||
"foo.tld");
|
||||
// Set ID to be the same to ignore for the purposes of comparison.
|
||||
assertThat(newCancellation.asBuilder().setId(cancellationRecurring.getId()).build())
|
||||
|
@ -304,7 +300,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
now.plusDays(1),
|
||||
"a registrar"),
|
||||
domainHistory.getModificationTime(),
|
||||
Key.create(domainHistory),
|
||||
domainHistory.getDomainHistoryId(),
|
||||
"foo.tld"));
|
||||
assertThat(thrown).hasMessageThat().contains("grace period without billing event");
|
||||
}
|
||||
|
@ -337,12 +333,6 @@ public class BillingEventTest extends EntityTestCase {
|
|||
assertThat(thrown).hasMessageThat().contains("exactly one billing event");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeadCodeThatDeletedScrapCommandsReference() {
|
||||
assertThat(recurring.getParentKey()).isEqualTo(Key.create(domainHistory));
|
||||
new BillingEvent.OneTime.Builder().setParent(Key.create(domainHistory));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReasonRequiringPeriodYears_missingPeriodYears_throwsException() {
|
||||
IllegalStateException thrown =
|
||||
|
@ -357,7 +347,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
.setCost(Money.of(USD, 10))
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTargetId("example.tld")
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
|
@ -379,7 +369,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
.setCost(Money.of(USD, 10))
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTargetId("example.tld")
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
|
@ -397,7 +387,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
.setCost(Money.of(USD, 10))
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setTargetId("example.tld")
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -413,7 +403,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -429,7 +419,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -456,7 +446,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -479,7 +469,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -506,7 +496,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -529,7 +519,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -557,7 +547,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -585,7 +575,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -616,7 +606,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -648,7 +638,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -680,7 +670,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -711,7 +701,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -743,7 +733,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -775,7 +765,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -792,7 +782,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -808,7 +798,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -826,7 +816,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
IllegalArgumentException.class,
|
||||
() ->
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -847,7 +837,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
IllegalArgumentException.class,
|
||||
() ->
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
@ -869,7 +859,7 @@ public class BillingEventTest extends EntityTestCase {
|
|||
IllegalArgumentException.class,
|
||||
() ->
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
|
|
|
@ -17,10 +17,6 @@ package google.registry.model.common;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import google.registry.model.billing.BillingEvent.Cancellation;
|
||||
import google.registry.model.billing.BillingEvent.Modification;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
|
@ -44,7 +40,7 @@ import org.junit.jupiter.api.Test;
|
|||
public class ClassPathManagerTest {
|
||||
@Test
|
||||
void getClass_classInClassRegistry_returnsClass() throws ClassNotFoundException {
|
||||
/**
|
||||
/*
|
||||
* Class names are used in stringified vkeys, which can be present in task queues. Class name is
|
||||
* required to create a vkey. Changing these names could break task queue entries that are
|
||||
* present during a rollout. If you want to change the names of any of the classses supported in
|
||||
|
@ -55,15 +51,11 @@ public class ClassPathManagerTest {
|
|||
*/
|
||||
assertThat(ClassPathManager.getClass("ForeignKeyContactIndex"))
|
||||
.isEqualTo(ForeignKeyContactIndex.class);
|
||||
assertThat(ClassPathManager.getClass("Modification")).isEqualTo(Modification.class);
|
||||
assertThat(ClassPathManager.getClass("AllocationToken")).isEqualTo(AllocationToken.class);
|
||||
assertThat(ClassPathManager.getClass("OneTime")).isEqualTo(OneTime.class);
|
||||
assertThat(ClassPathManager.getClass("RdeRevision")).isEqualTo(RdeRevision.class);
|
||||
assertThat(ClassPathManager.getClass("HostResource")).isEqualTo(HostResource.class);
|
||||
assertThat(ClassPathManager.getClass("Recurring")).isEqualTo(Recurring.class);
|
||||
assertThat(ClassPathManager.getClass("Registrar")).isEqualTo(Registrar.class);
|
||||
assertThat(ClassPathManager.getClass("ContactResource")).isEqualTo(ContactResource.class);
|
||||
assertThat(ClassPathManager.getClass("Cancellation")).isEqualTo(Cancellation.class);
|
||||
assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
||||
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
||||
.isEqualTo(EppResourceIndexBucket.class);
|
||||
|
@ -85,7 +77,7 @@ public class ClassPathManagerTest {
|
|||
IllegalArgumentException thrown =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> ClassPathManager.getClass("DomainHistory"));
|
||||
assertThat(thrown).hasMessageThat().contains("Class not found in class registry");
|
||||
assertThat(thrown).hasMessageThat().contains("Class DomainHistory not found in class registry");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -94,12 +86,14 @@ public class ClassPathManagerTest {
|
|||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> ClassPathManager.getClassName(DomainHistory.class));
|
||||
assertThat(thrown).hasMessageThat().contains("Class not found in class name registry");
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains("Class DomainHistory not found in class name registry");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getClassName() {
|
||||
/**
|
||||
/*
|
||||
* Class names are used in stringified vkeys, which can be present in task queues. Class name is
|
||||
* required to create a vkey. Changing these names could break task queue entries that are
|
||||
* present during a rollout. If you want to change the names of any of the classses supported in
|
||||
|
@ -110,15 +104,11 @@ public class ClassPathManagerTest {
|
|||
*/
|
||||
assertThat(ClassPathManager.getClassName(ForeignKeyContactIndex.class))
|
||||
.isEqualTo("ForeignKeyContactIndex");
|
||||
assertThat(ClassPathManager.getClassName(Modification.class)).isEqualTo("Modification");
|
||||
assertThat(ClassPathManager.getClassName(AllocationToken.class)).isEqualTo("AllocationToken");
|
||||
assertThat(ClassPathManager.getClassName(OneTime.class)).isEqualTo("OneTime");
|
||||
assertThat(ClassPathManager.getClassName(RdeRevision.class)).isEqualTo("RdeRevision");
|
||||
assertThat(ClassPathManager.getClassName(HostResource.class)).isEqualTo("HostResource");
|
||||
assertThat(ClassPathManager.getClassName(Recurring.class)).isEqualTo("Recurring");
|
||||
assertThat(ClassPathManager.getClassName(Registrar.class)).isEqualTo("Registrar");
|
||||
assertThat(ClassPathManager.getClassName(ContactResource.class)).isEqualTo("ContactResource");
|
||||
assertThat(ClassPathManager.getClassName(Cancellation.class)).isEqualTo("Cancellation");
|
||||
assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class))
|
||||
.isEqualTo("GaeUserIdConverter");
|
||||
assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class))
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.googlecode.objectify.Key;
|
|||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
|
@ -409,11 +410,9 @@ public class DomainBaseSqlTest {
|
|||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
|
@ -436,11 +435,10 @@ public class DomainBaseSqlTest {
|
|||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setBillingTime(DateTime.now(UTC))
|
||||
.setCost(Money.of(USD, 100))
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
DomainTransferData transferData =
|
||||
new DomainTransferData.Builder()
|
||||
|
@ -536,11 +534,9 @@ public class DomainBaseSqlTest {
|
|||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
|
@ -563,11 +559,10 @@ public class DomainBaseSqlTest {
|
|||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setBillingTime(DateTime.now(UTC))
|
||||
.setCost(Money.of(USD, 100))
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
DomainTransferData transferData =
|
||||
createPendingTransferData(
|
||||
|
@ -599,8 +594,7 @@ public class DomainBaseSqlTest {
|
|||
domain =
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(
|
||||
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))
|
||||
.setAutorenewBillingEvent(Recurring.createVKey(billEvent.getId()))
|
||||
.setAutorenewPollMessage(
|
||||
createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()),
|
||||
autorenewPollMessage.getHistoryRevisionId())
|
||||
|
|
|
@ -106,7 +106,7 @@ public class DomainBaseTest {
|
|||
domainHistory =
|
||||
persistResource(
|
||||
new DomainHistory.Builder()
|
||||
.setDomainRepoId(domain.createVKey().getOfyKey().getName())
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setRegistrarId("TheRegistrar")
|
||||
|
@ -118,11 +118,10 @@ public class DomainBaseTest {
|
|||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setBillingTime(DateTime.now(UTC))
|
||||
.setCost(Money.of(USD, 100))
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build())
|
||||
.createVKey();
|
||||
DomainHistory historyEntry =
|
||||
|
@ -145,11 +144,10 @@ public class DomainBaseTest {
|
|||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setBillingTime(DateTime.now(UTC))
|
||||
.setCost(Money.of(USD, 100))
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
oneTimeBillKey = oneTimeBill.createVKey();
|
||||
BillingEvent.Recurring recurringBill =
|
||||
|
@ -159,11 +157,9 @@ public class DomainBaseTest {
|
|||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setDomainHistoryRevisionId(historyEntry.getId())
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
insertInDb(historyEntry, oneTimeBill, recurringBill);
|
||||
recurringBillKey = recurringBill.createVKey();
|
||||
|
@ -427,7 +423,7 @@ public class DomainBaseTest {
|
|||
.plus(Registry.get("com").getTransferGracePeriodLength()))
|
||||
.setCost(Money.of(USD, 11))
|
||||
.setPeriodYears(1)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
domain =
|
||||
domain
|
||||
|
|
|
@ -18,12 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
@ -54,20 +53,12 @@ public class GracePeriodTest {
|
|||
.setBillingTime(now.plusDays(1))
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setCost(Money.of(CurrencyUnit.USD, 42))
|
||||
.setParent(
|
||||
Key.create(Key.create(DomainBase.class, "domain"), DomainHistory.class, 12345))
|
||||
.setDomainHistoryId(new DomainHistoryId("domain", 12345))
|
||||
.setReason(Reason.CREATE)
|
||||
.setPeriodYears(1)
|
||||
.setTargetId("foo.google")
|
||||
.build();
|
||||
recurringKey =
|
||||
VKey.create(
|
||||
Recurring.class,
|
||||
12345L,
|
||||
Key.create(
|
||||
Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L),
|
||||
Recurring.class,
|
||||
12345L));
|
||||
recurringKey = Recurring.createVKey(12345L);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -60,7 +60,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
|||
String domainRepoId = "4-TLD";
|
||||
createTld("tld");
|
||||
|
||||
/** Create a domain for the purpose of testing a foreign key reference in the Threat table. */
|
||||
// Create a domain for the purpose of testing a foreign key reference in the Threat table.
|
||||
domain =
|
||||
new DomainBase()
|
||||
.asBuilder()
|
||||
|
@ -73,7 +73,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
|||
.setContacts(ImmutableSet.of())
|
||||
.build();
|
||||
|
||||
/** Create a contact for the purpose of testing a foreign key reference in the Domain table. */
|
||||
// Create a contact for the purpose of testing a foreign key reference in the Domain table.
|
||||
registrantContact =
|
||||
new ContactResource.Builder()
|
||||
.setRepoId("contact_id")
|
||||
|
@ -82,7 +82,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
|||
.setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID)
|
||||
.build();
|
||||
|
||||
/** Create a host for the purpose of testing a foreign key reference in the Domain table. */
|
||||
// Create a host for the purpose of testing a foreign key reference in the Domain table. */
|
||||
host =
|
||||
new HostResource.Builder()
|
||||
.setRepoId("host")
|
||||
|
|
|
@ -20,6 +20,9 @@ import static org.joda.time.DateTimeZone.UTC;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Cancellation;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
|
@ -50,21 +53,9 @@ public class TransferDataTest {
|
|||
void beforeEach() {
|
||||
Key<HistoryEntry> historyEntryKey =
|
||||
Key.create(Key.create(DomainBase.class, "4-TLD"), HistoryEntry.class, 1356L);
|
||||
transferBillingEventKey =
|
||||
VKey.create(
|
||||
BillingEvent.OneTime.class,
|
||||
12345L,
|
||||
Key.create(historyEntryKey, BillingEvent.OneTime.class, 12345L));
|
||||
otherServerApproveBillingEventKey =
|
||||
VKey.create(
|
||||
BillingEvent.Cancellation.class,
|
||||
2468L,
|
||||
Key.create(historyEntryKey, BillingEvent.Cancellation.class, 2468L));
|
||||
recurringBillingEventKey =
|
||||
VKey.create(
|
||||
BillingEvent.Recurring.class,
|
||||
13579L,
|
||||
Key.create(historyEntryKey, BillingEvent.Recurring.class, 13579L));
|
||||
transferBillingEventKey = OneTime.createVKey(12345L);
|
||||
otherServerApproveBillingEventKey = Cancellation.createVKey(2468L);
|
||||
recurringBillingEventKey = Recurring.createVKey(13579L);
|
||||
autorenewPollMessageKey =
|
||||
VKey.create(
|
||||
PollMessage.Autorenew.class,
|
||||
|
|
|
@ -19,9 +19,10 @@ import static google.registry.testing.DatabaseHelper.newDomainBase;
|
|||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.common.ClassPathManager;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
|
@ -60,14 +61,12 @@ public class VKeyTranslatorFactoryTest {
|
|||
void testEntityWithAncestor() {
|
||||
Key<DomainBase> domainKey = Key.create(DomainBase.class, "ROID-1");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(domainKey, HistoryEntry.class, 10L);
|
||||
Key<BillingEvent.OneTime> oneTimeKey =
|
||||
Key.create(historyEntryKey, BillingEvent.OneTime.class, 200L);
|
||||
|
||||
VKey<BillingEvent.OneTime> vkey = VKeyTranslatorFactory.createVKey(oneTimeKey);
|
||||
VKey<HistoryEntry> vkey = VKeyTranslatorFactory.createVKey(historyEntryKey);
|
||||
|
||||
assertThat(vkey.getKind()).isEqualTo(BillingEvent.OneTime.class);
|
||||
assertThat(vkey.getOfyKey()).isEqualTo(oneTimeKey);
|
||||
assertThat(vkey.getSqlKey()).isEqualTo(200L);
|
||||
assertThat(vkey.getKind()).isEqualTo(DomainHistory.class);
|
||||
assertThat(vkey.getOfyKey()).isEqualTo(historyEntryKey);
|
||||
assertThat(vkey.getSqlKey()).isEqualTo(new DomainHistoryId("ROID-1", 10L));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 google.registry.persistence;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.BillingVKey.BillingEventVKey;
|
||||
import google.registry.persistence.BillingVKey.BillingRecurrenceVKey;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import javax.persistence.Transient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit test for {@link BillingVKey}. */
|
||||
class BillingVKeyTest {
|
||||
@RegisterExtension
|
||||
final AppEngineExtension appEngine =
|
||||
AppEngineExtension.builder()
|
||||
.withCloudSql()
|
||||
.withOfyTestEntities(BillingVKeyTestEntity.class)
|
||||
.withJpaUnitTestEntities(BillingVKeyTestEntity.class)
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void testRestoreSymmetricVKey() {
|
||||
Key<HistoryEntry> domainHistoryKey =
|
||||
Key.create(Key.create(DomainBase.class, "domainRepoId"), HistoryEntry.class, 10L);
|
||||
|
||||
Key<BillingEvent.OneTime> oneTimeOfyKey =
|
||||
Key.create(domainHistoryKey, BillingEvent.OneTime.class, 100L);
|
||||
VKey<BillingEvent.OneTime> oneTimeVKey =
|
||||
VKey.create(BillingEvent.OneTime.class, 100L, oneTimeOfyKey);
|
||||
|
||||
Key<BillingEvent.Recurring> recurringOfyKey =
|
||||
Key.create(domainHistoryKey, BillingEvent.Recurring.class, 200L);
|
||||
VKey<BillingEvent.Recurring> recurringVKey =
|
||||
VKey.create(BillingEvent.Recurring.class, 200L, recurringOfyKey);
|
||||
|
||||
BillingVKeyTestEntity original = new BillingVKeyTestEntity(oneTimeVKey, recurringVKey);
|
||||
tm().transact(() -> tm().insert(original));
|
||||
BillingVKeyTestEntity persisted = tm().transact(() -> tm().loadByKey(original.createVKey()));
|
||||
|
||||
assertThat(persisted).isEqualTo(original);
|
||||
assertThat(persisted.getBillingEventVKey()).isEqualTo(oneTimeVKey);
|
||||
assertThat(persisted.getBillingRecurrenceVKey()).isEqualTo(recurringVKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleNullVKeyCorrectly() {
|
||||
BillingVKeyTestEntity original = new BillingVKeyTestEntity(null, null);
|
||||
tm().transact(() -> tm().insert(original));
|
||||
BillingVKeyTestEntity persisted = tm().transact(() -> tm().loadByKey(original.createVKey()));
|
||||
|
||||
assertThat(persisted).isEqualTo(original);
|
||||
}
|
||||
|
||||
@Entity
|
||||
@javax.persistence.Entity
|
||||
private static class BillingVKeyTestEntity extends ImmutableObject {
|
||||
@Transient @Parent Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||
|
||||
@Id @javax.persistence.Id String id = "id";
|
||||
|
||||
BillingEventVKey billingEventVKey;
|
||||
|
||||
BillingRecurrenceVKey billingRecurrenceVKey;
|
||||
|
||||
BillingVKeyTestEntity() {}
|
||||
|
||||
BillingVKeyTestEntity(
|
||||
VKey<BillingEvent.OneTime> onetime, VKey<BillingEvent.Recurring> recurring) {
|
||||
this.billingEventVKey = BillingEventVKey.create(onetime);
|
||||
this.billingRecurrenceVKey = BillingRecurrenceVKey.create(recurring);
|
||||
}
|
||||
|
||||
VKey<BillingEvent.OneTime> getBillingEventVKey() {
|
||||
return billingEventVKey.createVKey();
|
||||
}
|
||||
|
||||
VKey<BillingEvent.Recurring> getBillingRecurrenceVKey() {
|
||||
return billingRecurrenceVKey.createVKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VKey<BillingVKeyTestEntity> createVKey() {
|
||||
return VKey.createSql(BillingVKeyTestEntity.class, id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -234,7 +234,7 @@ public class DomainBaseToXjcConverterTest {
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
||||
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build());
|
||||
domain =
|
||||
domain
|
||||
|
@ -295,7 +295,7 @@ public class DomainBaseToXjcConverterTest {
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
||||
.setBillingTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build())),
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
|
@ -319,7 +319,7 @@ public class DomainBaseToXjcConverterTest {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(END_OF_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build())
|
||||
.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
|
@ -349,7 +349,7 @@ public class DomainBaseToXjcConverterTest {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(END_OF_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(domainHistory)
|
||||
.setDomainHistory(domainHistory)
|
||||
.build())
|
||||
.createVKey())
|
||||
.setServerApproveAutorenewPollMessage(
|
||||
|
|
|
@ -84,7 +84,7 @@ final class RdeFixtures {
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
||||
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
domain =
|
||||
domain
|
||||
|
@ -138,7 +138,7 @@ final class RdeFixtures {
|
|||
.setPeriodYears(2)
|
||||
.setEventTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
||||
.setBillingTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build())),
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.TRANSFER,
|
||||
|
@ -162,7 +162,7 @@ final class RdeFixtures {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(END_OF_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build())
|
||||
.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
|
@ -192,7 +192,7 @@ final class RdeFixtures {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(END_OF_TIME)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build())
|
||||
.createVKey())
|
||||
.setServerApproveAutorenewPollMessage(
|
||||
|
|
|
@ -349,7 +349,7 @@ public class DatabaseHelper {
|
|||
Recurring recurring =
|
||||
persistResource(
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.setRenewalPrice(renewalPrice)
|
||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||
.setRegistrarId(domain.getCreationRegistrarId())
|
||||
|
@ -557,7 +557,7 @@ public class DatabaseHelper {
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setPeriodYears(1)
|
||||
.setCost(getDomainRenewCost(domain.getDomainName(), costLookupTime, 1))
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -654,7 +654,7 @@ public class DatabaseHelper {
|
|||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(expirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainCreate)
|
||||
.setDomainHistory(historyEntryDomainCreate)
|
||||
.build());
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
persistResource(
|
||||
|
@ -701,7 +701,7 @@ public class DatabaseHelper {
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setEventTime(extendedRegistrationExpirationTime)
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntryDomainTransfer)
|
||||
.setDomainHistory(historyEntryDomainTransfer)
|
||||
.build());
|
||||
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
||||
persistResource(
|
||||
|
|
|
@ -575,7 +575,7 @@ public final class DomainLockUtilsTest {
|
|||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setBillingTime(clock.nowUtc())
|
||||
.setParent(entry)
|
||||
.setDomainHistory(entry)
|
||||
.build())
|
||||
.collect(Collectors.toSet());
|
||||
DatabaseHelper.assertBillingEvents(expectedEvents);
|
||||
|
|
|
@ -150,7 +150,8 @@ class EppLifecycleToolsTest extends EppTestCase {
|
|||
.setPeriodYears(4)
|
||||
.setEventTime(DateTime.parse("2000-06-07T00:00:00Z"))
|
||||
.setBillingTime(DateTime.parse("2000-06-12T00:00:00Z"))
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class))
|
||||
.setDomainHistory(
|
||||
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class))
|
||||
.build();
|
||||
|
||||
assertBillingEventsForResource(
|
||||
|
|
|
@ -134,7 +134,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
|
|||
assertBillingEventsEqual(
|
||||
loadByKey(domain.getAutorenewBillingEvent()),
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setParent(synthetic)
|
||||
.setDomainHistory(synthetic)
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId(domain.getDomainName())
|
||||
|
|
|
@ -345,7 +345,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
|
|||
.setRegistrarId("NewRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc().minusDays(5))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(createHistoryEntry)
|
||||
.setDomainHistory(createHistoryEntry)
|
||||
.build());
|
||||
persistResource(
|
||||
domain
|
||||
|
|
|
@ -320,7 +320,7 @@ final class RegistryLockVerifyActionTest {
|
|||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setBillingTime(fakeClock.nowUtc())
|
||||
.setParent(historyEntry)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,78 +1,3 @@
|
|||
class google.registry.model.billing.BillingEvent$Cancellation {
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
||||
google.registry.model.billing.BillingEvent$Reason reason;
|
||||
google.registry.persistence.BillingVKey$BillingEventVKey refOneTime;
|
||||
google.registry.persistence.BillingVKey$BillingRecurrenceVKey refRecurring;
|
||||
java.lang.String clientId;
|
||||
java.lang.String targetId;
|
||||
java.util.Set<google.registry.model.billing.BillingEvent$Flag> flags;
|
||||
org.joda.time.DateTime billingTime;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
enum google.registry.model.billing.BillingEvent$Flag {
|
||||
ALLOCATION;
|
||||
ANCHOR_TENANT;
|
||||
AUTO_RENEW;
|
||||
LANDRUSH;
|
||||
RESERVED;
|
||||
SUNRISE;
|
||||
SYNTHETIC;
|
||||
}
|
||||
class google.registry.model.billing.BillingEvent$Modification {
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
||||
com.googlecode.objectify.Key<google.registry.model.billing.BillingEvent$OneTime> eventRef;
|
||||
google.registry.model.billing.BillingEvent$Reason reason;
|
||||
java.lang.String clientId;
|
||||
java.lang.String description;
|
||||
java.lang.String targetId;
|
||||
java.util.Set<google.registry.model.billing.BillingEvent$Flag> flags;
|
||||
org.joda.money.Money cost;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.billing.BillingEvent$OneTime {
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
||||
google.registry.model.billing.BillingEvent$Reason reason;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> cancellationMatchingBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.domain.token.AllocationToken> allocationToken;
|
||||
java.lang.Integer periodYears;
|
||||
java.lang.String clientId;
|
||||
java.lang.String targetId;
|
||||
java.util.Set<google.registry.model.billing.BillingEvent$Flag> flags;
|
||||
org.joda.money.Money cost;
|
||||
org.joda.time.DateTime billingTime;
|
||||
org.joda.time.DateTime eventTime;
|
||||
org.joda.time.DateTime syntheticCreationTime;
|
||||
}
|
||||
enum google.registry.model.billing.BillingEvent$Reason {
|
||||
CREATE;
|
||||
ERROR;
|
||||
FEE_EARLY_ACCESS;
|
||||
RENEW;
|
||||
RESTORE;
|
||||
SERVER_STATUS;
|
||||
TRANSFER;
|
||||
}
|
||||
class google.registry.model.billing.BillingEvent$Recurring {
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
||||
google.registry.model.billing.BillingEvent$Reason reason;
|
||||
google.registry.model.billing.BillingEvent$RenewalPriceBehavior renewalPriceBehavior;
|
||||
google.registry.model.common.TimeOfYear recurrenceTimeOfYear;
|
||||
java.lang.String clientId;
|
||||
java.lang.String targetId;
|
||||
java.util.Set<google.registry.model.billing.BillingEvent$Flag> flags;
|
||||
org.joda.money.Money renewalPrice;
|
||||
org.joda.time.DateTime eventTime;
|
||||
org.joda.time.DateTime recurrenceEndTime;
|
||||
}
|
||||
enum google.registry.model.billing.BillingEvent$RenewalPriceBehavior {
|
||||
DEFAULT;
|
||||
NONPREMIUM;
|
||||
SPECIFIED;
|
||||
}
|
||||
class google.registry.model.common.EntityGroupRoot {
|
||||
@Id java.lang.String id;
|
||||
}
|
||||
|
@ -80,9 +5,6 @@ class google.registry.model.common.GaeUserIdConverter {
|
|||
@Id long id;
|
||||
com.google.appengine.api.users.User user;
|
||||
}
|
||||
class google.registry.model.common.TimeOfYear {
|
||||
java.lang.String timeString;
|
||||
}
|
||||
class google.registry.model.contact.ContactAddress {
|
||||
java.lang.String city;
|
||||
java.lang.String countryCode;
|
||||
|
@ -183,7 +105,6 @@ class google.registry.model.domain.DomainBase {
|
|||
google.registry.model.domain.DomainAuthInfo authInfo;
|
||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||
google.registry.model.transfer.DomainTransferData transferData;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> autorenewBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> adminContact;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> registrantContact;
|
||||
|
@ -213,7 +134,6 @@ class google.registry.model.domain.DomainContent {
|
|||
google.registry.model.domain.DomainAuthInfo authInfo;
|
||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||
google.registry.model.transfer.DomainTransferData transferData;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> autorenewBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> adminContact;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> registrantContact;
|
||||
|
@ -259,16 +179,12 @@ class google.registry.model.domain.DomainHistory {
|
|||
}
|
||||
class google.registry.model.domain.GracePeriod {
|
||||
google.registry.model.domain.rgp.GracePeriodStatus type;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$OneTime> billingEventOneTime;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> billingEventRecurring;
|
||||
java.lang.String clientId;
|
||||
long gracePeriodId;
|
||||
org.joda.time.DateTime expirationTime;
|
||||
}
|
||||
class google.registry.model.domain.GracePeriod$GracePeriodHistory {
|
||||
google.registry.model.domain.rgp.GracePeriodStatus type;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$OneTime> billingEventOneTime;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> billingEventRecurring;
|
||||
java.lang.Long domainHistoryRevisionId;
|
||||
java.lang.Long gracePeriodHistoryRevisionId;
|
||||
java.lang.String clientId;
|
||||
|
@ -319,7 +235,6 @@ class google.registry.model.domain.token.AllocationToken {
|
|||
@Id java.lang.String token;
|
||||
boolean discountPremiums;
|
||||
double discountFraction;
|
||||
google.registry.model.billing.BillingEvent$RenewalPriceBehavior renewalPriceBehavior;
|
||||
google.registry.model.common.TimedTransitionProperty<google.registry.model.domain.token.AllocationToken$TokenStatus> tokenStatusTransitions;
|
||||
google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior;
|
||||
google.registry.model.domain.token.AllocationToken$TokenType tokenType;
|
||||
|
@ -626,8 +541,6 @@ class google.registry.model.transfer.DomainTransferData {
|
|||
google.registry.model.domain.Period transferPeriod;
|
||||
google.registry.model.eppcommon.Trid transferRequestTrid;
|
||||
google.registry.model.transfer.TransferStatus transferStatus;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$OneTime> serverApproveBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> serverApproveAutorenewEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.poll.PollMessage$Autorenew> serverApproveAutorenewPollMessage;
|
||||
java.lang.String gainingClientId;
|
||||
java.lang.String losingClientId;
|
||||
|
@ -643,16 +556,6 @@ enum google.registry.model.transfer.TransferStatus {
|
|||
SERVER_APPROVED;
|
||||
SERVER_CANCELLED;
|
||||
}
|
||||
class google.registry.persistence.BillingVKey$BillingEventVKey {
|
||||
java.lang.Long billingId;
|
||||
java.lang.Long historyRevisionId;
|
||||
java.lang.String repoId;
|
||||
}
|
||||
class google.registry.persistence.BillingVKey$BillingRecurrenceVKey {
|
||||
java.lang.Long billingId;
|
||||
java.lang.Long historyRevisionId;
|
||||
java.lang.String repoId;
|
||||
}
|
||||
class google.registry.persistence.DomainHistoryVKey {
|
||||
java.lang.Long historyRevisionId;
|
||||
java.lang.String repoId;
|
||||
|
|
|
@ -42,11 +42,7 @@
|
|||
domain_name text not null,
|
||||
billing_time timestamptz,
|
||||
billing_event_id int8,
|
||||
billing_event_history_id int8,
|
||||
billing_event_domain_repo_id text,
|
||||
billing_recurrence_id int8,
|
||||
billing_recurrence_history_id int8,
|
||||
billing_recurrence_domain_repo_id text,
|
||||
primary key (billing_cancellation_id)
|
||||
);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.lang.model.SourceVersion;
|
|||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
public class LongVKeyProcessor extends AbstractVKeyProcessor {
|
||||
|
||||
private static final String ANNOTATION_SIMPLE_NAME = "WithStringVKey";
|
||||
private static final String ANNOTATION_SIMPLE_NAME = "WithLongVKey";
|
||||
|
||||
@Override
|
||||
Class<?> getSqlColumnType() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue