mirror of
https://github.com/google/nomulus.git
synced 2025-07-09 12:43:24 +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 =
|
final ImmutableSet<DateTime> billingTimes =
|
||||||
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
||||||
|
|
||||||
VKey<DomainBase> domainKey =
|
VKey<DomainBase> domainKey = VKey.createSql(DomainBase.class, recurring.getDomainRepoId());
|
||||||
VKey.create(
|
|
||||||
DomainBase.class, recurring.getDomainRepoId(), recurring.getParentKey().getParent());
|
|
||||||
Iterable<OneTime> oneTimesForDomain;
|
Iterable<OneTime> oneTimesForDomain;
|
||||||
oneTimesForDomain =
|
oneTimesForDomain =
|
||||||
tm().createQueryComposer(OneTime.class)
|
tm().createQueryComposer(OneTime.class)
|
||||||
|
@ -311,11 +309,11 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||||
.getRenewCost())
|
.getRenewCost())
|
||||||
.setEventTime(eventTime)
|
.setEventTime(eventTime)
|
||||||
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setReason(recurring.getReason())
|
.setReason(recurring.getReason())
|
||||||
.setSyntheticCreationTime(executeTime)
|
.setSyntheticCreationTime(executeTime)
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.setTargetId(recurring.getTargetId())
|
.setTargetId(recurring.getTargetId())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,47 +14,38 @@
|
||||||
|
|
||||||
package google.registry.beam.invoicing;
|
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.auto.value.AutoValue;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
|
||||||
import google.registry.reporting.billing.BillingModule;
|
import google.registry.reporting.billing.BillingModule;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.text.DecimalFormat;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.apache.avro.generic.GenericRecord;
|
|
||||||
import org.apache.beam.sdk.coders.AtomicCoder;
|
import org.apache.beam.sdk.coders.AtomicCoder;
|
||||||
import org.apache.beam.sdk.coders.Coder;
|
import org.apache.beam.sdk.coders.Coder;
|
||||||
import org.apache.beam.sdk.coders.StringUtf8Coder;
|
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.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}.
|
* 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
|
* <p>This is a trivially serializable class that allows Beam to transform the results of a Cloud
|
||||||
* query into a standard Java representation, giving us the type guarantees and ease of manipulation
|
* SQL query into a standard Java representation, giving us the type guarantees and ease of
|
||||||
* Bigquery lacks, while localizing any Bigquery-side failures to the {@link #parseFromRecord}
|
* manipulation Cloud SQL lacks.
|
||||||
* function.
|
|
||||||
*/
|
*/
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class BillingEvent implements Serializable {
|
public abstract class BillingEvent implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3593088371541450077L;
|
||||||
|
|
||||||
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
||||||
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz");
|
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 Pattern SYNTHETIC_REGEX = Pattern.compile("SYNTHETIC", Pattern.LITERAL);
|
||||||
private static final double SUNRISE_DISCOUNT_PRICE_MODIFIER = 0.85;
|
|
||||||
|
|
||||||
private static final ImmutableList<String> FIELD_NAMES =
|
private static final ImmutableList<String> FIELD_NAMES =
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
|
@ -115,67 +106,7 @@ public abstract class BillingEvent implements Serializable {
|
||||||
/** Returns a list of space-delimited flags associated with the event. */
|
/** Returns a list of space-delimited flags associated with the event. */
|
||||||
abstract String flags();
|
abstract String flags();
|
||||||
|
|
||||||
/**
|
/** Creates a concrete {@link BillingEvent}. */
|
||||||
* 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
|
|
||||||
static BillingEvent create(
|
static BillingEvent create(
|
||||||
long id,
|
long id,
|
||||||
DateTime billingTime,
|
DateTime billingTime,
|
||||||
|
@ -209,7 +140,7 @@ public abstract class BillingEvent implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getHeader() {
|
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(),
|
currency(),
|
||||||
String.format("%.2f", amount()),
|
String.format("%.2f", amount()),
|
||||||
// Strip out the 'synthetic' flag, which is internal only.
|
// 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. */
|
/** Returns the grouping key for this {@code BillingEvent}, to generate the overall invoice. */
|
||||||
|
@ -274,6 +205,8 @@ public abstract class BillingEvent implements Serializable {
|
||||||
@AutoValue
|
@AutoValue
|
||||||
abstract static class InvoiceGroupingKey implements Serializable {
|
abstract static class InvoiceGroupingKey implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -151561764235256205L;
|
||||||
|
|
||||||
private static final ImmutableList<String> INVOICE_HEADERS =
|
private static final ImmutableList<String> INVOICE_HEADERS =
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
"StartDate",
|
"StartDate",
|
||||||
|
@ -345,6 +278,8 @@ public abstract class BillingEvent implements Serializable {
|
||||||
/** Coder that provides deterministic (de)serialization for {@code InvoiceGroupingKey}. */
|
/** Coder that provides deterministic (de)serialization for {@code InvoiceGroupingKey}. */
|
||||||
static class InvoiceGroupingKeyCoder extends AtomicCoder<InvoiceGroupingKey> {
|
static class InvoiceGroupingKeyCoder extends AtomicCoder<InvoiceGroupingKey> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6680701524304107547L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(InvoiceGroupingKey value, OutputStream outStream) throws IOException {
|
public void encode(InvoiceGroupingKey value, OutputStream outStream) throws IOException {
|
||||||
Coder<String> stringCoder = StringUtf8Coder.of();
|
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;
|
||||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
|
import google.registry.model.billing.BillingEvent.OneTime;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||||
import google.registry.reporting.billing.BillingModule;
|
import google.registry.reporting.billing.BillingModule;
|
||||||
import google.registry.util.DomainNameUtils;
|
import google.registry.util.DomainNameUtils;
|
||||||
import google.registry.util.SqlTemplate;
|
import google.registry.util.SqlTemplate;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.YearMonth;
|
import java.time.YearMonth;
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -66,8 +64,7 @@ import org.joda.money.CurrencyUnit;
|
||||||
*/
|
*/
|
||||||
public class InvoicingPipeline implements Serializable {
|
public class InvoicingPipeline implements Serializable {
|
||||||
|
|
||||||
private static final DateTimeFormatter TIMESTAMP_FORMATTER =
|
private static final long serialVersionUID = 5386330443625580081L;
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
|
|
||||||
|
|
||||||
private static final Pattern SQL_COMMENT_REGEX =
|
private static final Pattern SQL_COMMENT_REGEX =
|
||||||
Pattern.compile("^\\s*--.*\\n", Pattern.MULTILINE);
|
Pattern.compile("^\\s*--.*\\n", Pattern.MULTILINE);
|
||||||
|
@ -107,8 +104,7 @@ public class InvoicingPipeline implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<BillingEvent> parseRow(Object[] row) {
|
private static Optional<BillingEvent> parseRow(Object[] row) {
|
||||||
google.registry.model.billing.BillingEvent.OneTime oneTime =
|
OneTime oneTime = (OneTime) row[0];
|
||||||
(google.registry.model.billing.BillingEvent.OneTime) row[0];
|
|
||||||
Registrar registrar = (Registrar) row[1];
|
Registrar registrar = (Registrar) row[1];
|
||||||
CurrencyUnit currency = oneTime.getCost().getCurrencyUnit();
|
CurrencyUnit currency = oneTime.getCost().getCurrencyUnit();
|
||||||
if (!registrar.getBillingAccountMap().containsKey(currency)) {
|
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. */
|
/** Transform that converts a {@code BillingEvent} into an invoice CSV row. */
|
||||||
private static class GenerateInvoiceRows
|
private static class GenerateInvoiceRows
|
||||||
extends PTransform<PCollection<BillingEvent>, PCollection<String>> {
|
extends PTransform<PCollection<BillingEvent>, PCollection<String>> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8090619008258393728L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PCollection<String> expand(PCollection<BillingEvent> input) {
|
public PCollection<String> expand(PCollection<BillingEvent> input) {
|
||||||
return input
|
return input
|
||||||
|
@ -203,32 +202,13 @@ public class InvoicingPipeline implements Serializable {
|
||||||
TextIO.sink().withHeader(BillingEvent.getHeader())));
|
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. */
|
/** Create the Cloud SQL query for a given yearMonth at runtime. */
|
||||||
static String makeCloudSqlQuery(String yearMonth) {
|
static String makeCloudSqlQuery(String yearMonth) {
|
||||||
YearMonth endMonth = YearMonth.parse(yearMonth).plusMonths(1);
|
YearMonth endMonth = YearMonth.parse(yearMonth).plusMonths(1);
|
||||||
String queryWithComments =
|
String queryWithComments =
|
||||||
SqlTemplate.create(
|
SqlTemplate.create(
|
||||||
getQueryFromFile(InvoicingPipeline.class, "cloud_sql_billing_events.sql"))
|
getQueryFromFile(InvoicingPipeline.class, "cloud_sql_billing_events.sql"))
|
||||||
.put("FIRST_TIMESTAMP_OF_MONTH", yearMonth.concat("-01"))
|
.put("FIRST_TIMESTAMP_OF_MONTH", yearMonth + "-01")
|
||||||
.put(
|
.put(
|
||||||
"LAST_TIMESTAMP_OF_MONTH",
|
"LAST_TIMESTAMP_OF_MONTH",
|
||||||
String.format("%d-%d-01", endMonth.getYear(), endMonth.getMonthValue()))
|
String.format("%d-%d-01", endMonth.getYear(), endMonth.getMonthValue()))
|
||||||
|
|
|
@ -333,9 +333,9 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||||
DateTime registrationExpirationTime = leapSafeAddYears(now, years);
|
DateTime registrationExpirationTime = leapSafeAddYears(now, years);
|
||||||
String repoId = createDomainRepoId(allocateId(), registry.getTldStr());
|
String repoId = createDomainRepoId(allocateId(), registry.getTldStr());
|
||||||
Key<DomainHistory> domainHistoryKey =
|
long historyRevisionId = allocateId();
|
||||||
Key.create(Key.create(DomainBase.class, repoId), DomainHistory.class, allocateId());
|
DomainHistoryId domainHistoryId = new DomainHistoryId(repoId, historyRevisionId);
|
||||||
historyBuilder.setId(domainHistoryKey.getId());
|
historyBuilder.setId(historyRevisionId);
|
||||||
// Bill for the create.
|
// Bill for the create.
|
||||||
BillingEvent.OneTime createBillingEvent =
|
BillingEvent.OneTime createBillingEvent =
|
||||||
createOneTimeBillingEvent(
|
createOneTimeBillingEvent(
|
||||||
|
@ -345,17 +345,17 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
isReserved(domainName, isSunriseCreate),
|
isReserved(domainName, isSunriseCreate),
|
||||||
years,
|
years,
|
||||||
feesAndCredits,
|
feesAndCredits,
|
||||||
domainHistoryKey,
|
domainHistoryId,
|
||||||
allocationToken,
|
allocationToken,
|
||||||
now);
|
now);
|
||||||
// Create a new autorenew billing event and poll message starting at the expiration time.
|
// Create a new autorenew billing event and poll message starting at the expiration time.
|
||||||
BillingEvent.Recurring autorenewBillingEvent =
|
BillingEvent.Recurring autorenewBillingEvent =
|
||||||
createAutorenewBillingEvent(
|
createAutorenewBillingEvent(
|
||||||
domainHistoryKey,
|
domainHistoryId,
|
||||||
registrationExpirationTime,
|
registrationExpirationTime,
|
||||||
getRenewalPriceInfo(isAnchorTenant, allocationToken, feesAndCredits));
|
getRenewalPriceInfo(isAnchorTenant, allocationToken, feesAndCredits));
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
createAutorenewPollMessage(domainHistoryKey, registrationExpirationTime);
|
createAutorenewPollMessage(domainHistoryId, registrationExpirationTime);
|
||||||
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
||||||
entitiesToSave.add(createBillingEvent, autorenewBillingEvent, autorenewPollMessage);
|
entitiesToSave.add(createBillingEvent, autorenewBillingEvent, autorenewPollMessage);
|
||||||
// Bill for EAP cost, if any.
|
// Bill for EAP cost, if any.
|
||||||
|
@ -552,7 +552,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
boolean isReserved,
|
boolean isReserved,
|
||||||
int years,
|
int years,
|
||||||
FeesAndCredits feesAndCredits,
|
FeesAndCredits feesAndCredits,
|
||||||
Key<DomainHistory> domainHistoryKey,
|
DomainHistoryId domainHistoryId,
|
||||||
Optional<AllocationToken> allocationToken,
|
Optional<AllocationToken> allocationToken,
|
||||||
DateTime now) {
|
DateTime now) {
|
||||||
ImmutableSet.Builder<Flag> flagsBuilder = new ImmutableSet.Builder<>();
|
ImmutableSet.Builder<Flag> flagsBuilder = new ImmutableSet.Builder<>();
|
||||||
|
@ -581,12 +581,12 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
? registry.getAnchorTenantAddGracePeriodLength()
|
? registry.getAnchorTenantAddGracePeriodLength()
|
||||||
: registry.getAddGracePeriodLength()))
|
: registry.getAddGracePeriodLength()))
|
||||||
.setFlags(flagsBuilder.build())
|
.setFlags(flagsBuilder.build())
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(domainHistoryId)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Recurring createAutorenewBillingEvent(
|
private Recurring createAutorenewBillingEvent(
|
||||||
Key<DomainHistory> domainHistoryKey,
|
DomainHistoryId domainHistoryId,
|
||||||
DateTime registrationExpirationTime,
|
DateTime registrationExpirationTime,
|
||||||
RenewalPriceInfo renewalpriceInfo) {
|
RenewalPriceInfo renewalpriceInfo) {
|
||||||
return new BillingEvent.Recurring.Builder()
|
return new BillingEvent.Recurring.Builder()
|
||||||
|
@ -596,21 +596,20 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
.setRegistrarId(registrarId)
|
.setRegistrarId(registrarId)
|
||||||
.setEventTime(registrationExpirationTime)
|
.setEventTime(registrationExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(domainHistoryId)
|
||||||
.setRenewalPriceBehavior(renewalpriceInfo.renewalPriceBehavior())
|
.setRenewalPriceBehavior(renewalpriceInfo.renewalPriceBehavior())
|
||||||
.setRenewalPrice(renewalpriceInfo.renewalPrice())
|
.setRenewalPrice(renewalpriceInfo.renewalPrice())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Autorenew createAutorenewPollMessage(
|
private Autorenew createAutorenewPollMessage(
|
||||||
Key<DomainHistory> domainHistoryKey, DateTime registrationExpirationTime) {
|
DomainHistoryId domainHistoryId, DateTime registrationExpirationTime) {
|
||||||
return new PollMessage.Autorenew.Builder()
|
return new PollMessage.Autorenew.Builder()
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
.setRegistrarId(registrarId)
|
.setRegistrarId(registrarId)
|
||||||
.setEventTime(registrationExpirationTime)
|
.setEventTime(registrationExpirationTime)
|
||||||
.setMsg("Domain was auto-renewed.")
|
.setMsg("Domain was auto-renewed.")
|
||||||
.setDomainHistoryId(
|
.setDomainHistoryId(domainHistoryId)
|
||||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +624,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||||
.setEventTime(createBillingEvent.getEventTime())
|
.setEventTime(createBillingEvent.getEventTime())
|
||||||
.setBillingTime(createBillingEvent.getBillingTime())
|
.setBillingTime(createBillingEvent.getBillingTime())
|
||||||
.setFlags(createBillingEvent.getFlags())
|
.setFlags(createBillingEvent.getFlags())
|
||||||
.setParent(createBillingEvent.getParentKey())
|
.setDomainHistoryId(createBillingEvent.getDomainHistoryId())
|
||||||
.build();
|
.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.
|
// No cancellation is written if the grace period was not for a billable event.
|
||||||
if (gracePeriod.hasBillingEvent()) {
|
if (gracePeriod.hasBillingEvent()) {
|
||||||
entitiesToSave.add(
|
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) {
|
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
||||||
// Take the amount of amount of registration time being refunded off the expiration time.
|
// 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.
|
// This can be either add grace periods or renew grace periods.
|
||||||
|
|
|
@ -210,7 +210,9 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setRenewalPrice(existingRecurringBillingEvent.getRenewalPrice().orElse(null))
|
.setRenewalPrice(existingRecurringBillingEvent.getRenewalPrice().orElse(null))
|
||||||
.setRenewalPriceBehavior(existingRecurringBillingEvent.getRenewalPriceBehavior())
|
.setRenewalPriceBehavior(existingRecurringBillingEvent.getRenewalPriceBehavior())
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(
|
||||||
|
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build();
|
.build();
|
||||||
PollMessage.Autorenew newAutorenewPollMessage =
|
PollMessage.Autorenew newAutorenewPollMessage =
|
||||||
newAutorenewPollMessage(existingDomain)
|
newAutorenewPollMessage(existingDomain)
|
||||||
|
@ -332,7 +334,8 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null))
|
.setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null))
|
||||||
.setBillingTime(now.plus(Registry.get(tld).getRenewGracePeriodLength()))
|
.setBillingTime(now.plus(Registry.get(tld).getRenewGracePeriodLength()))
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||||
verifyRestoreAllowed(command, existingDomain, feeUpdate, feesAndCredits, now);
|
verifyRestoreAllowed(command, existingDomain, feeUpdate, feesAndCredits, now);
|
||||||
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
||||||
historyBuilder.setId(domainHistoryKey.getId());
|
historyBuilder.setId(domainHistoryKey.getId());
|
||||||
|
DomainHistoryId domainHistoryId =
|
||||||
|
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId());
|
||||||
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
||||||
|
|
||||||
DateTime newExpirationTime =
|
DateTime newExpirationTime =
|
||||||
|
@ -158,17 +160,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||||
// a year and bill for it immediately, with no grace period.
|
// a year and bill for it immediately, with no grace period.
|
||||||
if (isExpired) {
|
if (isExpired) {
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
createRenewBillingEvent(domainHistoryKey, feesAndCredits.getRenewCost(), now));
|
createRenewBillingEvent(domainHistoryId, feesAndCredits.getRenewCost(), now));
|
||||||
}
|
}
|
||||||
// Always bill for the restore itself.
|
// Always bill for the restore itself.
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
createRestoreBillingEvent(domainHistoryKey, feesAndCredits.getRestoreCost(), now));
|
createRestoreBillingEvent(domainHistoryId, feesAndCredits.getRestoreCost(), now));
|
||||||
|
|
||||||
BillingEvent.Recurring autorenewEvent =
|
BillingEvent.Recurring autorenewEvent =
|
||||||
newAutorenewBillingEvent(existingDomain)
|
newAutorenewBillingEvent(existingDomain)
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(domainHistoryId)
|
||||||
.build();
|
.build();
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
newAutorenewPollMessage(existingDomain)
|
newAutorenewPollMessage(existingDomain)
|
||||||
|
@ -259,19 +261,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
private OneTime createRenewBillingEvent(
|
private OneTime createRenewBillingEvent(
|
||||||
Key<DomainHistory> domainHistoryKey, Money renewCost, DateTime now) {
|
DomainHistoryId domainHistoryId, Money renewCost, DateTime now) {
|
||||||
return prepareBillingEvent(domainHistoryKey, renewCost, now).setReason(Reason.RENEW).build();
|
return prepareBillingEvent(domainHistoryId, renewCost, now).setReason(Reason.RENEW).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BillingEvent.OneTime createRestoreBillingEvent(
|
private BillingEvent.OneTime createRestoreBillingEvent(
|
||||||
Key<DomainHistory> domainHistoryKey, Money restoreCost, DateTime now) {
|
DomainHistoryId domainHistoryId, Money restoreCost, DateTime now) {
|
||||||
return prepareBillingEvent(domainHistoryKey, restoreCost, now)
|
return prepareBillingEvent(domainHistoryId, restoreCost, now).setReason(Reason.RESTORE).build();
|
||||||
.setReason(Reason.RESTORE)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private OneTime.Builder prepareBillingEvent(
|
private OneTime.Builder prepareBillingEvent(
|
||||||
Key<DomainHistory> domainHistoryKey, Money cost, DateTime now) {
|
DomainHistoryId domainHistoryId, Money cost, DateTime now) {
|
||||||
return new BillingEvent.OneTime.Builder()
|
return new BillingEvent.OneTime.Builder()
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
.setRegistrarId(registrarId)
|
.setRegistrarId(registrarId)
|
||||||
|
@ -279,7 +279,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||||
.setBillingTime(now)
|
.setBillingTime(now)
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setCost(cost)
|
.setCost(cost)
|
||||||
.setParent(domainHistoryKey);
|
.setDomainHistoryId(domainHistoryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImmutableList<FeeTransformResponseExtension> createResponseExtensions(
|
private static ImmutableList<FeeTransformResponseExtension> createResponseExtensions(
|
||||||
|
|
|
@ -123,7 +123,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
Key<DomainHistory> domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class);
|
||||||
historyBuilder.setId(domainHistoryKey.getId());
|
historyBuilder.setId(domainHistoryKey.getId());
|
||||||
Optional<BillingEvent.OneTime> billingEvent =
|
Optional<BillingEvent.OneTime> billingEvent =
|
||||||
(transferData.getTransferPeriod().getValue() == 0)
|
transferData.getTransferPeriod().getValue() == 0
|
||||||
? Optional.empty()
|
? Optional.empty()
|
||||||
: Optional.of(
|
: Optional.of(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
|
@ -134,7 +134,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||||
.setCost(getDomainRenewCost(targetId, transferData.getTransferRequestTime(), 1))
|
.setCost(getDomainRenewCost(targetId, transferData.getTransferRequestTime(), 1))
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
.setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength()))
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(
|
||||||
|
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build());
|
.build());
|
||||||
ImmutableList.Builder<ImmutableObject> entitiesToSave = new ImmutableList.Builder<>();
|
ImmutableList.Builder<ImmutableObject> entitiesToSave = new ImmutableList.Builder<>();
|
||||||
// If we are within an autorenew grace period, cancel the autorenew billing event and don't
|
// 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()) {
|
if (billingEvent.isPresent()) {
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
BillingEvent.Cancellation.forGracePeriod(
|
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
|
// 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)
|
.setRegistrarId(gainingRegistrarId)
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(
|
||||||
|
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build();
|
.build();
|
||||||
// Create a new autorenew poll message.
|
// Create a new autorenew poll message.
|
||||||
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
||||||
|
|
|
@ -250,7 +250,8 @@ public final class DomainTransferUtils {
|
||||||
.setRegistrarId(gainingRegistrarId)
|
.setRegistrarId(gainingRegistrarId)
|
||||||
.setEventTime(serverApproveNewExpirationTime)
|
.setEventTime(serverApproveNewExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +286,11 @@ public final class DomainTransferUtils {
|
||||||
if (autorenewGracePeriod != null && transferCost.isPresent()) {
|
if (autorenewGracePeriod != null && transferCost.isPresent()) {
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
BillingEvent.Cancellation.forGracePeriod(
|
BillingEvent.Cancellation.forGracePeriod(
|
||||||
autorenewGracePeriod, now, domainHistoryKey, targetId)
|
autorenewGracePeriod,
|
||||||
|
now,
|
||||||
|
new DomainHistoryId(
|
||||||
|
domainHistoryKey.getParent().getName(), domainHistoryKey.getId()),
|
||||||
|
targetId)
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setEventTime(automaticTransferTime)
|
.setEventTime(automaticTransferTime)
|
||||||
.build());
|
.build());
|
||||||
|
@ -308,7 +313,8 @@ public final class DomainTransferUtils {
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setEventTime(automaticTransferTime)
|
.setEventTime(automaticTransferTime)
|
||||||
.setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength()))
|
.setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength()))
|
||||||
.setParent(domainHistoryKey)
|
.setDomainHistoryId(
|
||||||
|
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
|
||||||
.setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost())
|
.setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost())
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setBillingTime(now)
|
.setBillingTime(now)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static google.registry.model.IdService.allocateId;
|
||||||
import static google.registry.model.ModelUtils.getAllFields;
|
import static google.registry.model.ModelUtils.getAllFields;
|
||||||
|
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
import google.registry.model.annotations.OfyIdAllocation;
|
||||||
import google.registry.util.TypeUtils.TypeInstantiator;
|
import google.registry.util.TypeUtils.TypeInstantiator;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Optional;
|
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.
|
// any entity it has one and only one @Id field in its class hierarchy.
|
||||||
Field idField =
|
Field idField =
|
||||||
getAllFields(instance.getClass()).values().stream()
|
getAllFields(instance.getClass()).values().stream()
|
||||||
.filter(field -> field.isAnnotationPresent(Id.class))
|
.filter(
|
||||||
|
field ->
|
||||||
|
field.isAnnotationPresent(Id.class)
|
||||||
|
|| field.isAnnotationPresent(OfyIdAllocation.class))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (idField != null
|
if (idField != null
|
||||||
|
|
|
@ -16,7 +16,6 @@ package google.registry.model;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import google.registry.model.annotations.DeleteAfterMigration;
|
import google.registry.model.annotations.DeleteAfterMigration;
|
||||||
import google.registry.model.billing.BillingEvent;
|
|
||||||
import google.registry.model.common.EntityGroupRoot;
|
import google.registry.model.common.EntityGroupRoot;
|
||||||
import google.registry.model.common.GaeUserIdConverter;
|
import google.registry.model.common.GaeUserIdConverter;
|
||||||
import google.registry.model.contact.ContactHistory;
|
import google.registry.model.contact.ContactHistory;
|
||||||
|
@ -44,10 +43,6 @@ public final class EntityClasses {
|
||||||
public static final ImmutableSet<Class<? extends ImmutableObject>> ALL_CLASSES =
|
public static final ImmutableSet<Class<? extends ImmutableObject>> ALL_CLASSES =
|
||||||
ImmutableSet.of(
|
ImmutableSet.of(
|
||||||
AllocationToken.class,
|
AllocationToken.class,
|
||||||
BillingEvent.Cancellation.class,
|
|
||||||
BillingEvent.Modification.class,
|
|
||||||
BillingEvent.OneTime.class,
|
|
||||||
BillingEvent.Recurring.class,
|
|
||||||
ContactHistory.class,
|
ContactHistory.class,
|
||||||
ContactResource.class,
|
ContactResource.class,
|
||||||
DomainBase.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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
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.forceEmptyToNull;
|
||||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
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.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
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.Buildable;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.UnsafeSerializable;
|
import google.registry.model.UnsafeSerializable;
|
||||||
|
import google.registry.model.annotations.OfyIdAllocation;
|
||||||
import google.registry.model.annotations.ReportedOn;
|
import google.registry.model.annotations.ReportedOn;
|
||||||
import google.registry.model.common.TimeOfYear;
|
import google.registry.model.common.TimeOfYear;
|
||||||
import google.registry.model.domain.DomainBase;
|
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
|
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||||
import google.registry.model.domain.GracePeriod;
|
import google.registry.model.domain.GracePeriod;
|
||||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||||
import google.registry.model.domain.token.AllocationToken;
|
import google.registry.model.domain.token.AllocationToken;
|
||||||
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
|
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.VKey;
|
||||||
import google.registry.persistence.WithLongVKey;
|
import google.registry.persistence.WithLongVKey;
|
||||||
import google.registry.persistence.converter.JodaMoneyType;
|
import google.registry.persistence.converter.JodaMoneyType;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -58,11 +47,13 @@ import javax.persistence.AttributeOverride;
|
||||||
import javax.persistence.AttributeOverrides;
|
import javax.persistence.AttributeOverrides;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embedded;
|
import javax.persistence.Embedded;
|
||||||
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Index;
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
import javax.persistence.PostLoad;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
|
||||||
import org.hibernate.annotations.Columns;
|
import org.hibernate.annotations.Columns;
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
import org.joda.money.Money;
|
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. */
|
/** The reason for the bill, which maps 1:1 to skus in go/registry-billing-skus. */
|
||||||
public enum Reason {
|
public enum Reason {
|
||||||
CREATE(true),
|
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),
|
ERROR(false),
|
||||||
FEE_EARLY_ACCESS(true),
|
FEE_EARLY_ACCESS(true),
|
||||||
RENEW(true),
|
RENEW(true),
|
||||||
|
@ -105,9 +96,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
ALLOCATION,
|
ALLOCATION,
|
||||||
ANCHOR_TENANT,
|
ANCHOR_TENANT,
|
||||||
AUTO_RENEW,
|
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,
|
LANDRUSH,
|
||||||
/**
|
/**
|
||||||
* This flag is used on create {@link OneTime} billing events for domains that were reserved.
|
* 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
|
* This flag will be added to any {@link OneTime} events that are created via, e.g., an
|
||||||
* automated process to expand {@link Recurring} events.
|
* automated process to expand {@link Recurring} events.
|
||||||
*/
|
*/
|
||||||
SYNTHETIC;
|
SYNTHETIC
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,37 +138,30 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
*/
|
*/
|
||||||
NONPREMIUM,
|
NONPREMIUM,
|
||||||
/**
|
/**
|
||||||
* This indicates that the renewalPrice in {@link BillingEvent.Recurring} will be used for
|
* This indicates that the renewalPrice in {@link Recurring} will be used for domain renewal.
|
||||||
* domain renewal.
|
|
||||||
*
|
*
|
||||||
* <p>The renewalPrice has a non-null value iff the price behavior is set to "SPECIFIED". This
|
* <p>The renewalPrice has a non-null value iff the price behavior is set to "SPECIFIED". This
|
||||||
* behavior is used with internal registrations.
|
* behavior is used with internal registrations.
|
||||||
*/
|
*/
|
||||||
SPECIFIED;
|
SPECIFIED
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Entity id. */
|
/** Entity id. */
|
||||||
@Id @javax.persistence.Id Long id;
|
@OfyIdAllocation @Id Long id;
|
||||||
|
|
||||||
@Parent @DoNotHydrate @Transient Key<DomainHistory> parent;
|
|
||||||
|
|
||||||
/** The registrar to bill. */
|
/** The registrar to bill. */
|
||||||
@Index
|
|
||||||
@Column(name = "registrarId", nullable = false)
|
@Column(name = "registrarId", nullable = false)
|
||||||
String clientId;
|
String clientId;
|
||||||
|
|
||||||
/** Revision id of the entry in DomainHistory table that ths bill belongs to. */
|
/** Revision id of the entry in DomainHistory table that ths bill belongs to. */
|
||||||
@Ignore
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
Long domainHistoryRevisionId;
|
Long domainHistoryRevisionId;
|
||||||
|
|
||||||
/** ID of the EPP resource that the bill is for. */
|
/** ID of the EPP resource that the bill is for. */
|
||||||
@Ignore
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
String domainRepoId;
|
String domainRepoId;
|
||||||
|
|
||||||
/** When this event was created. For recurring events, this is also the recurrence start time. */
|
/** When this event was created. For recurring events, this is also the recurrence start time. */
|
||||||
@Index
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
DateTime eventTime;
|
DateTime eventTime;
|
||||||
|
|
||||||
|
@ -192,17 +174,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
@Column(name = "domain_name", nullable = false)
|
@Column(name = "domain_name", nullable = false)
|
||||||
String targetId;
|
String targetId;
|
||||||
|
|
||||||
@Nullable
|
@Nullable Set<Flag> flags;
|
||||||
Set<Flag> flags;
|
|
||||||
|
|
||||||
@PostLoad
|
|
||||||
void postLoad() {
|
|
||||||
parent =
|
|
||||||
Key.create(
|
|
||||||
Key.create(DomainBase.class, domainRepoId),
|
|
||||||
DomainHistory.class,
|
|
||||||
domainHistoryRevisionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegistrarId() {
|
public String getRegistrarId() {
|
||||||
return clientId;
|
return clientId;
|
||||||
|
@ -232,8 +204,8 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
return targetId;
|
return targetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Key<DomainHistory> getParentKey() {
|
public DomainHistoryId getDomainHistoryId() {
|
||||||
return parent;
|
return new DomainHistoryId(domainRepoId, domainHistoryRevisionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableSet<Flag> getFlags() {
|
public ImmutableSet<Flag> getFlags() {
|
||||||
|
@ -269,16 +241,6 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
return thisCastToDerived();
|
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) {
|
public B setEventTime(DateTime eventTime) {
|
||||||
getInstance().eventTime = eventTime;
|
getInstance().eventTime = eventTime;
|
||||||
return thisCastToDerived();
|
return thisCastToDerived();
|
||||||
|
@ -294,14 +256,14 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
return thisCastToDerived();
|
return thisCastToDerived();
|
||||||
}
|
}
|
||||||
|
|
||||||
public B setParent(DomainHistory parent) {
|
public B setDomainHistoryId(DomainHistoryId domainHistoryId) {
|
||||||
getInstance().parent = Key.create(parent);
|
getInstance().domainHistoryRevisionId = domainHistoryId.getId();
|
||||||
|
getInstance().domainRepoId = domainHistoryId.getDomainRepoId();
|
||||||
return thisCastToDerived();
|
return thisCastToDerived();
|
||||||
}
|
}
|
||||||
|
|
||||||
public B setParent(Key<DomainHistory> parentKey) {
|
public B setDomainHistory(DomainHistory domainHistory) {
|
||||||
getInstance().parent = parentKey;
|
return setDomainHistoryId(domainHistory.getDomainHistoryId());
|
||||||
return thisCastToDerived();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -311,29 +273,23 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
checkNotNull(instance.clientId, "Registrar ID must be set");
|
checkNotNull(instance.clientId, "Registrar ID must be set");
|
||||||
checkNotNull(instance.eventTime, "Event time must be set");
|
checkNotNull(instance.eventTime, "Event time must be set");
|
||||||
checkNotNull(instance.targetId, "Target ID must be set");
|
checkNotNull(instance.targetId, "Target ID must be set");
|
||||||
checkNotNull(instance.parent, "Parent must be set");
|
checkNotNull(instance.domainHistoryRevisionId, "Domain History Revision ID must be set");
|
||||||
checkNotNull(instance.parent.getParent(), "parent.getParent() must be set");
|
checkNotNull(instance.domainRepoId, "Domain Repo ID 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();
|
|
||||||
return super.build();
|
return super.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A one-time billable event. */
|
/** A one-time billable event. */
|
||||||
@ReportedOn
|
@Entity(name = "BillingEvent")
|
||||||
@Entity
|
@Table(
|
||||||
@javax.persistence.Entity(name = "BillingEvent")
|
|
||||||
@javax.persistence.Table(
|
|
||||||
indexes = {
|
indexes = {
|
||||||
@javax.persistence.Index(columnList = "registrarId"),
|
@Index(columnList = "registrarId"),
|
||||||
@javax.persistence.Index(columnList = "eventTime"),
|
@Index(columnList = "eventTime"),
|
||||||
@javax.persistence.Index(columnList = "billingTime"),
|
@Index(columnList = "billingTime"),
|
||||||
@javax.persistence.Index(columnList = "syntheticCreationTime"),
|
@Index(columnList = "syntheticCreationTime"),
|
||||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
@Index(columnList = "domainRepoId"),
|
||||||
@javax.persistence.Index(columnList = "allocationToken"),
|
@Index(columnList = "allocationToken"),
|
||||||
@javax.persistence.Index(columnList = "cancellation_matching_billing_recurrence_id")
|
@Index(columnList = "cancellation_matching_billing_recurrence_id")
|
||||||
})
|
})
|
||||||
@AttributeOverride(name = "id", column = @Column(name = "billing_event_id"))
|
@AttributeOverride(name = "id", column = @Column(name = "billing_event_id"))
|
||||||
@WithLongVKey(compositeKey = true)
|
@WithLongVKey(compositeKey = true)
|
||||||
|
@ -345,15 +301,13 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
Money cost;
|
Money cost;
|
||||||
|
|
||||||
/** When the cost should be billed. */
|
/** When the cost should be billed. */
|
||||||
@Index
|
|
||||||
DateTime billingTime;
|
DateTime billingTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The period in years of the action being billed for, if applicable, otherwise null. Used for
|
* The period in years of the action being billed for, if applicable, otherwise null. Used for
|
||||||
* financial reporting.
|
* financial reporting.
|
||||||
*/
|
*/
|
||||||
@IgnoreSave(IfNull.class)
|
Integer periodYears;
|
||||||
Integer periodYears = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For {@link Flag#SYNTHETIC} events, when this event was persisted to Datastore (i.e. the
|
* 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
|
* needs to be undone, a query on this field will return the complete set of potentially bad
|
||||||
* events.
|
* events.
|
||||||
*/
|
*/
|
||||||
@Index
|
|
||||||
DateTime syntheticCreationTime;
|
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 OneTime} was created. This is needed in order to properly match billing events against
|
||||||
* {@link Cancellation}s.
|
* {@link Cancellation}s.
|
||||||
*/
|
*/
|
||||||
|
@ -373,20 +326,17 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
VKey<Recurring> cancellationMatchingBillingEvent;
|
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
|
* Recurring} from which this {@link OneTime} was created. This is needed in order to recreate
|
||||||
* the {@link VKey} when reading from SQL.
|
* the {@link VKey} when reading from SQL.
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
@Column(name = "recurrence_history_revision_id")
|
@Column(name = "recurrence_history_revision_id")
|
||||||
Long recurringEventHistoryRevisionId;
|
Long recurringEventHistoryRevisionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link AllocationToken} used in the creation of this event, or null if one was not used.
|
* 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() {
|
public Money getCost() {
|
||||||
return cost;
|
return cost;
|
||||||
|
@ -418,11 +368,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VKey<OneTime> createVKey() {
|
public VKey<OneTime> createVKey() {
|
||||||
return VKey.create(OneTime.class, getId(), Key.create(this));
|
return createVKey(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VKey<OneTime> createVKey(Key<OneTime> key) {
|
public static VKey<OneTime> createVKey(long id) {
|
||||||
return VKey.create(OneTime.class, key.getId(), key);
|
return VKey.createSql(OneTime.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -430,19 +380,6 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
return new Builder(clone(this));
|
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. */
|
/** A builder for {@link OneTime} since it is immutable. */
|
||||||
public static class Builder extends BillingEvent.Builder<OneTime, Builder> {
|
public static class Builder extends BillingEvent.Builder<OneTime, Builder> {
|
||||||
|
|
||||||
|
@ -475,11 +412,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setCancellationMatchingBillingEvent(
|
public Builder setCancellationMatchingBillingEvent(
|
||||||
VKey<Recurring> cancellationMatchingBillingEvent) {
|
Recurring cancellationMatchingBillingEvent) {
|
||||||
getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent;
|
getInstance().cancellationMatchingBillingEvent =
|
||||||
// getOfyKey() here is safe, recurring billing event VKeys have a valid ofy key.
|
cancellationMatchingBillingEvent.createVKey();
|
||||||
getInstance().recurringEventHistoryRevisionId =
|
getInstance().recurringEventHistoryRevisionId =
|
||||||
cancellationMatchingBillingEvent.getOfyKey().getParent().getId();
|
cancellationMatchingBillingEvent.getDomainHistoryRevisionId();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,12 +448,6 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
== (instance.cancellationMatchingBillingEvent != null),
|
== (instance.cancellationMatchingBillingEvent != null),
|
||||||
"Cancellation matching billing event must be set if and only if the SYNTHETIC flag "
|
"Cancellation matching billing event must be set if and only if the SYNTHETIC flag "
|
||||||
+ "is set.");
|
+ "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();
|
return super.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,29 +457,26 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
* A recurring billable event.
|
* A recurring billable event.
|
||||||
*
|
*
|
||||||
* <p>Unlike {@link OneTime} events, these do not store an explicit cost, since the cost of the
|
* <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.
|
* not the value that was in use at the time the recurrence was created.
|
||||||
*/
|
*/
|
||||||
@ReportedOn
|
@Entity(name = "BillingRecurrence")
|
||||||
@Entity
|
@Table(
|
||||||
@javax.persistence.Entity(name = "BillingRecurrence")
|
|
||||||
@javax.persistence.Table(
|
|
||||||
indexes = {
|
indexes = {
|
||||||
@javax.persistence.Index(columnList = "registrarId"),
|
@Index(columnList = "registrarId"),
|
||||||
@javax.persistence.Index(columnList = "eventTime"),
|
@Index(columnList = "eventTime"),
|
||||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
@Index(columnList = "domainRepoId"),
|
||||||
@javax.persistence.Index(columnList = "recurrenceEndTime"),
|
@Index(columnList = "recurrenceEndTime"),
|
||||||
@javax.persistence.Index(columnList = "recurrence_time_of_year")
|
@Index(columnList = "recurrence_time_of_year")
|
||||||
})
|
})
|
||||||
@AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id"))
|
@AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id"))
|
||||||
@WithLongVKey(compositeKey = true)
|
@WithLongVKey(compositeKey = true)
|
||||||
public static class Recurring extends BillingEvent {
|
public static class Recurring extends BillingEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The billing event recurs every year between {@link #eventTime} and this time on the
|
* The billing event recurs every year between {@link #eventTime} and this time on the [month,
|
||||||
* [month, day, time] specified in {@link #recurrenceTimeOfYear}.
|
* day, time] specified in {@link #recurrenceTimeOfYear}.
|
||||||
*/
|
*/
|
||||||
@Index
|
|
||||||
DateTime recurrenceEndTime;
|
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
|
* (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.
|
* model, whereas the billing time is a fixed {@link org.joda.time.Duration} later.
|
||||||
*/
|
*/
|
||||||
@Index
|
|
||||||
@Embedded
|
@Embedded
|
||||||
@AttributeOverrides({
|
@AttributeOverrides(
|
||||||
@AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year"))
|
@AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year")))
|
||||||
})
|
|
||||||
TimeOfYear recurrenceTimeOfYear;
|
TimeOfYear recurrenceTimeOfYear;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -605,11 +531,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VKey<Recurring> createVKey() {
|
public VKey<Recurring> createVKey() {
|
||||||
return VKey.create(Recurring.class, getId(), Key.create(this));
|
return createVKey(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VKey<Recurring> createVKey(Key<Recurring> key) {
|
public static VKey<Recurring> createVKey(Long id) {
|
||||||
return VKey.create(Recurring.class, key.getId(), key);
|
return VKey.createSql(Recurring.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -647,8 +573,8 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
checkNotNull(instance.eventTime);
|
checkNotNull(instance.eventTime);
|
||||||
checkNotNull(instance.reason);
|
checkNotNull(instance.reason);
|
||||||
checkArgument(
|
checkArgument(
|
||||||
(instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED)
|
instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED
|
||||||
^ (instance.renewalPrice == null),
|
^ instance.renewalPrice == null,
|
||||||
"Renewal price can have a value if and only if the renewal price behavior is"
|
"Renewal price can have a value if and only if the renewal price behavior is"
|
||||||
+ " SPECIFIED");
|
+ " SPECIFIED");
|
||||||
instance.recurrenceTimeOfYear = TimeOfYear.fromDateTime(instance.eventTime);
|
instance.recurrenceTimeOfYear = TimeOfYear.fromDateTime(instance.eventTime);
|
||||||
|
@ -666,47 +592,45 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
* preserve the immutability of billing events.
|
* preserve the immutability of billing events.
|
||||||
*/
|
*/
|
||||||
@ReportedOn
|
@ReportedOn
|
||||||
@Entity
|
@Entity(name = "BillingCancellation")
|
||||||
@javax.persistence.Entity(name = "BillingCancellation")
|
@Table(
|
||||||
@javax.persistence.Table(
|
|
||||||
indexes = {
|
indexes = {
|
||||||
@javax.persistence.Index(columnList = "registrarId"),
|
@Index(columnList = "registrarId"),
|
||||||
@javax.persistence.Index(columnList = "eventTime"),
|
@Index(columnList = "eventTime"),
|
||||||
@javax.persistence.Index(columnList = "domainRepoId"),
|
@Index(columnList = "domainRepoId"),
|
||||||
@javax.persistence.Index(columnList = "billingTime"),
|
@Index(columnList = "billingTime"),
|
||||||
@javax.persistence.Index(columnList = "billing_event_id"),
|
@Index(columnList = "billing_event_id"),
|
||||||
@javax.persistence.Index(columnList = "billing_recurrence_id")
|
@Index(columnList = "billing_recurrence_id")
|
||||||
})
|
})
|
||||||
@AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id"))
|
@AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id"))
|
||||||
@WithLongVKey(compositeKey = true)
|
@WithLongVKey(compositeKey = true)
|
||||||
public static class Cancellation extends BillingEvent {
|
public static class Cancellation extends BillingEvent {
|
||||||
|
|
||||||
/** The billing time of the charge that is being cancelled. */
|
/** The billing time of the charge that is being cancelled. */
|
||||||
@Index
|
|
||||||
DateTime billingTime;
|
DateTime billingTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The one-time billing event to cancel, or null for autorenew cancellations.
|
* 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)
|
@Column(name = "billing_event_id")
|
||||||
BillingEventVKey refOneTime = null;
|
VKey<OneTime> refOneTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The recurring billing event to cancel, or null for non-autorenew cancellations.
|
* 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)
|
@Column(name = "billing_recurrence_id")
|
||||||
BillingRecurrenceVKey refRecurring = null;
|
VKey<Recurring> refRecurring;
|
||||||
|
|
||||||
public DateTime getBillingTime() {
|
public DateTime getBillingTime() {
|
||||||
return billingTime;
|
return billingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VKey<? extends BillingEvent> getEventKey() {
|
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. */
|
/** 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
|
* using the supplied targetId and deriving other metadata (clientId, billing time, and the
|
||||||
* cancellation reason) from the grace period.
|
* cancellation reason) from the grace period.
|
||||||
*/
|
*/
|
||||||
public static BillingEvent.Cancellation forGracePeriod(
|
public static Cancellation forGracePeriod(
|
||||||
GracePeriod gracePeriod,
|
GracePeriod gracePeriod,
|
||||||
DateTime eventTime,
|
DateTime eventTime,
|
||||||
Key<DomainHistory> domainHistoryKey,
|
DomainHistoryId domainHistoryId,
|
||||||
String targetId) {
|
String targetId) {
|
||||||
checkArgument(gracePeriod.hasBillingEvent(),
|
checkArgument(
|
||||||
|
gracePeriod.hasBillingEvent(),
|
||||||
"Cannot create cancellation for grace period without billing event");
|
"Cannot create cancellation for grace period without billing event");
|
||||||
BillingEvent.Cancellation.Builder builder =
|
Builder builder =
|
||||||
new BillingEvent.Cancellation.Builder()
|
new Builder()
|
||||||
.setReason(checkNotNull(GRACE_PERIOD_TO_REASON.get(gracePeriod.getType())))
|
.setReason(checkNotNull(GRACE_PERIOD_TO_REASON.get(gracePeriod.getType())))
|
||||||
.setTargetId(targetId)
|
.setTargetId(targetId)
|
||||||
.setRegistrarId(gracePeriod.getRegistrarId())
|
.setRegistrarId(gracePeriod.getRegistrarId())
|
||||||
.setEventTime(eventTime)
|
.setEventTime(eventTime)
|
||||||
// The charge being cancelled will take place at the grace period's expiration time.
|
// The charge being cancelled will take place at the grace period's expiration time.
|
||||||
.setBillingTime(gracePeriod.getExpirationTime())
|
.setBillingTime(gracePeriod.getExpirationTime())
|
||||||
.setParent(domainHistoryKey);
|
.setDomainHistoryId(domainHistoryId);
|
||||||
// Set the grace period's billing event using the appropriate Cancellation builder method.
|
// Set the grace period's billing event using the appropriate Cancellation builder method.
|
||||||
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
||||||
builder.setOneTimeEventKey(gracePeriod.getOneTimeBillingEvent());
|
builder.setOneTimeEventKey(gracePeriod.getOneTimeBillingEvent());
|
||||||
|
@ -750,11 +675,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VKey<Cancellation> createVKey() {
|
public VKey<Cancellation> createVKey() {
|
||||||
return VKey.create(Cancellation.class, getId(), Key.create(this));
|
return createVKey(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VKey<Cancellation> createVKey(Key<Cancellation> key) {
|
public static VKey<Cancellation> createVKey(long id) {
|
||||||
return VKey.create(Cancellation.class, key.getId(), key);
|
return VKey.createSql(Cancellation.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -776,13 +701,13 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setOneTimeEventKey(VKey<BillingEvent.OneTime> eventKey) {
|
public Builder setOneTimeEventKey(VKey<OneTime> eventKey) {
|
||||||
getInstance().refOneTime = BillingEventVKey.create(eventKey);
|
getInstance().refOneTime = eventKey;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setRecurringEventKey(VKey<BillingEvent.Recurring> eventKey) {
|
public Builder setRecurringEventKey(VKey<Recurring> eventKey) {
|
||||||
getInstance().refRecurring = BillingRecurrenceVKey.create(eventKey);
|
getInstance().refRecurring = eventKey;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,115 +716,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||||
Cancellation instance = getInstance();
|
Cancellation instance = getInstance();
|
||||||
checkNotNull(instance.billingTime, "Must set billing time");
|
checkNotNull(instance.billingTime, "Must set billing time");
|
||||||
checkNotNull(instance.reason, "Must set reason");
|
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");
|
"Cancellations must have exactly one billing event key set");
|
||||||
return super.build();
|
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) {
|
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);
|
return (Class<T>) CLASS_REGISTRY.get(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String getClassName(Class<T> clazz) {
|
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);
|
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.
|
* should be created, and this field should be updated to point to the new one.
|
||||||
*/
|
*/
|
||||||
@Column(name = "billing_recurrence_id")
|
@Column(name = "billing_recurrence_id")
|
||||||
|
@Ignore
|
||||||
VKey<BillingEvent.Recurring> autorenewBillingEvent;
|
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.
|
// NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections.
|
||||||
@Access(AccessType.FIELD)
|
@Access(AccessType.FIELD)
|
||||||
@Column(name = "billing_event_id")
|
@Column(name = "billing_event_id")
|
||||||
|
@Ignore
|
||||||
VKey<BillingEvent.OneTime> billingEventOneTime = null;
|
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.
|
// NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections.
|
||||||
@Access(AccessType.FIELD)
|
@Access(AccessType.FIELD)
|
||||||
@Column(name = "billing_recurrence_id")
|
@Column(name = "billing_recurrence_id")
|
||||||
|
@Ignore
|
||||||
VKey<BillingEvent.Recurring> billingEventRecurring = null;
|
VKey<BillingEvent.Recurring> billingEventRecurring = null;
|
||||||
|
|
||||||
public long getGracePeriodId() {
|
public long getGracePeriodId() {
|
||||||
|
|
|
@ -168,6 +168,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "renewalPriceBehavior", nullable = false)
|
@Column(name = "renewalPriceBehavior", nullable = false)
|
||||||
|
@Ignore
|
||||||
RenewalPriceBehavior renewalPriceBehavior = RenewalPriceBehavior.DEFAULT;
|
RenewalPriceBehavior renewalPriceBehavior = RenewalPriceBehavior.DEFAULT;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@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
|
* <p>This field should be null if there is not currently a pending transfer or if the object
|
||||||
* being transferred is not a domain.
|
* being transferred is not a domain.
|
||||||
*/
|
*/
|
||||||
@IgnoreSave(IfNull.class)
|
|
||||||
@Column(name = "transfer_billing_event_id")
|
@Column(name = "transfer_billing_event_id")
|
||||||
|
@Ignore
|
||||||
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
|
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
|
* <p>This field should be null if there is not currently a pending transfer or if the object
|
||||||
* being transferred is not a domain.
|
* being transferred is not a domain.
|
||||||
*/
|
*/
|
||||||
@IgnoreSave(IfNull.class)
|
|
||||||
@Column(name = "transfer_billing_recurrence_id")
|
@Column(name = "transfer_billing_recurrence_id")
|
||||||
|
@Ignore
|
||||||
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
|
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.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import google.registry.persistence.BillingVKey.BillingEventVKey;
|
|
||||||
import google.registry.persistence.BillingVKey.BillingRecurrenceVKey;
|
|
||||||
import google.registry.persistence.DomainHistoryVKey;
|
import google.registry.persistence.DomainHistoryVKey;
|
||||||
import google.registry.persistence.EppHistoryVKey;
|
import google.registry.persistence.EppHistoryVKey;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
@ -45,8 +43,7 @@ public class EppHistoryVKeyTranslatorFactory
|
||||||
// key, e.g. the map key for ContactPollMessageVKey is "ContactResource/HistoryEntry/PollMessage".
|
// key, e.g. the map key for ContactPollMessageVKey is "ContactResource/HistoryEntry/PollMessage".
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final ImmutableMap<String, Class<? extends EppHistoryVKey>> kindPathToVKeyClass =
|
static final ImmutableMap<String, Class<? extends EppHistoryVKey>> kindPathToVKeyClass =
|
||||||
ImmutableSet.of(DomainHistoryVKey.class, BillingEventVKey.class, BillingRecurrenceVKey.class)
|
ImmutableSet.of(DomainHistoryVKey.class).stream()
|
||||||
.stream()
|
|
||||||
.collect(toImmutableMap(EppHistoryVKeyTranslatorFactory::getKindPath, identity()));
|
.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.annotation.Nullable;
|
||||||
import javax.persistence.AttributeConverter;
|
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>
|
public abstract class VKeyConverter<T, C extends Serializable>
|
||||||
implements AttributeConverter<VKey<? extends T>, C> {
|
implements AttributeConverter<VKey<? extends T>, C> {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public C convertToDatabaseColumn(@Nullable VKey<? extends T> attribute) {
|
public C convertToDatabaseColumn(@Nullable VKey<? extends T> attribute) {
|
||||||
return attribute == null ? null : (C) attribute.getSqlKey();
|
return attribute == null ? null : (C) attribute.getSqlKey();
|
||||||
}
|
}
|
||||||
|
@ -35,8 +36,8 @@ public abstract class VKeyConverter<T, C extends Serializable>
|
||||||
if (dbData == null) {
|
if (dbData == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Class<? extends T> clazz = getAttributeClass();
|
Class<T> clazz = getAttributeClass();
|
||||||
Key ofyKey = null;
|
Key<T> ofyKey;
|
||||||
if (!hasCompositeOfyKey()) {
|
if (!hasCompositeOfyKey()) {
|
||||||
// If this isn't a composite key, we can create the Ofy key from the SQL key.
|
// If this isn't a composite key, we can create the Ofy key from the SQL key.
|
||||||
ofyKey =
|
ofyKey =
|
||||||
|
|
|
@ -415,7 +415,7 @@ public final class DomainLockUtils {
|
||||||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
.setBillingTime(now)
|
.setBillingTime(now)
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build();
|
.build();
|
||||||
tm().insert(oneTime);
|
tm().insert(oneTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot
|
||||||
BillingEvent.Recurring newAutorenewEvent =
|
BillingEvent.Recurring newAutorenewEvent =
|
||||||
newAutorenewBillingEvent(domain)
|
newAutorenewBillingEvent(domain)
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build();
|
.build();
|
||||||
PollMessage.Autorenew newAutorenewPollMessage =
|
PollMessage.Autorenew newAutorenewPollMessage =
|
||||||
newAutorenewPollMessage(domain)
|
newAutorenewPollMessage(domain)
|
||||||
|
|
|
@ -99,7 +99,6 @@
|
||||||
|
|
||||||
<!-- Generated converters for VKey -->
|
<!-- Generated converters for VKey -->
|
||||||
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
<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_OneTime</class>
|
||||||
<class>google.registry.model.billing.VKeyConverter_Recurring</class>
|
<class>google.registry.model.billing.VKeyConverter_Recurring</class>
|
||||||
<class>google.registry.model.contact.VKeyConverter_ContactResource</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 Registrar r ON b.clientId = r.clientIdentifier
|
||||||
JOIN Domain d ON b.domainRepoId = d.repoId
|
JOIN Domain d ON b.domainRepoId = d.repoId
|
||||||
JOIN Tld t ON t.tldStr = d.tld
|
JOIN Tld t ON t.tldStr = d.tld
|
||||||
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId
|
LEFT JOIN BillingCancellation c ON b.id = c.refOneTime
|
||||||
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring.billingId
|
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring
|
||||||
WHERE r.billingAccountMap IS NOT NULL
|
WHERE r.billingAccountMap IS NOT NULL
|
||||||
AND r.type = 'REAL'
|
AND r.type = 'REAL'
|
||||||
AND t.invoicingEnabled IS TRUE
|
AND t.invoicingEnabled IS TRUE
|
||||||
|
|
|
@ -200,7 +200,7 @@ class DeleteExpiredDomainsActionTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(clock.nowUtc().plusYears(1))
|
.setEventTime(clock.nowUtc().plusYears(1))
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(createHistoryEntry);
|
.setDomainHistory(createHistoryEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PollMessage.Autorenew.Builder createAutorenewPollMessage(
|
private PollMessage.Autorenew.Builder createAutorenewPollMessage(
|
||||||
|
|
|
@ -296,7 +296,7 @@ class DeleteProberDataActionTest {
|
||||||
BillingEvent.OneTime billingEvent =
|
BillingEvent.OneTime billingEvent =
|
||||||
persistSimpleResource(
|
persistSimpleResource(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setBillingTime(DELETION_TIME.plusYears(1))
|
.setBillingTime(DELETION_TIME.plusYears(1))
|
||||||
.setCost(Money.parse("USD 10"))
|
.setCost(Money.parse("USD 10"))
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.build());
|
.build());
|
||||||
recurring =
|
recurring =
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setRegistrarId(domain.getCreationRegistrarId())
|
.setRegistrarId(domain.getCreationRegistrarId())
|
||||||
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
|
@ -171,7 +171,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setSyntheticCreationTime(currentTestTime)
|
.setSyntheticCreationTime(currentTestTime)
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.setTargetId(domain.getDomainName());
|
.setTargetId(domain.getDomainName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +205,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
recurring =
|
recurring =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setRegistrarId(deletedDomain.getCreationRegistrarId())
|
.setRegistrarId(deletedDomain.getCreationRegistrarId())
|
||||||
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-01-05T00:00:00Z"))
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
|
@ -225,7 +226,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
true);
|
true);
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.setTargetId(deletedDomain.getDomainName())
|
.setTargetId(deletedDomain.getDomainName())
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(deletedDomain, expected, recurring);
|
assertBillingEventsForResource(deletedDomain, expected, recurring);
|
||||||
|
@ -241,7 +242,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertCursorAt(currentTestTime);
|
||||||
DateTime beginningOfSecondRun = clock.nowUtc();
|
DateTime beginningOfSecondRun = clock.nowUtc();
|
||||||
action.response = new FakeResponse();
|
action.response = new FakeResponse();
|
||||||
|
@ -254,7 +256,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
void testSuccess_expandSingleEvent_idempotentForExistingOneTime() throws Exception {
|
void testSuccess_expandSingleEvent_idempotentForExistingOneTime() throws Exception {
|
||||||
persistResource(recurring);
|
persistResource(recurring);
|
||||||
BillingEvent.OneTime persisted =
|
BillingEvent.OneTime persisted =
|
||||||
persistResource(defaultOneTimeBuilder().setParent(historyEntry).build());
|
persistResource(defaultOneTimeBuilder().setDomainHistory(historyEntry).build());
|
||||||
action.cursorTimeParam = Optional.of(START_OF_TIME);
|
action.cursorTimeParam = Optional.of(START_OF_TIME);
|
||||||
runAction();
|
runAction();
|
||||||
// No new history entries should be generated
|
// No new history entries should be generated
|
||||||
|
@ -273,7 +275,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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).
|
// Persist an otherwise identical billing event that differs only in billing time (and ID).
|
||||||
BillingEvent.OneTime persisted =
|
BillingEvent.OneTime persisted =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
@ -301,13 +304,13 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
}
|
}
|
||||||
assertThat(persistedEntries).hasSize(2);
|
assertThat(persistedEntries).hasSize(2);
|
||||||
BillingEvent.OneTime expected =
|
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.
|
// Persist an otherwise identical billing event that differs only in recurring event key.
|
||||||
BillingEvent.OneTime persisted =
|
BillingEvent.OneTime persisted =
|
||||||
expected
|
expected
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
.setCancellationMatchingBillingEvent(recurring2)
|
||||||
.build();
|
.build();
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2);
|
assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2);
|
||||||
|
@ -350,7 +353,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -364,7 +368,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -401,7 +406,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2002-02-19T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2002-02-19T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2002-01-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2002-01-05T00:00:00Z"))
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, recurring);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -416,7 +421,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -482,7 +488,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(billingDate.plusYears(year))
|
.setBillingTime(billingDate.plusYears(year))
|
||||||
.setEventTime(eventDate.plusYears(year))
|
.setEventTime(eventDate.plusYears(year))
|
||||||
.setParent(persistedEntries.get(year))
|
.setDomainHistory(persistedEntries.get(year))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
assertBillingEventsForResource(domain, Iterables.toArray(expectedEvents, BillingEvent.class));
|
assertBillingEventsForResource(domain, Iterables.toArray(expectedEvents, BillingEvent.class));
|
||||||
|
@ -508,7 +514,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
expectedEvents.add(
|
expectedEvents.add(
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(billingDate.plusYears(year))
|
.setBillingTime(billingDate.plusYears(year))
|
||||||
.setParent(persistedEntries.get(year))
|
.setDomainHistory(persistedEntries.get(year))
|
||||||
.setEventTime(eventDate.plusYears(year))
|
.setEventTime(eventDate.plusYears(year))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
@ -554,7 +560,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, recurring, expected);
|
assertBillingEventsForResource(domain, recurring, expected);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -583,7 +589,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-02-19T00:00:00Z"))
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, recurring, expected);
|
assertBillingEventsForResource(domain, recurring, expected);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -604,7 +610,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2000-02-29T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-02-29T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2000-01-15T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-01-15T00:00:00Z"))
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, recurring);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -626,7 +632,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2001-03-01T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2001-03-01T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2001-01-15T00:00:00Z"))
|
.setEventTime(DateTime.parse("2001-01-15T00:00:00Z"))
|
||||||
.setParent(persistedEntry)
|
.setDomainHistory(persistedEntry)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, recurring);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -652,7 +658,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
BillingEvent.Recurring recurring2 =
|
BillingEvent.Recurring recurring2 =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry2)
|
.setDomainHistory(historyEntry2)
|
||||||
.setRegistrarId(domain2.getCreationRegistrarId())
|
.setRegistrarId(domain2.getCreationRegistrarId())
|
||||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
|
@ -677,7 +683,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
BillingEvent.Recurring recurring3 =
|
BillingEvent.Recurring recurring3 =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry3)
|
.setDomainHistory(historyEntry3)
|
||||||
.setRegistrarId(domain3.getCreationRegistrarId())
|
.setRegistrarId(domain3.getCreationRegistrarId())
|
||||||
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
|
@ -694,8 +700,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
domain, persistedHistory1, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
domain, persistedHistory1, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setParent(persistedHistory1)
|
.setDomainHistory(persistedHistory1)
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.build();
|
.build();
|
||||||
DomainHistory persistedHistory2 =
|
DomainHistory persistedHistory2 =
|
||||||
getOnlyHistoryEntryOfType(domain2, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain2, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
|
@ -705,9 +711,9 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||||
.setParent(persistedHistory2)
|
.setDomainHistory(persistedHistory2)
|
||||||
.setTargetId(domain2.getDomainName())
|
.setTargetId(domain2.getDomainName())
|
||||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
.setCancellationMatchingBillingEvent(recurring2)
|
||||||
.build();
|
.build();
|
||||||
DomainHistory persistedHistory3 =
|
DomainHistory persistedHistory3 =
|
||||||
getOnlyHistoryEntryOfType(domain3, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain3, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
|
@ -718,8 +724,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setBillingTime(DateTime.parse("2000-07-20T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-07-20T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-06-05T00:00:00Z"))
|
||||||
.setTargetId(domain3.getDomainName())
|
.setTargetId(domain3.getDomainName())
|
||||||
.setParent(persistedHistory3)
|
.setDomainHistory(persistedHistory3)
|
||||||
.setCancellationMatchingBillingEvent(recurring3.createVKey())
|
.setCancellationMatchingBillingEvent(recurring3)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, recurring);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertBillingEventsForResource(domain2, expected2, recurring2);
|
assertBillingEventsForResource(domain2, expected2, recurring2);
|
||||||
|
@ -755,8 +761,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
true);
|
true);
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setParent(persistedEntries.get(0))
|
.setDomainHistory(persistedEntries.get(0))
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.build();
|
.build();
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain,
|
domain,
|
||||||
|
@ -768,8 +774,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
.setCancellationMatchingBillingEvent(recurring2)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -812,8 +818,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
BillingEvent.OneTime expected =
|
BillingEvent.OneTime expected =
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setCost(Money.of(USD, 4))
|
.setCost(Money.of(USD, 4))
|
||||||
.setParent(persistedEntries.get(0))
|
.setDomainHistory(persistedEntries.get(0))
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.build();
|
.build();
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain,
|
domain,
|
||||||
|
@ -826,8 +832,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setCost(Money.of(USD, 4))
|
.setCost(Money.of(USD, 4))
|
||||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
.setCancellationMatchingBillingEvent(recurring2)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -848,7 +854,10 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||||
BillingEvent.OneTime expected =
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -868,7 +877,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||||
BillingEvent.OneTime expected =
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -882,7 +891,8 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class);
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +918,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||||
BillingEvent.OneTime expected =
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -929,7 +939,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true);
|
||||||
BillingEvent.OneTime expected =
|
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);
|
assertBillingEventsForResource(domain, expected, recurring);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
}
|
}
|
||||||
|
@ -961,7 +971,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(billingDate)
|
.setBillingTime(billingDate)
|
||||||
.setEventTime(eventDate)
|
.setEventTime(eventDate)
|
||||||
.setParent(persistedEntries.get(0))
|
.setDomainHistory(persistedEntries.get(0))
|
||||||
.setCost(Money.of(USD, 8))
|
.setCost(Money.of(USD, 8))
|
||||||
.build();
|
.build();
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
|
@ -972,7 +982,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setCost(Money.of(USD, 10))
|
.setCost(Money.of(USD, 10))
|
||||||
.setBillingTime(billingDate.plusYears(1))
|
.setBillingTime(billingDate.plusYears(1))
|
||||||
.setEventTime(eventDate.plusYears(1))
|
.setEventTime(eventDate.plusYears(1))
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -1006,7 +1016,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(billingDate)
|
.setBillingTime(billingDate)
|
||||||
.setEventTime(eventDate)
|
.setEventTime(eventDate)
|
||||||
.setParent(persistedEntries.get(0))
|
.setDomainHistory(persistedEntries.get(0))
|
||||||
.setCost(Money.of(USD, 8))
|
.setCost(Money.of(USD, 8))
|
||||||
.build();
|
.build();
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
|
@ -1017,7 +1027,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setCost(Money.of(USD, 10))
|
.setCost(Money.of(USD, 10))
|
||||||
.setBillingTime(billingDate.plusYears(1))
|
.setBillingTime(billingDate.plusYears(1))
|
||||||
.setEventTime(eventDate.plusYears(1))
|
.setEventTime(eventDate.plusYears(1))
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
@ -1057,7 +1067,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
defaultOneTimeBuilder()
|
defaultOneTimeBuilder()
|
||||||
.setBillingTime(billingDate)
|
.setBillingTime(billingDate)
|
||||||
.setEventTime(eventDate)
|
.setEventTime(eventDate)
|
||||||
.setParent(persistedEntries.get(0))
|
.setDomainHistory(persistedEntries.get(0))
|
||||||
.setCost(Money.of(USD, 5))
|
.setCost(Money.of(USD, 5))
|
||||||
.build();
|
.build();
|
||||||
assertHistoryEntryMatches(
|
assertHistoryEntryMatches(
|
||||||
|
@ -1068,7 +1078,7 @@ public class ExpandRecurringBillingEventsActionTest {
|
||||||
.setCost(Money.of(USD, 5))
|
.setCost(Money.of(USD, 5))
|
||||||
.setBillingTime(billingDate.plusYears(1))
|
.setBillingTime(billingDate.plusYears(1))
|
||||||
.setEventTime(eventDate.plusYears(1))
|
.setEventTime(eventDate.plusYears(1))
|
||||||
.setParent(persistedEntries.get(1))
|
.setDomainHistory(persistedEntries.get(1))
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
assertBillingEventsForResource(domain, recurring, cheaper, expensive);
|
||||||
assertCursorAt(currentTestTime);
|
assertCursorAt(currentTestTime);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package google.registry.beam.invoicing;
|
package google.registry.beam.invoicing;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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;
|
||||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
||||||
|
@ -23,108 +22,41 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
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.DateTime;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/** Unit tests for {@link BillingEvent} */
|
/** Unit tests for {@link BillingEvent} */
|
||||||
class BillingEventTest {
|
class BillingEventTest {
|
||||||
|
|
||||||
private static final String BILLING_EVENT_SCHEMA =
|
private BillingEvent event;
|
||||||
"{\"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;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach() {
|
void beforeEach() {
|
||||||
// Create a record with a given JSON schema.
|
event = createBillingEvent("", 5);
|
||||||
schemaAndRecord = new SchemaAndRecord(createRecord(), null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GenericRecord createRecord() {
|
private static BillingEvent createBillingEvent(String pONumber, int years) {
|
||||||
GenericRecord record = new GenericData.Record(new Schema.Parser().parse(BILLING_EVENT_SCHEMA));
|
return BillingEvent.create(
|
||||||
record.put("id", "1");
|
1,
|
||||||
record.put("billingTime", 1508835963000000L);
|
new DateTime(1508835963000L, DateTimeZone.UTC),
|
||||||
record.put("eventTime", 1484870383000000L);
|
new DateTime(1484870383000L, DateTimeZone.UTC),
|
||||||
record.put("registrarId", "myRegistrar");
|
"myRegistrar",
|
||||||
record.put("billingId", "12345-CRRHELLO");
|
"12345-CRRHELLO",
|
||||||
record.put("poNumber", "");
|
pONumber,
|
||||||
record.put("tld", "test");
|
"test",
|
||||||
record.put("action", "RENEW");
|
"RENEW",
|
||||||
record.put("domain", "example.test");
|
"example.test",
|
||||||
record.put("repositoryId", "123456");
|
"123456",
|
||||||
record.put("years", 5);
|
years,
|
||||||
record.put("currency", "USD");
|
"USD",
|
||||||
record.put("amount", 20.5);
|
20.5,
|
||||||
record.put("flags", "AUTO_RENEW SYNTHETIC");
|
"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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConvertBillingEvent_toCsv() {
|
void testConvertBillingEvent_toCsv() {
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
|
||||||
assertThat(event.toCsv())
|
assertThat(event.toCsv())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
||||||
|
@ -133,9 +65,7 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConvertBillingEvent_nonNullPoNumber_toCsv() {
|
void testConvertBillingEvent_nonNullPoNumber_toCsv() {
|
||||||
GenericRecord record = createRecord();
|
event = createBillingEvent("905610", 5);
|
||||||
record.put("poNumber", "905610");
|
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null));
|
|
||||||
assertThat(event.toCsv())
|
assertThat(event.toCsv())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
"1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar,"
|
||||||
|
@ -144,13 +74,11 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGenerateBillingEventFilename() {
|
void testGenerateBillingEventFilename() {
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
|
||||||
assertThat(event.toFilename("2017-10")).isEqualTo("invoice_details_2017-10_myRegistrar_test");
|
assertThat(event.toFilename("2017-10")).isEqualTo("invoice_details_2017-10_myRegistrar_test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetInvoiceGroupingKey_fromBillingEvent() {
|
void testGetInvoiceGroupingKey_fromBillingEvent() {
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
|
||||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||||
assertThat(invoiceKey.startDate()).isEqualTo("2017-10-01");
|
assertThat(invoiceKey.startDate()).isEqualTo("2017-10-01");
|
||||||
assertThat(invoiceKey.endDate()).isEqualTo("2022-09-30");
|
assertThat(invoiceKey.endDate()).isEqualTo("2022-09-30");
|
||||||
|
@ -164,9 +92,7 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void test_nonNullPoNumber() {
|
void test_nonNullPoNumber() {
|
||||||
GenericRecord record = createRecord();
|
event = createBillingEvent("905610", 5);
|
||||||
record.put("poNumber", "905610");
|
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null));
|
|
||||||
assertThat(event.poNumber()).isEqualTo("905610");
|
assertThat(event.poNumber()).isEqualTo("905610");
|
||||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||||
assertThat(invoiceKey.poNumber()).isEqualTo("905610");
|
assertThat(invoiceKey.poNumber()).isEqualTo("905610");
|
||||||
|
@ -174,7 +100,6 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConvertInvoiceGroupingKey_toCsv() {
|
void testConvertInvoiceGroupingKey_toCsv() {
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
|
||||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||||
assertThat(invoiceKey.toCsv(3L))
|
assertThat(invoiceKey.toCsv(3L))
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
|
@ -184,10 +109,7 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConvertInvoiceGroupingKey_zeroYears_toCsv() {
|
void testConvertInvoiceGroupingKey_zeroYears_toCsv() {
|
||||||
GenericRecord record = schemaAndRecord.getRecord();
|
event = createBillingEvent("", 0);
|
||||||
record.put("years", 0);
|
|
||||||
schemaAndRecord = new SchemaAndRecord(record, null);
|
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
|
||||||
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||||
assertThat(invoiceKey.toCsv(3L))
|
assertThat(invoiceKey.toCsv(3L))
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
|
@ -197,8 +119,7 @@ class BillingEventTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInvoiceGroupingKeyCoder_deterministicSerialization() throws IOException {
|
void testInvoiceGroupingKeyCoder_deterministicSerialization() throws IOException {
|
||||||
InvoiceGroupingKey invoiceKey =
|
InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey();
|
||||||
BillingEvent.parseFromRecord(schemaAndRecord).getInvoiceGroupingKey();
|
|
||||||
InvoiceGroupingKeyCoder coder = new InvoiceGroupingKeyCoder();
|
InvoiceGroupingKeyCoder coder = new InvoiceGroupingKeyCoder();
|
||||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||||
coder.encode(invoiceKey, outStream);
|
coder.encode(invoiceKey, outStream);
|
||||||
|
@ -217,7 +138,8 @@ class BillingEventTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetOverallInvoiceHeader() {
|
void testGetOverallInvoiceHeader() {
|
||||||
assertThat(InvoiceGroupingKey.invoiceHeader())
|
assertThat(InvoiceGroupingKey.invoiceHeader())
|
||||||
.isEqualTo("StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode,"
|
.isEqualTo(
|
||||||
|
"StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode,"
|
||||||
+ "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice,"
|
+ "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice,"
|
||||||
+ "UnitPriceCurrency,PONumber");
|
+ "UnitPriceCurrency,PONumber");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||||
import google.registry.testing.DatastoreEntityExtension;
|
import google.registry.testing.DatastoreEntityExtension;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.TestDataHelper;
|
|
||||||
import google.registry.util.ResourceUtils;
|
import google.registry.util.ResourceUtils;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
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.transforms.PTransform;
|
||||||
import org.apache.beam.sdk.values.PCollection;
|
import org.apache.beam.sdk.values.PCollection;
|
||||||
import org.apache.beam.sdk.values.TypeDescriptor;
|
import org.apache.beam.sdk.values.TypeDescriptor;
|
||||||
import org.joda.money.CurrencyUnit;
|
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -81,8 +79,7 @@ class InvoicingPipelineTest {
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
@Order(Order.DEFAULT - 1)
|
@Order(Order.DEFAULT - 1)
|
||||||
final transient DatastoreEntityExtension datastore =
|
final DatastoreEntityExtension datastore = new DatastoreEntityExtension().allThreads(true);
|
||||||
new DatastoreEntityExtension().allThreads(true);
|
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
final TestPipelineExtension pipeline =
|
final TestPipelineExtension pipeline =
|
||||||
|
@ -263,15 +260,6 @@ class InvoicingPipelineTest {
|
||||||
pipeline.apply(Create.of(INPUT_EVENTS).withCoder(SerializableCoder.of(BillingEvent.class)));
|
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
|
@Test
|
||||||
void testSuccess_fullSqlPipeline() throws Exception {
|
void testSuccess_fullSqlPipeline() throws Exception {
|
||||||
setupCloudSql();
|
setupCloudSql();
|
||||||
|
@ -365,14 +353,14 @@ class InvoicingPipelineTest {
|
||||||
// Test that comments are removed from the .sql file correctly
|
// Test that comments are removed from the .sql file correctly
|
||||||
assertThat(InvoicingPipeline.makeCloudSqlQuery("2017-10"))
|
assertThat(InvoicingPipeline.makeCloudSqlQuery("2017-10"))
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
"\n"
|
'\n'
|
||||||
+ "SELECT b, r FROM BillingEvent b\n"
|
+ "SELECT b, r FROM BillingEvent b\n"
|
||||||
+ "JOIN Registrar r ON b.clientId = r.clientIdentifier\n"
|
+ "JOIN Registrar r ON b.clientId = r.clientIdentifier\n"
|
||||||
+ "JOIN Domain d ON b.domainRepoId = d.repoId\n"
|
+ "JOIN Domain d ON b.domainRepoId = d.repoId\n"
|
||||||
+ "JOIN Tld t ON t.tldStr = d.tld\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 ="
|
+ "LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent ="
|
||||||
+ " cr.refRecurring.billingId\n"
|
+ " cr.refRecurring\n"
|
||||||
+ "WHERE r.billingAccountMap IS NOT NULL\n"
|
+ "WHERE r.billingAccountMap IS NOT NULL\n"
|
||||||
+ "AND r.type = 'REAL'\n"
|
+ "AND r.type = 'REAL'\n"
|
||||||
+ "AND t.invoicingEnabled IS TRUE\n"
|
+ "AND t.invoicingEnabled IS TRUE\n"
|
||||||
|
@ -386,13 +374,12 @@ class InvoicingPipelineTest {
|
||||||
private ImmutableList<String> resultFileContents(String filename) throws Exception {
|
private ImmutableList<String> resultFileContents(String filename) throws Exception {
|
||||||
File resultFile =
|
File resultFile =
|
||||||
new File(
|
new File(
|
||||||
String.format(
|
String.format("%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath(), filename));
|
||||||
"%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath().toString(), filename));
|
|
||||||
return ImmutableList.copyOf(
|
return ImmutableList.copyOf(
|
||||||
ResourceUtils.readResourceUtf8(resultFile.toURI().toURL()).split("\n"));
|
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
|
// Populate billing events in Cloud SQL to match existing test data for Datastore
|
||||||
persistNewRegistrar("NewRegistrar");
|
persistNewRegistrar("NewRegistrar");
|
||||||
persistNewRegistrar("TheRegistrar");
|
persistNewRegistrar("TheRegistrar");
|
||||||
|
@ -444,7 +431,7 @@ class InvoicingPipelineTest {
|
||||||
registrar1,
|
registrar1,
|
||||||
Reason.CREATE,
|
Reason.CREATE,
|
||||||
5,
|
5,
|
||||||
Money.ofMajor(CurrencyUnit.JPY, 70),
|
Money.ofMajor(JPY, 70),
|
||||||
DateTime.parse("2017-09-29T00:00:00.0Z"),
|
DateTime.parse("2017-09-29T00:00:00.0Z"),
|
||||||
DateTime.parse("2017-10-02T00:00:00.0Z"));
|
DateTime.parse("2017-10-02T00:00:00.0Z"));
|
||||||
persistOneTimeBillingEvent(4, domain4, registrar2, Reason.RENEW, 1, Money.of(USD, 20.5));
|
persistOneTimeBillingEvent(4, domain4, registrar2, Reason.RENEW, 1, Money.of(USD, 20.5));
|
||||||
|
@ -495,7 +482,7 @@ class InvoicingPipelineTest {
|
||||||
registrar1,
|
registrar1,
|
||||||
Reason.CREATE,
|
Reason.CREATE,
|
||||||
5,
|
5,
|
||||||
Money.ofMajor(CurrencyUnit.JPY, 70),
|
Money.ofMajor(JPY, 70),
|
||||||
DateTime.parse("2017-06-29T00:00:00.0Z"),
|
DateTime.parse("2017-06-29T00:00:00.0Z"),
|
||||||
DateTime.parse("2017-07-02T00:00:00.0Z"));
|
DateTime.parse("2017-07-02T00:00:00.0Z"));
|
||||||
|
|
||||||
|
@ -510,13 +497,12 @@ class InvoicingPipelineTest {
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setId(1)
|
.setId(1)
|
||||||
.setRegistrarId(registrar1.getRegistrarId())
|
.setRegistrarId(registrar1.getRegistrarId())
|
||||||
.setDomainHistoryRevisionId(domainHistory.getId())
|
|
||||||
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
||||||
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||||
.setOneTimeEventKey(oneTime.createVKey())
|
.setOneTimeEventKey(oneTime.createVKey())
|
||||||
.setTargetId(domain12.getDomainName())
|
.setTargetId(domain12.getDomainName())
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build();
|
.build();
|
||||||
persistResource(cancellation);
|
persistResource(cancellation);
|
||||||
|
|
||||||
|
@ -530,7 +516,7 @@ class InvoicingPipelineTest {
|
||||||
.setRegistrarId(registrar1.getRegistrarId())
|
.setRegistrarId(registrar1.getRegistrarId())
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setId(1)
|
.setId(1)
|
||||||
.setParent(domainHistoryRecurring)
|
.setDomainHistory(domainHistoryRecurring)
|
||||||
.setTargetId(domain13.getDomainName())
|
.setTargetId(domain13.getDomainName())
|
||||||
.setEventTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
.setEventTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
|
@ -541,7 +527,7 @@ class InvoicingPipelineTest {
|
||||||
oneTimeRecurring =
|
oneTimeRecurring =
|
||||||
oneTimeRecurring
|
oneTimeRecurring
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.setFlags(ImmutableSet.of(Flag.SYNTHETIC))
|
.setFlags(ImmutableSet.of(Flag.SYNTHETIC))
|
||||||
.setSyntheticCreationTime(DateTime.parse("2017-10-03T00:00:00.0Z"))
|
.setSyntheticCreationTime(DateTime.parse("2017-10-03T00:00:00.0Z"))
|
||||||
.build();
|
.build();
|
||||||
|
@ -552,18 +538,17 @@ class InvoicingPipelineTest {
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setId(2)
|
.setId(2)
|
||||||
.setRegistrarId(registrar1.getRegistrarId())
|
.setRegistrarId(registrar1.getRegistrarId())
|
||||||
.setDomainHistoryRevisionId(domainHistoryRecurring.getId())
|
|
||||||
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
.setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z"))
|
||||||
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
.setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z"))
|
||||||
.setRecurringEventKey(recurring.createVKey())
|
.setRecurringEventKey(recurring.createVKey())
|
||||||
.setTargetId(domain13.getDomainName())
|
.setTargetId(domain13.getDomainName())
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setParent(domainHistoryRecurring)
|
.setDomainHistory(domainHistoryRecurring)
|
||||||
.build();
|
.build();
|
||||||
persistResource(cancellationRecurring);
|
persistResource(cancellationRecurring);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) {
|
private static DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) {
|
||||||
DomainHistory domainHistory =
|
DomainHistory domainHistory =
|
||||||
new DomainHistory.Builder()
|
new DomainHistory.Builder()
|
||||||
.setType(HistoryEntry.Type.DOMAIN_RENEW)
|
.setType(HistoryEntry.Type.DOMAIN_RENEW)
|
||||||
|
@ -574,7 +559,7 @@ class InvoicingPipelineTest {
|
||||||
return persistResource(domainHistory);
|
return persistResource(domainHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OneTime persistOneTimeBillingEvent(
|
private static OneTime persistOneTimeBillingEvent(
|
||||||
int id, DomainBase domainBase, Registrar registrar, Reason reason, int years, Money money) {
|
int id, DomainBase domainBase, Registrar registrar, Reason reason, int years, Money money) {
|
||||||
return persistOneTimeBillingEvent(
|
return persistOneTimeBillingEvent(
|
||||||
id,
|
id,
|
||||||
|
@ -587,7 +572,7 @@ class InvoicingPipelineTest {
|
||||||
DateTime.parse("2017-10-04T00:00:00.0Z"));
|
DateTime.parse("2017-10-04T00:00:00.0Z"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private OneTime persistOneTimeBillingEvent(
|
private static OneTime persistOneTimeBillingEvent(
|
||||||
int id,
|
int id,
|
||||||
DomainBase domainBase,
|
DomainBase domainBase,
|
||||||
Registrar registrar,
|
Registrar registrar,
|
||||||
|
@ -597,7 +582,7 @@ class InvoicingPipelineTest {
|
||||||
DateTime eventTime,
|
DateTime eventTime,
|
||||||
DateTime billingTime,
|
DateTime billingTime,
|
||||||
Flag... flags) {
|
Flag... flags) {
|
||||||
google.registry.model.billing.BillingEvent.OneTime.Builder billingEventBuilder =
|
OneTime.Builder billingEventBuilder =
|
||||||
new OneTime()
|
new OneTime()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setId(id)
|
.setId(id)
|
||||||
|
@ -606,10 +591,9 @@ class InvoicingPipelineTest {
|
||||||
.setRegistrarId(registrar.getRegistrarId())
|
.setRegistrarId(registrar.getRegistrarId())
|
||||||
.setReason(reason)
|
.setReason(reason)
|
||||||
.setTargetId(domainBase.getDomainName())
|
.setTargetId(domainBase.getDomainName())
|
||||||
.setDomainRepoId("REPO-ID")
|
|
||||||
.setCost(money)
|
.setCost(money)
|
||||||
.setFlags(Arrays.stream(flags).collect(toImmutableSet()))
|
.setFlags(Arrays.stream(flags).collect(toImmutableSet()))
|
||||||
.setParent(persistDomainHistory(domainBase, registrar));
|
.setDomainHistory(persistDomainHistory(domainBase, registrar));
|
||||||
|
|
||||||
if (years > 0) {
|
if (years > 0) {
|
||||||
billingEventBuilder.setPeriodYears(years);
|
billingEventBuilder.setPeriodYears(years);
|
||||||
|
@ -620,6 +604,9 @@ class InvoicingPipelineTest {
|
||||||
|
|
||||||
private static class ChangeDomainRepo
|
private static class ChangeDomainRepo
|
||||||
extends PTransform<PCollection<BillingEvent>, PCollection<BillingEvent>> {
|
extends PTransform<PCollection<BillingEvent>, PCollection<BillingEvent>> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2695033474967615250L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PCollection<BillingEvent> expand(PCollection<BillingEvent> input) {
|
public PCollection<BillingEvent> expand(PCollection<BillingEvent> input) {
|
||||||
return input.apply(
|
return input.apply(
|
||||||
|
|
|
@ -544,7 +544,8 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||||
.setCost(Money.parse("USD 100.00"))
|
.setCost(Money.parse("USD 100.00"))
|
||||||
.setEventTime(createTime)
|
.setEventTime(createTime)
|
||||||
.setBillingTime(createTime.plus(Registry.get("tld").getRenewGracePeriodLength()))
|
.setBillingTime(createTime.plus(Registry.get("tld").getRenewGracePeriodLength()))
|
||||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
.setDomainHistory(
|
||||||
|
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// The expected one-time billing event, that should have an associated Cancellation.
|
// 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.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
import google.registry.flows.EppTestComponent.FakesAndMocksModule;
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
|
@ -327,7 +326,8 @@ public class EppTestCase {
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setEventTime(createTime)
|
.setEventTime(createTime)
|
||||||
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
.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();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ public class EppTestCase {
|
||||||
.setPeriodYears(3)
|
.setPeriodYears(3)
|
||||||
.setEventTime(renewTime)
|
.setEventTime(renewTime)
|
||||||
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
.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();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ public class EppTestCase {
|
||||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||||
.setEventTime(eventTime)
|
.setEventTime(eventTime)
|
||||||
.setRecurrenceEndTime(endTime)
|
.setRecurrenceEndTime(endTime)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,10 +386,11 @@ public class EppTestCase {
|
||||||
.setTargetId(domain.getDomainName())
|
.setTargetId(domain.getDomainName())
|
||||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||||
.setEventTime(deleteTime)
|
.setEventTime(deleteTime)
|
||||||
.setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||||
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
.setDomainHistory(
|
||||||
|
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,10 +401,11 @@ public class EppTestCase {
|
||||||
.setTargetId(domain.getDomainName())
|
.setTargetId(domain.getDomainName())
|
||||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||||
.setEventTime(deleteTime)
|
.setEventTime(deleteTime)
|
||||||
.setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||||
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
.setDomainHistory(
|
||||||
|
getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,11 +414,11 @@ public class EppTestCase {
|
||||||
*
|
*
|
||||||
* <p>This is used in the situation where we have created an expected billing event associated
|
* <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
|
* 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
|
* This is necessary because the ID will be different even though all the rest of the fields are
|
||||||
* the same.
|
* the same.
|
||||||
*/
|
*/
|
||||||
private static Key<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
|
private static VKey<OneTime> findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) {
|
||||||
Optional<OneTime> actualCreateBillingEvent =
|
Optional<OneTime> actualCreateBillingEvent =
|
||||||
loadAllOf(BillingEvent.OneTime.class).stream()
|
loadAllOf(BillingEvent.OneTime.class).stream()
|
||||||
.filter(
|
.filter(
|
||||||
|
@ -425,6 +427,6 @@ public class EppTestCase {
|
||||||
stripBillingEventId(b), stripBillingEventId(expectedBillingEvent)))
|
stripBillingEventId(b), stripBillingEventId(expectedBillingEvent)))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
assertThat(actualCreateBillingEvent).isPresent();
|
assertThat(actualCreateBillingEvent).isPresent();
|
||||||
return Key.create(actualCreateBillingEvent.get());
|
return actualCreateBillingEvent.get().createVKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1440,7 +1440,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(existingDomain.getCreationTime())
|
.setEventTime(existingDomain.getCreationTime())
|
||||||
.setRecurrenceEndTime(clock.nowUtc())
|
.setRecurrenceEndTime(clock.nowUtc())
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.build());
|
||||||
return persistResource(
|
return persistResource(
|
||||||
existingDomain.asBuilder().setAutorenewBillingEvent(renewEvent.createVKey()).build());
|
existingDomain.asBuilder().setAutorenewBillingEvent(renewEvent.createVKey()).build());
|
||||||
|
|
|
@ -301,7 +301,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(billingTime)
|
.setBillingTime(billingTime)
|
||||||
.setFlags(expectedBillingFlags)
|
.setFlags(expectedBillingFlags)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setAllocationToken(allocationToken == null ? null : allocationToken.createVKey())
|
.setAllocationToken(allocationToken == null ? null : allocationToken.createVKey())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(domain.getRegistrationExpirationTime())
|
.setEventTime(domain.getRegistrationExpirationTime())
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setRenewalPriceBehavior(renewalPriceInfo.renewalPriceBehavior())
|
.setRenewalPriceBehavior(renewalPriceInfo.renewalPriceBehavior())
|
||||||
.setRenewalPrice(renewalPriceInfo.renewalPrice())
|
.setRenewalPrice(renewalPriceInfo.renewalPrice())
|
||||||
.build();
|
.build();
|
||||||
|
@ -334,7 +334,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(billingTime)
|
.setBillingTime(billingTime)
|
||||||
.setFlags(expectedBillingFlags)
|
.setFlags(expectedBillingFlags)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
expectedBillingEvents.add(eapBillingEvent);
|
expectedBillingEvents.add(eapBillingEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||||
.setEventTime(eventTime)
|
.setEventTime(eventTime)
|
||||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||||
.setOneTimeEventKey(graceBillingEvent.createVKey())
|
.setOneTimeEventKey(graceBillingEvent.createVKey())
|
||||||
.setParent(historyEntryDomainDelete)
|
.setDomainHistory(historyEntryDomainDelete)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setEventTime(TIME_BEFORE_FLOW.minusDays(4))
|
.setEventTime(TIME_BEFORE_FLOW.minusDays(4))
|
||||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||||
.setParent(earlierHistoryEntry)
|
.setDomainHistory(earlierHistoryEntry)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||||
.setRegistrarId(registrarId)
|
.setRegistrarId(registrarId)
|
||||||
.setEventTime(A_MONTH_FROM_NOW)
|
.setEventTime(A_MONTH_FROM_NOW)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(earlierHistoryEntry);
|
.setDomainHistory(earlierHistoryEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PollMessage.Autorenew.Builder createAutorenewPollMessage(String registrarId) {
|
private PollMessage.Autorenew.Builder createAutorenewPollMessage(String registrarId) {
|
||||||
|
|
|
@ -388,7 +388,7 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, DomainBase
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.build());
|
||||||
VKey<BillingEvent.Recurring> recurringVKey = renewEvent.createVKey();
|
VKey<BillingEvent.Recurring> recurringVKey = renewEvent.createVKey();
|
||||||
// Add an AUTO_RENEW grace period to the saved resource.
|
// Add an AUTO_RENEW grace period to the saved resource.
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class DomainPricingLogicTest {
|
||||||
Recurring recurring =
|
Recurring recurring =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setRegistrarId(domain.getCreationRegistrarId())
|
.setRegistrarId(domain.getCreationRegistrarId())
|
||||||
.setEventTime(DateTime.parse("1999-01-05T00:00:00Z"))
|
.setEventTime(DateTime.parse("1999-01-05T00:00:00Z"))
|
||||||
.setFlags(ImmutableSet.of(AUTO_RENEW))
|
.setFlags(ImmutableSet.of(AUTO_RENEW))
|
||||||
|
|
|
@ -170,7 +170,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(expirationTime)
|
.setEventTime(expirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainCreate)
|
.setDomainHistory(historyEntryDomainCreate)
|
||||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||||
.setRenewalPrice(renewalPrice)
|
.setRenewalPrice(renewalPrice)
|
||||||
.build();
|
.build();
|
||||||
|
@ -284,7 +284,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
||||||
.setPeriodYears(renewalYears)
|
.setPeriodYears(renewalYears)
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc().plus(Registry.get("tld").getRenewGracePeriodLength()))
|
.setBillingTime(clock.nowUtc().plus(Registry.get("tld").getRenewGracePeriodLength()))
|
||||||
.setParent(historyEntryDomainRenew)
|
.setDomainHistory(historyEntryDomainRenew)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEvents(
|
assertBillingEvents(
|
||||||
renewBillingEvent,
|
renewBillingEvent,
|
||||||
|
@ -297,7 +297,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(expirationTime)
|
.setEventTime(expirationTime)
|
||||||
.setRecurrenceEndTime(clock.nowUtc())
|
.setRecurrenceEndTime(clock.nowUtc())
|
||||||
.setParent(
|
.setDomainHistory(
|
||||||
getOnlyHistoryEntryOfType(
|
getOnlyHistoryEntryOfType(
|
||||||
domain, HistoryEntry.Type.DOMAIN_CREATE, DomainHistory.class))
|
domain, HistoryEntry.Type.DOMAIN_CREATE, DomainHistory.class))
|
||||||
.build(),
|
.build(),
|
||||||
|
@ -310,7 +310,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(domain.getRegistrationExpirationTime())
|
.setEventTime(domain.getRegistrationExpirationTime())
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainRenew)
|
.setDomainHistory(historyEntryDomainRenew)
|
||||||
.build());
|
.build());
|
||||||
// There should only be the new autorenew poll message, as the old one will have been deleted
|
// 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.
|
// since it had no messages left to deliver.
|
||||||
|
|
|
@ -212,7 +212,7 @@ class DomainRestoreRequestFlowTest
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(expirationTime)
|
.setEventTime(expirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainRestore)
|
.setDomainHistory(historyEntryDomainRestore)
|
||||||
.build(),
|
.build(),
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setReason(Reason.RESTORE)
|
.setReason(Reason.RESTORE)
|
||||||
|
@ -222,7 +222,7 @@ class DomainRestoreRequestFlowTest
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc())
|
.setBillingTime(clock.nowUtc())
|
||||||
.setParent(historyEntryDomainRestore)
|
.setDomainHistory(historyEntryDomainRestore)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ class DomainRestoreRequestFlowTest
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(newExpirationTime)
|
.setEventTime(newExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainRestore)
|
.setDomainHistory(historyEntryDomainRestore)
|
||||||
.build(),
|
.build(),
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setReason(Reason.RESTORE)
|
.setReason(Reason.RESTORE)
|
||||||
|
@ -291,7 +291,7 @@ class DomainRestoreRequestFlowTest
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc())
|
.setBillingTime(clock.nowUtc())
|
||||||
.setParent(historyEntryDomainRestore)
|
.setDomainHistory(historyEntryDomainRestore)
|
||||||
.build(),
|
.build(),
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
|
@ -301,7 +301,7 @@ class DomainRestoreRequestFlowTest
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc())
|
.setBillingTime(clock.nowUtc())
|
||||||
.setParent(historyEntryDomainRestore)
|
.setDomainHistory(historyEntryDomainRestore)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,13 +265,13 @@ class DomainTransferApproveFlowTest
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setCost(Money.of(USD, 11).multipliedBy(expectedYearsToCharge))
|
.setCost(Money.of(USD, 11).multipliedBy(expectedYearsToCharge))
|
||||||
.setPeriodYears(expectedYearsToCharge)
|
.setPeriodYears(expectedYearsToCharge)
|
||||||
.setParent(historyEntryTransferApproved)
|
.setDomainHistory(historyEntryTransferApproved)
|
||||||
.build();
|
.build();
|
||||||
assertBillingEventsForResource(
|
assertBillingEventsForResource(
|
||||||
domain,
|
domain,
|
||||||
Streams.concat(
|
Streams.concat(
|
||||||
Arrays.stream(expectedCancellationBillingEvents)
|
Arrays.stream(expectedCancellationBillingEvents)
|
||||||
.map(builder -> builder.setParent(historyEntryTransferApproved).build()),
|
.map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()),
|
||||||
Stream.of(
|
Stream.of(
|
||||||
transferBillingEvent,
|
transferBillingEvent,
|
||||||
getLosingClientAutorenewEvent()
|
getLosingClientAutorenewEvent()
|
||||||
|
@ -281,7 +281,7 @@ class DomainTransferApproveFlowTest
|
||||||
getGainingClientAutorenewEvent()
|
getGainingClientAutorenewEvent()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setEventTime(domain.getRegistrationExpirationTime())
|
.setEventTime(domain.getRegistrationExpirationTime())
|
||||||
.setParent(historyEntryTransferApproved)
|
.setDomainHistory(historyEntryTransferApproved)
|
||||||
.build()))
|
.build()))
|
||||||
.toArray(BillingEvent[]::new));
|
.toArray(BillingEvent[]::new));
|
||||||
// There should be a grace period for the new transfer billing event.
|
// There should be a grace period for the new transfer billing event.
|
||||||
|
@ -308,7 +308,7 @@ class DomainTransferApproveFlowTest
|
||||||
domain,
|
domain,
|
||||||
Streams.concat(
|
Streams.concat(
|
||||||
Arrays.stream(expectedCancellationBillingEvents)
|
Arrays.stream(expectedCancellationBillingEvents)
|
||||||
.map(builder -> builder.setParent(historyEntryTransferApproved).build()),
|
.map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()),
|
||||||
Stream.of(
|
Stream.of(
|
||||||
getLosingClientAutorenewEvent()
|
getLosingClientAutorenewEvent()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
|
@ -317,7 +317,7 @@ class DomainTransferApproveFlowTest
|
||||||
getGainingClientAutorenewEvent()
|
getGainingClientAutorenewEvent()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setEventTime(domain.getRegistrationExpirationTime())
|
.setEventTime(domain.getRegistrationExpirationTime())
|
||||||
.setParent(historyEntryTransferApproved)
|
.setDomainHistory(historyEntryTransferApproved)
|
||||||
.build()))
|
.build()))
|
||||||
.toArray(BillingEvent[]::new));
|
.toArray(BillingEvent[]::new));
|
||||||
// There should be no grace period.
|
// There should be no grace period.
|
||||||
|
|
|
@ -143,7 +143,7 @@ abstract class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(REGISTRATION_EXPIRATION_TIME)
|
.setEventTime(REGISTRATION_EXPIRATION_TIME)
|
||||||
.setRecurrenceEndTime(TRANSFER_EXPIRATION_TIME)
|
.setRecurrenceEndTime(TRANSFER_EXPIRATION_TIME)
|
||||||
.setParent(historyEntryDomainCreate)
|
.setDomainHistory(historyEntryDomainCreate)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ abstract class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME)
|
.setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(
|
.setDomainHistory(
|
||||||
getOnlyHistoryEntryOfType(
|
getOnlyHistoryEntryOfType(
|
||||||
domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST, DomainHistory.class))
|
domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST, DomainHistory.class))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -262,7 +262,7 @@ class DomainTransferRequestFlowTest
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setCost(transferCost.orElse(Money.of(USD, 11)))
|
.setCost(transferCost.orElse(Money.of(USD, 11)))
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setParent(historyEntryTransferRequest)
|
.setDomainHistory(historyEntryTransferRequest)
|
||||||
.build());
|
.build());
|
||||||
} else {
|
} else {
|
||||||
// Superuser transfers with no bundled renewal have no transfer billing event.
|
// 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.
|
// Construct extra billing events expected by the specific test.
|
||||||
ImmutableSet<BillingEvent> extraBillingEvents =
|
ImmutableSet<BillingEvent> extraBillingEvents =
|
||||||
Stream.of(extraExpectedBillingEvents)
|
Stream.of(extraExpectedBillingEvents)
|
||||||
.map(builder -> builder.setParent(historyEntryTransferRequest).build())
|
.map(builder -> builder.setDomainHistory(historyEntryTransferRequest).build())
|
||||||
.collect(toImmutableSet());
|
.collect(toImmutableSet());
|
||||||
// Assert that the billing events we constructed above actually exist in Datastore.
|
// Assert that the billing events we constructed above actually exist in Datastore.
|
||||||
ImmutableSet<BillingEvent> expectedBillingEvents =
|
ImmutableSet<BillingEvent> expectedBillingEvents =
|
||||||
|
|
|
@ -815,7 +815,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||||
.setCost(Money.of(USD, 19))
|
.setCost(Money.of(USD, 19))
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc())
|
.setBillingTime(clock.nowUtc())
|
||||||
.setParent(
|
.setDomainHistory(
|
||||||
getOnlyHistoryEntryOfType(
|
getOnlyHistoryEntryOfType(
|
||||||
reloadResourceByForeignKey(), DOMAIN_UPDATE, DomainHistory.class))
|
reloadResourceByForeignKey(), DOMAIN_UPDATE, DomainHistory.class))
|
||||||
.build());
|
.build());
|
||||||
|
|
|
@ -30,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import google.registry.model.EntityTestCase;
|
import google.registry.model.EntityTestCase;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
|
@ -110,7 +109,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT))
|
.setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT))
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
|
@ -123,7 +122,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -132,13 +131,13 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.OneTime.Builder()
|
new BillingEvent.OneTime.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setFlags(
|
.setFlags(
|
||||||
ImmutableSet.of(
|
ImmutableSet.of(
|
||||||
BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
|
BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
|
||||||
.setSyntheticCreationTime(now.plusDays(10))
|
.setSyntheticCreationTime(now.plusDays(10))
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setCost(Money.of(USD, 1))
|
.setCost(Money.of(USD, 1))
|
||||||
.setEventTime(now)
|
.setEventTime(now)
|
||||||
|
@ -148,7 +147,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Cancellation.Builder()
|
new BillingEvent.Cancellation.Builder()
|
||||||
.setParent(domainHistory2)
|
.setDomainHistory(domainHistory2)
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setEventTime(now.plusDays(1))
|
.setEventTime(now.plusDays(1))
|
||||||
.setBillingTime(now.plusDays(5))
|
.setBillingTime(now.plusDays(5))
|
||||||
|
@ -158,14 +157,15 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Cancellation.Builder()
|
new BillingEvent.Cancellation.Builder()
|
||||||
.setParent(domainHistory2)
|
.setDomainHistory(domainHistory2)
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusDays(1))
|
.setEventTime(now.plusDays(1))
|
||||||
.setBillingTime(now.plusYears(1).plusDays(45))
|
.setBillingTime(now.plusYears(1).plusDays(45))
|
||||||
.setRecurringEventKey(recurring.createVKey())));
|
.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();
|
return builder.setRegistrarId("TheRegistrar").setTargetId("foo.tld").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
oneTime
|
oneTime
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
|
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
.setCancellationMatchingBillingEvent(recurring)
|
||||||
.build());
|
.build());
|
||||||
assertThat(thrown)
|
assertThat(thrown)
|
||||||
.hasMessageThat()
|
.hasMessageThat()
|
||||||
|
@ -248,11 +248,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
IllegalStateException thrown =
|
IllegalStateException thrown =
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
() ->
|
() -> oneTime.asBuilder().setCancellationMatchingBillingEvent(recurring).build());
|
||||||
oneTime
|
|
||||||
.asBuilder()
|
|
||||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
|
||||||
.build());
|
|
||||||
assertThat(thrown)
|
assertThat(thrown)
|
||||||
.hasMessageThat()
|
.hasMessageThat()
|
||||||
.contains(
|
.contains(
|
||||||
|
@ -266,7 +262,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
BillingEvent.Cancellation.forGracePeriod(
|
BillingEvent.Cancellation.forGracePeriod(
|
||||||
GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), oneTime),
|
GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), oneTime),
|
||||||
domainHistory2.getModificationTime(),
|
domainHistory2.getModificationTime(),
|
||||||
Key.create(domainHistory2),
|
domainHistory2.getDomainHistoryId(),
|
||||||
"foo.tld");
|
"foo.tld");
|
||||||
// Set ID to be the same to ignore for the purposes of comparison.
|
// Set ID to be the same to ignore for the purposes of comparison.
|
||||||
assertThat(newCancellation.asBuilder().setId(cancellationOneTime.getId()).build())
|
assertThat(newCancellation.asBuilder().setId(cancellationOneTime.getId()).build())
|
||||||
|
@ -284,7 +280,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
"TheRegistrar",
|
"TheRegistrar",
|
||||||
recurring.createVKey()),
|
recurring.createVKey()),
|
||||||
domainHistory2.getModificationTime(),
|
domainHistory2.getModificationTime(),
|
||||||
Key.create(domainHistory2),
|
domainHistory2.getDomainHistoryId(),
|
||||||
"foo.tld");
|
"foo.tld");
|
||||||
// Set ID to be the same to ignore for the purposes of comparison.
|
// Set ID to be the same to ignore for the purposes of comparison.
|
||||||
assertThat(newCancellation.asBuilder().setId(cancellationRecurring.getId()).build())
|
assertThat(newCancellation.asBuilder().setId(cancellationRecurring.getId()).build())
|
||||||
|
@ -304,7 +300,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
now.plusDays(1),
|
now.plusDays(1),
|
||||||
"a registrar"),
|
"a registrar"),
|
||||||
domainHistory.getModificationTime(),
|
domainHistory.getModificationTime(),
|
||||||
Key.create(domainHistory),
|
domainHistory.getDomainHistoryId(),
|
||||||
"foo.tld"));
|
"foo.tld"));
|
||||||
assertThat(thrown).hasMessageThat().contains("grace period without billing event");
|
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");
|
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
|
@Test
|
||||||
void testReasonRequiringPeriodYears_missingPeriodYears_throwsException() {
|
void testReasonRequiringPeriodYears_missingPeriodYears_throwsException() {
|
||||||
IllegalStateException thrown =
|
IllegalStateException thrown =
|
||||||
|
@ -357,7 +347,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
.setCost(Money.of(USD, 10))
|
.setCost(Money.of(USD, 10))
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setTargetId("example.tld")
|
.setTargetId("example.tld")
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build());
|
.build());
|
||||||
assertThat(thrown)
|
assertThat(thrown)
|
||||||
.hasMessageThat()
|
.hasMessageThat()
|
||||||
|
@ -379,7 +369,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
.setCost(Money.of(USD, 10))
|
.setCost(Money.of(USD, 10))
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setTargetId("example.tld")
|
.setTargetId("example.tld")
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build());
|
.build());
|
||||||
assertThat(thrown)
|
assertThat(thrown)
|
||||||
.hasMessageThat()
|
.hasMessageThat()
|
||||||
|
@ -397,7 +387,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
.setCost(Money.of(USD, 10))
|
.setCost(Money.of(USD, 10))
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setTargetId("example.tld")
|
.setTargetId("example.tld")
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +403,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -429,7 +419,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -456,7 +446,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -479,7 +469,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -506,7 +496,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -529,7 +519,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -557,7 +547,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -585,7 +575,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -616,7 +606,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -648,7 +638,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -680,7 +670,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -711,7 +701,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -743,7 +733,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -775,7 +765,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -792,7 +782,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -808,7 +798,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
persistResource(
|
persistResource(
|
||||||
commonInit(
|
commonInit(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -826,7 +816,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() ->
|
() ->
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -847,7 +837,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() ->
|
() ->
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
@ -869,7 +859,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() ->
|
() ->
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setEventTime(now.plusYears(1))
|
.setEventTime(now.plusYears(1))
|
||||||
|
|
|
@ -17,10 +17,6 @@ package google.registry.model.common;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
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.contact.ContactResource;
|
||||||
import google.registry.model.domain.DomainBase;
|
import google.registry.model.domain.DomainBase;
|
||||||
import google.registry.model.domain.DomainHistory;
|
import google.registry.model.domain.DomainHistory;
|
||||||
|
@ -44,7 +40,7 @@ import org.junit.jupiter.api.Test;
|
||||||
public class ClassPathManagerTest {
|
public class ClassPathManagerTest {
|
||||||
@Test
|
@Test
|
||||||
void getClass_classInClassRegistry_returnsClass() throws ClassNotFoundException {
|
void getClass_classInClassRegistry_returnsClass() throws ClassNotFoundException {
|
||||||
/**
|
/*
|
||||||
* Class names are used in stringified vkeys, which can be present in task queues. Class name is
|
* 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
|
* 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
|
* 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"))
|
assertThat(ClassPathManager.getClass("ForeignKeyContactIndex"))
|
||||||
.isEqualTo(ForeignKeyContactIndex.class);
|
.isEqualTo(ForeignKeyContactIndex.class);
|
||||||
assertThat(ClassPathManager.getClass("Modification")).isEqualTo(Modification.class);
|
|
||||||
assertThat(ClassPathManager.getClass("AllocationToken")).isEqualTo(AllocationToken.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("RdeRevision")).isEqualTo(RdeRevision.class);
|
||||||
assertThat(ClassPathManager.getClass("HostResource")).isEqualTo(HostResource.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("Registrar")).isEqualTo(Registrar.class);
|
||||||
assertThat(ClassPathManager.getClass("ContactResource")).isEqualTo(ContactResource.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("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class);
|
||||||
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
assertThat(ClassPathManager.getClass("EppResourceIndexBucket"))
|
||||||
.isEqualTo(EppResourceIndexBucket.class);
|
.isEqualTo(EppResourceIndexBucket.class);
|
||||||
|
@ -85,7 +77,7 @@ public class ClassPathManagerTest {
|
||||||
IllegalArgumentException thrown =
|
IllegalArgumentException thrown =
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class, () -> ClassPathManager.getClass("DomainHistory"));
|
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
|
@Test
|
||||||
|
@ -94,12 +86,14 @@ public class ClassPathManagerTest {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalArgumentException.class,
|
IllegalArgumentException.class,
|
||||||
() -> ClassPathManager.getClassName(DomainHistory.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
|
@Test
|
||||||
void getClassName() {
|
void getClassName() {
|
||||||
/**
|
/*
|
||||||
* Class names are used in stringified vkeys, which can be present in task queues. Class name is
|
* 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
|
* 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
|
* 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))
|
assertThat(ClassPathManager.getClassName(ForeignKeyContactIndex.class))
|
||||||
.isEqualTo("ForeignKeyContactIndex");
|
.isEqualTo("ForeignKeyContactIndex");
|
||||||
assertThat(ClassPathManager.getClassName(Modification.class)).isEqualTo("Modification");
|
|
||||||
assertThat(ClassPathManager.getClassName(AllocationToken.class)).isEqualTo("AllocationToken");
|
assertThat(ClassPathManager.getClassName(AllocationToken.class)).isEqualTo("AllocationToken");
|
||||||
assertThat(ClassPathManager.getClassName(OneTime.class)).isEqualTo("OneTime");
|
|
||||||
assertThat(ClassPathManager.getClassName(RdeRevision.class)).isEqualTo("RdeRevision");
|
assertThat(ClassPathManager.getClassName(RdeRevision.class)).isEqualTo("RdeRevision");
|
||||||
assertThat(ClassPathManager.getClassName(HostResource.class)).isEqualTo("HostResource");
|
assertThat(ClassPathManager.getClassName(HostResource.class)).isEqualTo("HostResource");
|
||||||
assertThat(ClassPathManager.getClassName(Recurring.class)).isEqualTo("Recurring");
|
|
||||||
assertThat(ClassPathManager.getClassName(Registrar.class)).isEqualTo("Registrar");
|
assertThat(ClassPathManager.getClassName(Registrar.class)).isEqualTo("Registrar");
|
||||||
assertThat(ClassPathManager.getClassName(ContactResource.class)).isEqualTo("ContactResource");
|
assertThat(ClassPathManager.getClassName(ContactResource.class)).isEqualTo("ContactResource");
|
||||||
assertThat(ClassPathManager.getClassName(Cancellation.class)).isEqualTo("Cancellation");
|
|
||||||
assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class))
|
assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class))
|
||||||
.isEqualTo("GaeUserIdConverter");
|
.isEqualTo("GaeUserIdConverter");
|
||||||
assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class))
|
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;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
|
import google.registry.model.billing.BillingEvent.Recurring;
|
||||||
import google.registry.model.common.EntityGroupRoot;
|
import google.registry.model.common.EntityGroupRoot;
|
||||||
import google.registry.model.contact.ContactResource;
|
import google.registry.model.contact.ContactResource;
|
||||||
import google.registry.model.domain.DesignatedContact.Type;
|
import google.registry.model.domain.DesignatedContact.Type;
|
||||||
|
@ -409,11 +410,9 @@ public class DomainBaseSqlTest {
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setTargetId("example.com")
|
.setTargetId("example.com")
|
||||||
.setRegistrarId("registrar1")
|
.setRegistrarId("registrar1")
|
||||||
.setDomainRepoId("4-COM")
|
|
||||||
.setDomainHistoryRevisionId(1L)
|
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
new PollMessage.Autorenew.Builder()
|
new PollMessage.Autorenew.Builder()
|
||||||
|
@ -436,11 +435,10 @@ public class DomainBaseSqlTest {
|
||||||
.setReason(Reason.SERVER_STATUS)
|
.setReason(Reason.SERVER_STATUS)
|
||||||
.setTargetId("example.com")
|
.setTargetId("example.com")
|
||||||
.setRegistrarId("registrar1")
|
.setRegistrarId("registrar1")
|
||||||
.setDomainRepoId("4-COM")
|
|
||||||
.setBillingTime(DateTime.now(UTC))
|
.setBillingTime(DateTime.now(UTC))
|
||||||
.setCost(Money.of(USD, 100))
|
.setCost(Money.of(USD, 100))
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
DomainTransferData transferData =
|
DomainTransferData transferData =
|
||||||
new DomainTransferData.Builder()
|
new DomainTransferData.Builder()
|
||||||
|
@ -536,11 +534,9 @@ public class DomainBaseSqlTest {
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setTargetId("example.com")
|
.setTargetId("example.com")
|
||||||
.setRegistrarId("registrar1")
|
.setRegistrarId("registrar1")
|
||||||
.setDomainRepoId("4-COM")
|
|
||||||
.setDomainHistoryRevisionId(1L)
|
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
new PollMessage.Autorenew.Builder()
|
new PollMessage.Autorenew.Builder()
|
||||||
|
@ -563,11 +559,10 @@ public class DomainBaseSqlTest {
|
||||||
.setReason(Reason.SERVER_STATUS)
|
.setReason(Reason.SERVER_STATUS)
|
||||||
.setTargetId("example.com")
|
.setTargetId("example.com")
|
||||||
.setRegistrarId("registrar1")
|
.setRegistrarId("registrar1")
|
||||||
.setDomainRepoId("4-COM")
|
|
||||||
.setBillingTime(DateTime.now(UTC))
|
.setBillingTime(DateTime.now(UTC))
|
||||||
.setCost(Money.of(USD, 100))
|
.setCost(Money.of(USD, 100))
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
DomainTransferData transferData =
|
DomainTransferData transferData =
|
||||||
createPendingTransferData(
|
createPendingTransferData(
|
||||||
|
@ -599,8 +594,7 @@ public class DomainBaseSqlTest {
|
||||||
domain =
|
domain =
|
||||||
domain
|
domain
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setAutorenewBillingEvent(
|
.setAutorenewBillingEvent(Recurring.createVKey(billEvent.getId()))
|
||||||
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))
|
|
||||||
.setAutorenewPollMessage(
|
.setAutorenewPollMessage(
|
||||||
createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()),
|
createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()),
|
||||||
autorenewPollMessage.getHistoryRevisionId())
|
autorenewPollMessage.getHistoryRevisionId())
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class DomainBaseTest {
|
||||||
domainHistory =
|
domainHistory =
|
||||||
persistResource(
|
persistResource(
|
||||||
new DomainHistory.Builder()
|
new DomainHistory.Builder()
|
||||||
.setDomainRepoId(domain.createVKey().getOfyKey().getName())
|
.setDomainRepoId(domain.getRepoId())
|
||||||
.setModificationTime(fakeClock.nowUtc())
|
.setModificationTime(fakeClock.nowUtc())
|
||||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
|
@ -118,11 +118,10 @@ public class DomainBaseTest {
|
||||||
.setReason(Reason.SERVER_STATUS)
|
.setReason(Reason.SERVER_STATUS)
|
||||||
.setTargetId(domain.getDomainName())
|
.setTargetId(domain.getDomainName())
|
||||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||||
.setDomainRepoId(domain.getRepoId())
|
|
||||||
.setBillingTime(DateTime.now(UTC))
|
.setBillingTime(DateTime.now(UTC))
|
||||||
.setCost(Money.of(USD, 100))
|
.setCost(Money.of(USD, 100))
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build())
|
.build())
|
||||||
.createVKey();
|
.createVKey();
|
||||||
DomainHistory historyEntry =
|
DomainHistory historyEntry =
|
||||||
|
@ -145,11 +144,10 @@ public class DomainBaseTest {
|
||||||
.setReason(Reason.SERVER_STATUS)
|
.setReason(Reason.SERVER_STATUS)
|
||||||
.setTargetId("example.com")
|
.setTargetId("example.com")
|
||||||
.setRegistrarId("registrar1")
|
.setRegistrarId("registrar1")
|
||||||
.setDomainRepoId("4-COM")
|
|
||||||
.setBillingTime(DateTime.now(UTC))
|
.setBillingTime(DateTime.now(UTC))
|
||||||
.setCost(Money.of(USD, 100))
|
.setCost(Money.of(USD, 100))
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
oneTimeBillKey = oneTimeBill.createVKey();
|
oneTimeBillKey = oneTimeBill.createVKey();
|
||||||
BillingEvent.Recurring recurringBill =
|
BillingEvent.Recurring recurringBill =
|
||||||
|
@ -159,11 +157,9 @@ public class DomainBaseTest {
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setTargetId(domain.getDomainName())
|
.setTargetId(domain.getDomainName())
|
||||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||||
.setDomainRepoId(domain.getRepoId())
|
|
||||||
.setDomainHistoryRevisionId(historyEntry.getId())
|
|
||||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
insertInDb(historyEntry, oneTimeBill, recurringBill);
|
insertInDb(historyEntry, oneTimeBill, recurringBill);
|
||||||
recurringBillKey = recurringBill.createVKey();
|
recurringBillKey = recurringBill.createVKey();
|
||||||
|
@ -427,7 +423,7 @@ public class DomainBaseTest {
|
||||||
.plus(Registry.get("com").getTransferGracePeriodLength()))
|
.plus(Registry.get("com").getTransferGracePeriodLength()))
|
||||||
.setCost(Money.of(USD, 11))
|
.setCost(Money.of(USD, 11))
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.build());
|
||||||
domain =
|
domain =
|
||||||
domain
|
domain
|
||||||
|
|
|
@ -18,12 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
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;
|
||||||
import google.registry.model.billing.BillingEvent.Reason;
|
import google.registry.model.billing.BillingEvent.Reason;
|
||||||
import google.registry.model.billing.BillingEvent.Recurring;
|
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.domain.rgp.GracePeriodStatus;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.testing.AppEngineExtension;
|
import google.registry.testing.AppEngineExtension;
|
||||||
import org.joda.money.CurrencyUnit;
|
import org.joda.money.CurrencyUnit;
|
||||||
|
@ -54,20 +53,12 @@ public class GracePeriodTest {
|
||||||
.setBillingTime(now.plusDays(1))
|
.setBillingTime(now.plusDays(1))
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setCost(Money.of(CurrencyUnit.USD, 42))
|
.setCost(Money.of(CurrencyUnit.USD, 42))
|
||||||
.setParent(
|
.setDomainHistoryId(new DomainHistoryId("domain", 12345))
|
||||||
Key.create(Key.create(DomainBase.class, "domain"), DomainHistory.class, 12345))
|
|
||||||
.setReason(Reason.CREATE)
|
.setReason(Reason.CREATE)
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setTargetId("foo.google")
|
.setTargetId("foo.google")
|
||||||
.build();
|
.build();
|
||||||
recurringKey =
|
recurringKey = Recurring.createVKey(12345L);
|
||||||
VKey.create(
|
|
||||||
Recurring.class,
|
|
||||||
12345L,
|
|
||||||
Key.create(
|
|
||||||
Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L),
|
|
||||||
Recurring.class,
|
|
||||||
12345L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -60,7 +60,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
||||||
String domainRepoId = "4-TLD";
|
String domainRepoId = "4-TLD";
|
||||||
createTld("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 =
|
domain =
|
||||||
new DomainBase()
|
new DomainBase()
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
|
@ -73,7 +73,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
||||||
.setContacts(ImmutableSet.of())
|
.setContacts(ImmutableSet.of())
|
||||||
.build();
|
.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 =
|
registrantContact =
|
||||||
new ContactResource.Builder()
|
new ContactResource.Builder()
|
||||||
.setRepoId("contact_id")
|
.setRepoId("contact_id")
|
||||||
|
@ -82,7 +82,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase {
|
||||||
.setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID)
|
.setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID)
|
||||||
.build();
|
.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 =
|
host =
|
||||||
new HostResource.Builder()
|
new HostResource.Builder()
|
||||||
.setRepoId("host")
|
.setRepoId("host")
|
||||||
|
|
|
@ -20,6 +20,9 @@ import static org.joda.time.DateTimeZone.UTC;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.model.billing.BillingEvent;
|
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.DomainBase;
|
||||||
import google.registry.model.domain.Period;
|
import google.registry.model.domain.Period;
|
||||||
import google.registry.model.eppcommon.Trid;
|
import google.registry.model.eppcommon.Trid;
|
||||||
|
@ -50,21 +53,9 @@ public class TransferDataTest {
|
||||||
void beforeEach() {
|
void beforeEach() {
|
||||||
Key<HistoryEntry> historyEntryKey =
|
Key<HistoryEntry> historyEntryKey =
|
||||||
Key.create(Key.create(DomainBase.class, "4-TLD"), HistoryEntry.class, 1356L);
|
Key.create(Key.create(DomainBase.class, "4-TLD"), HistoryEntry.class, 1356L);
|
||||||
transferBillingEventKey =
|
transferBillingEventKey = OneTime.createVKey(12345L);
|
||||||
VKey.create(
|
otherServerApproveBillingEventKey = Cancellation.createVKey(2468L);
|
||||||
BillingEvent.OneTime.class,
|
recurringBillingEventKey = Recurring.createVKey(13579L);
|
||||||
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));
|
|
||||||
autorenewPollMessageKey =
|
autorenewPollMessageKey =
|
||||||
VKey.create(
|
VKey.create(
|
||||||
PollMessage.Autorenew.class,
|
PollMessage.Autorenew.class,
|
||||||
|
|
|
@ -19,9 +19,10 @@ import static google.registry.testing.DatabaseHelper.newDomainBase;
|
||||||
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
import static google.registry.testing.DatabaseHelper.persistActiveContact;
|
||||||
|
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.model.billing.BillingEvent;
|
|
||||||
import google.registry.model.common.ClassPathManager;
|
import google.registry.model.common.ClassPathManager;
|
||||||
import google.registry.model.domain.DomainBase;
|
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.model.reporting.HistoryEntry;
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.testing.AppEngineExtension;
|
import google.registry.testing.AppEngineExtension;
|
||||||
|
@ -60,14 +61,12 @@ public class VKeyTranslatorFactoryTest {
|
||||||
void testEntityWithAncestor() {
|
void testEntityWithAncestor() {
|
||||||
Key<DomainBase> domainKey = Key.create(DomainBase.class, "ROID-1");
|
Key<DomainBase> domainKey = Key.create(DomainBase.class, "ROID-1");
|
||||||
Key<HistoryEntry> historyEntryKey = Key.create(domainKey, HistoryEntry.class, 10L);
|
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.getKind()).isEqualTo(DomainHistory.class);
|
||||||
assertThat(vkey.getOfyKey()).isEqualTo(oneTimeKey);
|
assertThat(vkey.getOfyKey()).isEqualTo(historyEntryKey);
|
||||||
assertThat(vkey.getSqlKey()).isEqualTo(200L);
|
assertThat(vkey.getSqlKey()).isEqualTo(new DomainHistoryId("ROID-1", 10L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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)
|
.setPeriodYears(2)
|
||||||
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
||||||
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build());
|
.build());
|
||||||
domain =
|
domain =
|
||||||
domain
|
domain
|
||||||
|
@ -295,7 +295,7 @@ public class DomainBaseToXjcConverterTest {
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setEventTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
.setEventTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
||||||
.setBillingTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
.setBillingTime(DateTime.parse("1920-01-01T00:00:00Z"))
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build())),
|
.build())),
|
||||||
GracePeriod.create(
|
GracePeriod.create(
|
||||||
GracePeriodStatus.TRANSFER,
|
GracePeriodStatus.TRANSFER,
|
||||||
|
@ -319,7 +319,7 @@ public class DomainBaseToXjcConverterTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(END_OF_TIME)
|
.setEventTime(END_OF_TIME)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build())
|
.build())
|
||||||
.createVKey())
|
.createVKey())
|
||||||
.setAutorenewPollMessage(
|
.setAutorenewPollMessage(
|
||||||
|
@ -349,7 +349,7 @@ public class DomainBaseToXjcConverterTest {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(END_OF_TIME)
|
.setEventTime(END_OF_TIME)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(domainHistory)
|
.setDomainHistory(domainHistory)
|
||||||
.build())
|
.build())
|
||||||
.createVKey())
|
.createVKey())
|
||||||
.setServerApproveAutorenewPollMessage(
|
.setServerApproveAutorenewPollMessage(
|
||||||
|
|
|
@ -84,7 +84,7 @@ final class RdeFixtures {
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
||||||
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.build());
|
||||||
domain =
|
domain =
|
||||||
domain
|
domain
|
||||||
|
@ -138,7 +138,7 @@ final class RdeFixtures {
|
||||||
.setPeriodYears(2)
|
.setPeriodYears(2)
|
||||||
.setEventTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
.setEventTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
||||||
.setBillingTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
.setBillingTime(DateTime.parse("1992-01-01T00:00:00Z"))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build())),
|
.build())),
|
||||||
GracePeriod.create(
|
GracePeriod.create(
|
||||||
GracePeriodStatus.TRANSFER,
|
GracePeriodStatus.TRANSFER,
|
||||||
|
@ -162,7 +162,7 @@ final class RdeFixtures {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(END_OF_TIME)
|
.setEventTime(END_OF_TIME)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build())
|
.build())
|
||||||
.createVKey())
|
.createVKey())
|
||||||
.setAutorenewPollMessage(
|
.setAutorenewPollMessage(
|
||||||
|
@ -192,7 +192,7 @@ final class RdeFixtures {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(END_OF_TIME)
|
.setEventTime(END_OF_TIME)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build())
|
.build())
|
||||||
.createVKey())
|
.createVKey())
|
||||||
.setServerApproveAutorenewPollMessage(
|
.setServerApproveAutorenewPollMessage(
|
||||||
|
|
|
@ -349,7 +349,7 @@ public class DatabaseHelper {
|
||||||
Recurring recurring =
|
Recurring recurring =
|
||||||
persistResource(
|
persistResource(
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.setRenewalPrice(renewalPrice)
|
.setRenewalPrice(renewalPrice)
|
||||||
.setRenewalPriceBehavior(renewalPriceBehavior)
|
.setRenewalPriceBehavior(renewalPriceBehavior)
|
||||||
.setRegistrarId(domain.getCreationRegistrarId())
|
.setRegistrarId(domain.getCreationRegistrarId())
|
||||||
|
@ -557,7 +557,7 @@ public class DatabaseHelper {
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setPeriodYears(1)
|
.setPeriodYears(1)
|
||||||
.setCost(getDomainRenewCost(domain.getDomainName(), costLookupTime, 1))
|
.setCost(getDomainRenewCost(domain.getDomainName(), costLookupTime, 1))
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ public class DatabaseHelper {
|
||||||
.setRegistrarId("TheRegistrar")
|
.setRegistrarId("TheRegistrar")
|
||||||
.setEventTime(expirationTime)
|
.setEventTime(expirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainCreate)
|
.setDomainHistory(historyEntryDomainCreate)
|
||||||
.build());
|
.build());
|
||||||
PollMessage.Autorenew autorenewPollMessage =
|
PollMessage.Autorenew autorenewPollMessage =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
@ -701,7 +701,7 @@ public class DatabaseHelper {
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setEventTime(extendedRegistrationExpirationTime)
|
.setEventTime(extendedRegistrationExpirationTime)
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(historyEntryDomainTransfer)
|
.setDomainHistory(historyEntryDomainTransfer)
|
||||||
.build());
|
.build());
|
||||||
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
PollMessage.Autorenew gainingClientAutorenewPollMessage =
|
||||||
persistResource(
|
persistResource(
|
||||||
|
|
|
@ -575,7 +575,7 @@ public final class DomainLockUtilsTest {
|
||||||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||||
.setEventTime(clock.nowUtc())
|
.setEventTime(clock.nowUtc())
|
||||||
.setBillingTime(clock.nowUtc())
|
.setBillingTime(clock.nowUtc())
|
||||||
.setParent(entry)
|
.setDomainHistory(entry)
|
||||||
.build())
|
.build())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
DatabaseHelper.assertBillingEvents(expectedEvents);
|
DatabaseHelper.assertBillingEvents(expectedEvents);
|
||||||
|
|
|
@ -150,7 +150,8 @@ class EppLifecycleToolsTest extends EppTestCase {
|
||||||
.setPeriodYears(4)
|
.setPeriodYears(4)
|
||||||
.setEventTime(DateTime.parse("2000-06-07T00:00:00Z"))
|
.setEventTime(DateTime.parse("2000-06-07T00:00:00Z"))
|
||||||
.setBillingTime(DateTime.parse("2000-06-12T00: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();
|
.build();
|
||||||
|
|
||||||
assertBillingEventsForResource(
|
assertBillingEventsForResource(
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
|
||||||
assertBillingEventsEqual(
|
assertBillingEventsEqual(
|
||||||
loadByKey(domain.getAutorenewBillingEvent()),
|
loadByKey(domain.getAutorenewBillingEvent()),
|
||||||
new BillingEvent.Recurring.Builder()
|
new BillingEvent.Recurring.Builder()
|
||||||
.setParent(synthetic)
|
.setDomainHistory(synthetic)
|
||||||
.setReason(Reason.RENEW)
|
.setReason(Reason.RENEW)
|
||||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||||
.setTargetId(domain.getDomainName())
|
.setTargetId(domain.getDomainName())
|
||||||
|
|
|
@ -345,7 +345,7 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomainCommand
|
||||||
.setRegistrarId("NewRegistrar")
|
.setRegistrarId("NewRegistrar")
|
||||||
.setEventTime(fakeClock.nowUtc().minusDays(5))
|
.setEventTime(fakeClock.nowUtc().minusDays(5))
|
||||||
.setRecurrenceEndTime(END_OF_TIME)
|
.setRecurrenceEndTime(END_OF_TIME)
|
||||||
.setParent(createHistoryEntry)
|
.setDomainHistory(createHistoryEntry)
|
||||||
.build());
|
.build());
|
||||||
persistResource(
|
persistResource(
|
||||||
domain
|
domain
|
||||||
|
|
|
@ -320,7 +320,7 @@ final class RegistryLockVerifyActionTest {
|
||||||
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
.setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost())
|
||||||
.setEventTime(fakeClock.nowUtc())
|
.setEventTime(fakeClock.nowUtc())
|
||||||
.setBillingTime(fakeClock.nowUtc())
|
.setBillingTime(fakeClock.nowUtc())
|
||||||
.setParent(historyEntry)
|
.setDomainHistory(historyEntry)
|
||||||
.build());
|
.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 {
|
class google.registry.model.common.EntityGroupRoot {
|
||||||
@Id java.lang.String id;
|
@Id java.lang.String id;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +5,6 @@ class google.registry.model.common.GaeUserIdConverter {
|
||||||
@Id long id;
|
@Id long id;
|
||||||
com.google.appengine.api.users.User user;
|
com.google.appengine.api.users.User user;
|
||||||
}
|
}
|
||||||
class google.registry.model.common.TimeOfYear {
|
|
||||||
java.lang.String timeString;
|
|
||||||
}
|
|
||||||
class google.registry.model.contact.ContactAddress {
|
class google.registry.model.contact.ContactAddress {
|
||||||
java.lang.String city;
|
java.lang.String city;
|
||||||
java.lang.String countryCode;
|
java.lang.String countryCode;
|
||||||
|
@ -183,7 +105,6 @@ class google.registry.model.domain.DomainBase {
|
||||||
google.registry.model.domain.DomainAuthInfo authInfo;
|
google.registry.model.domain.DomainAuthInfo authInfo;
|
||||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||||
google.registry.model.transfer.DomainTransferData transferData;
|
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> adminContact;
|
||||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
||||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> registrantContact;
|
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.DomainAuthInfo authInfo;
|
||||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||||
google.registry.model.transfer.DomainTransferData transferData;
|
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> adminContact;
|
||||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> billingContact;
|
||||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> registrantContact;
|
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 {
|
class google.registry.model.domain.GracePeriod {
|
||||||
google.registry.model.domain.rgp.GracePeriodStatus type;
|
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;
|
java.lang.String clientId;
|
||||||
long gracePeriodId;
|
long gracePeriodId;
|
||||||
org.joda.time.DateTime expirationTime;
|
org.joda.time.DateTime expirationTime;
|
||||||
}
|
}
|
||||||
class google.registry.model.domain.GracePeriod$GracePeriodHistory {
|
class google.registry.model.domain.GracePeriod$GracePeriodHistory {
|
||||||
google.registry.model.domain.rgp.GracePeriodStatus type;
|
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 domainHistoryRevisionId;
|
||||||
java.lang.Long gracePeriodHistoryRevisionId;
|
java.lang.Long gracePeriodHistoryRevisionId;
|
||||||
java.lang.String clientId;
|
java.lang.String clientId;
|
||||||
|
@ -319,7 +235,6 @@ class google.registry.model.domain.token.AllocationToken {
|
||||||
@Id java.lang.String token;
|
@Id java.lang.String token;
|
||||||
boolean discountPremiums;
|
boolean discountPremiums;
|
||||||
double discountFraction;
|
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.common.TimedTransitionProperty<google.registry.model.domain.token.AllocationToken$TokenStatus> tokenStatusTransitions;
|
||||||
google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior;
|
google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior;
|
||||||
google.registry.model.domain.token.AllocationToken$TokenType tokenType;
|
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.domain.Period transferPeriod;
|
||||||
google.registry.model.eppcommon.Trid transferRequestTrid;
|
google.registry.model.eppcommon.Trid transferRequestTrid;
|
||||||
google.registry.model.transfer.TransferStatus transferStatus;
|
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;
|
google.registry.persistence.VKey<google.registry.model.poll.PollMessage$Autorenew> serverApproveAutorenewPollMessage;
|
||||||
java.lang.String gainingClientId;
|
java.lang.String gainingClientId;
|
||||||
java.lang.String losingClientId;
|
java.lang.String losingClientId;
|
||||||
|
@ -643,16 +556,6 @@ enum google.registry.model.transfer.TransferStatus {
|
||||||
SERVER_APPROVED;
|
SERVER_APPROVED;
|
||||||
SERVER_CANCELLED;
|
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 {
|
class google.registry.persistence.DomainHistoryVKey {
|
||||||
java.lang.Long historyRevisionId;
|
java.lang.Long historyRevisionId;
|
||||||
java.lang.String repoId;
|
java.lang.String repoId;
|
||||||
|
|
|
@ -42,11 +42,7 @@
|
||||||
domain_name text not null,
|
domain_name text not null,
|
||||||
billing_time timestamptz,
|
billing_time timestamptz,
|
||||||
billing_event_id int8,
|
billing_event_id int8,
|
||||||
billing_event_history_id int8,
|
|
||||||
billing_event_domain_repo_id text,
|
|
||||||
billing_recurrence_id int8,
|
billing_recurrence_id int8,
|
||||||
billing_recurrence_history_id int8,
|
|
||||||
billing_recurrence_domain_repo_id text,
|
|
||||||
primary key (billing_cancellation_id)
|
primary key (billing_cancellation_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import javax.lang.model.SourceVersion;
|
||||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
public class LongVKeyProcessor extends AbstractVKeyProcessor {
|
public class LongVKeyProcessor extends AbstractVKeyProcessor {
|
||||||
|
|
||||||
private static final String ANNOTATION_SIMPLE_NAME = "WithStringVKey";
|
private static final String ANNOTATION_SIMPLE_NAME = "WithLongVKey";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Class<?> getSqlColumnType() {
|
Class<?> getSqlColumnType() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue