From d5be4dcc3b6951c575b8da714835c058a8ea64c3 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Tue, 2 Aug 2022 11:36:28 -0400 Subject: [PATCH] Remove ofy support from BillingEvent (#1710) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. This change is [Reviewable](https://reviewable.io/reviews/google/nomulus/1710) --- .../ExpandRecurringBillingEventsAction.java | 8 +- .../registry/beam/invoicing/BillingEvent.java | 93 +---- .../beam/invoicing/InvoicingPipeline.java | 34 +- .../flows/domain/DomainCreateFlow.java | 27 +- .../flows/domain/DomainDeleteFlow.java | 7 +- .../flows/domain/DomainRenewFlow.java | 7 +- .../domain/DomainRestoreRequestFlow.java | 22 +- .../domain/DomainTransferApproveFlow.java | 16 +- .../flows/domain/DomainTransferUtils.java | 12 +- .../flows/domain/DomainUpdateFlow.java | 2 +- .../java/google/registry/model/Buildable.java | 6 +- .../google/registry/model/EntityClasses.java | 5 - .../model/annotations/OfyIdAllocation.java | 36 ++ .../registry/model/billing/BillingEvent.java | 359 +++++------------- .../model/common/ClassPathManager.java | 8 +- .../registry/model/domain/DomainContent.java | 1 + .../model/domain/GracePeriodBase.java | 2 + .../model/domain/token/AllocationToken.java | 1 + .../model/transfer/DomainTransferData.java | 4 +- .../EppHistoryVKeyTranslatorFactory.java | 5 +- .../registry/persistence/BillingVKey.java | 125 ------ .../persistence/converter/VKeyConverter.java | 7 +- .../registry/tools/DomainLockUtils.java | 2 +- .../registry/tools/UnrenewDomainCommand.java | 2 +- .../main/resources/META-INF/persistence.xml | 1 - .../beam/invoicing/sql/billing_events.sql | 101 ----- .../sql/cloud_sql_billing_events.sql | 4 +- .../batch/DeleteExpiredDomainsActionTest.java | 2 +- .../batch/DeleteProberDataActionTest.java | 2 +- ...xpandRecurringBillingEventsActionTest.java | 106 +++--- .../beam/invoicing/BillingEventTest.java | 132 ++----- .../beam/invoicing/InvoicingPipelineTest.java | 53 +-- .../flows/EppLifecycleDomainTest.java | 3 +- .../google/registry/flows/EppTestCase.java | 24 +- .../flows/domain/DomainCheckFlowTest.java | 2 +- .../flows/domain/DomainCreateFlowTest.java | 6 +- .../flows/domain/DomainDeleteFlowTest.java | 6 +- .../flows/domain/DomainInfoFlowTest.java | 2 +- .../flows/domain/DomainPricingLogicTest.java | 2 +- .../flows/domain/DomainRenewFlowTest.java | 8 +- .../domain/DomainRestoreRequestFlowTest.java | 10 +- .../domain/DomainTransferApproveFlowTest.java | 10 +- .../domain/DomainTransferFlowTestCase.java | 4 +- .../domain/DomainTransferRequestFlowTest.java | 4 +- .../flows/domain/DomainUpdateFlowTest.java | 2 +- .../model/billing/BillingEventTest.java | 80 ++-- .../model/common/ClassPathManagerTest.java | 22 +- .../model/domain/DomainBaseSqlTest.java | 18 +- .../registry/model/domain/DomainBaseTest.java | 14 +- .../model/domain/GracePeriodTest.java | 15 +- .../reporting/Spec11ThreatMatchTest.java | 6 +- .../model/transfer/TransferDataTest.java | 21 +- .../VKeyTranslatorFactoryTest.java | 13 +- .../registry/persistence/BillingVKeyTest.java | 112 ------ .../rde/DomainBaseToXjcConverterTest.java | 8 +- .../java/google/registry/rde/RdeFixtures.java | 8 +- .../registry/testing/DatabaseHelper.java | 8 +- .../registry/tools/DomainLockUtilsTest.java | 2 +- .../registry/tools/EppLifecycleToolsTest.java | 3 +- .../tools/UnrenewDomainCommandTest.java | 2 +- .../tools/UpdateDomainCommandTest.java | 2 +- .../RegistryLockVerifyActionTest.java | 2 +- .../google/registry/model/schema.txt | 97 ----- .../sql/schema/db-schema.sql.generated | 4 - .../processors/LongVKeyProcessor.java | 2 +- 65 files changed, 472 insertions(+), 1242 deletions(-) create mode 100644 core/src/main/java/google/registry/model/annotations/OfyIdAllocation.java delete mode 100644 core/src/main/java/google/registry/persistence/BillingVKey.java delete mode 100644 core/src/main/resources/google/registry/beam/invoicing/sql/billing_events.sql delete mode 100644 core/src/test/java/google/registry/persistence/BillingVKeyTest.java diff --git a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java index 46a59dd9c..295692a2b 100644 --- a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java +++ b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java @@ -253,9 +253,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable { final ImmutableSet billingTimes = getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld); - VKey domainKey = - VKey.create( - DomainBase.class, recurring.getDomainRepoId(), recurring.getParentKey().getParent()); + VKey domainKey = VKey.createSql(DomainBase.class, recurring.getDomainRepoId()); Iterable oneTimesForDomain; oneTimesForDomain = tm().createQueryComposer(OneTime.class) @@ -311,11 +309,11 @@ public class ExpandRecurringBillingEventsAction implements Runnable { .getRenewCost()) .setEventTime(eventTime) .setFlags(union(recurring.getFlags(), Flag.SYNTHETIC)) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setPeriodYears(1) .setReason(recurring.getReason()) .setSyntheticCreationTime(executeTime) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setCancellationMatchingBillingEvent(recurring) .setTargetId(recurring.getTargetId()) .build()); } diff --git a/core/src/main/java/google/registry/beam/invoicing/BillingEvent.java b/core/src/main/java/google/registry/beam/invoicing/BillingEvent.java index fb413b9c7..8d99e67b8 100644 --- a/core/src/main/java/google/registry/beam/invoicing/BillingEvent.java +++ b/core/src/main/java/google/registry/beam/invoicing/BillingEvent.java @@ -14,47 +14,38 @@ package google.registry.beam.invoicing; -import static google.registry.beam.BeamUtils.checkFieldsNotNull; -import static google.registry.beam.BeamUtils.extractField; - import com.google.auto.value.AutoValue; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; -import google.registry.model.billing.BillingEvent.Flag; import google.registry.reporting.billing.BillingModule; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; -import java.text.DecimalFormat; -import java.util.stream.Collectors; -import org.apache.avro.generic.GenericRecord; +import java.util.regex.Pattern; import org.apache.beam.sdk.coders.AtomicCoder; import org.apache.beam.sdk.coders.Coder; import org.apache.beam.sdk.coders.StringUtf8Coder; -import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord; import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}. * - *

This is a trivially serializable class that allows Beam to transform the results of a Bigquery - * query into a standard Java representation, giving us the type guarantees and ease of manipulation - * Bigquery lacks, while localizing any Bigquery-side failures to the {@link #parseFromRecord} - * function. + *

This is a trivially serializable class that allows Beam to transform the results of a Cloud + * SQL query into a standard Java representation, giving us the type guarantees and ease of + * manipulation Cloud SQL lacks. */ @AutoValue public abstract class BillingEvent implements Serializable { + private static final long serialVersionUID = -3593088371541450077L; + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz"); - /** The amount we multiply the price for sunrise creates. This is currently a 15% discount. */ - private static final double SUNRISE_DISCOUNT_PRICE_MODIFIER = 0.85; + private static final Pattern SYNTHETIC_REGEX = Pattern.compile("SYNTHETIC", Pattern.LITERAL); private static final ImmutableList FIELD_NAMES = ImmutableList.of( @@ -115,67 +106,7 @@ public abstract class BillingEvent implements Serializable { /** Returns a list of space-delimited flags associated with the event. */ abstract String flags(); - /** - * Constructs a {@code BillingEvent} from a {@code SchemaAndRecord}. - * - * @see - * Apache AVRO GenericRecord - */ - 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}. - * - *

This should only be used outside this class for testing- instances of {@code BillingEvent} - * should otherwise come from {@link #parseFromRecord}. - */ - @VisibleForTesting + /** Creates a concrete {@link BillingEvent}. */ static BillingEvent create( long id, DateTime billingTime, @@ -209,7 +140,7 @@ public abstract class BillingEvent implements Serializable { } static String getHeader() { - return FIELD_NAMES.stream().collect(Collectors.joining(",")); + return String.join(",", FIELD_NAMES); } /** @@ -242,7 +173,7 @@ public abstract class BillingEvent implements Serializable { currency(), String.format("%.2f", amount()), // Strip out the 'synthetic' flag, which is internal only. - flags().replace("SYNTHETIC", "").trim())); + SYNTHETIC_REGEX.matcher(flags()).replaceAll("").trim())); } /** Returns the grouping key for this {@code BillingEvent}, to generate the overall invoice. */ @@ -274,6 +205,8 @@ public abstract class BillingEvent implements Serializable { @AutoValue abstract static class InvoiceGroupingKey implements Serializable { + private static final long serialVersionUID = -151561764235256205L; + private static final ImmutableList INVOICE_HEADERS = ImmutableList.of( "StartDate", @@ -345,6 +278,8 @@ public abstract class BillingEvent implements Serializable { /** Coder that provides deterministic (de)serialization for {@code InvoiceGroupingKey}. */ static class InvoiceGroupingKeyCoder extends AtomicCoder { + private static final long serialVersionUID = 6680701524304107547L; + @Override public void encode(InvoiceGroupingKey value, OutputStream outStream) throws IOException { Coder stringCoder = StringUtf8Coder.of(); diff --git a/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java b/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java index 134a5d735..0cc90b8c4 100644 --- a/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java +++ b/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java @@ -24,16 +24,14 @@ import google.registry.beam.common.RegistryJpaIO.Read; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder; import google.registry.model.billing.BillingEvent.Flag; +import google.registry.model.billing.BillingEvent.OneTime; import google.registry.model.registrar.Registrar; import google.registry.persistence.PersistenceModule.TransactionIsolationLevel; import google.registry.reporting.billing.BillingModule; import google.registry.util.DomainNameUtils; import google.registry.util.SqlTemplate; import java.io.Serializable; -import java.time.LocalDateTime; -import java.time.LocalTime; import java.time.YearMonth; -import java.time.format.DateTimeFormatter; import java.util.Objects; import java.util.Optional; import java.util.regex.Pattern; @@ -66,8 +64,7 @@ import org.joda.money.CurrencyUnit; */ public class InvoicingPipeline implements Serializable { - private static final DateTimeFormatter TIMESTAMP_FORMATTER = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"); + private static final long serialVersionUID = 5386330443625580081L; private static final Pattern SQL_COMMENT_REGEX = Pattern.compile("^\\s*--.*\\n", Pattern.MULTILINE); @@ -107,8 +104,7 @@ public class InvoicingPipeline implements Serializable { } private static Optional parseRow(Object[] row) { - google.registry.model.billing.BillingEvent.OneTime oneTime = - (google.registry.model.billing.BillingEvent.OneTime) row[0]; + OneTime oneTime = (OneTime) row[0]; Registrar registrar = (Registrar) row[1]; CurrencyUnit currency = oneTime.getCost().getCurrencyUnit(); if (!registrar.getBillingAccountMap().containsKey(currency)) { @@ -140,6 +136,9 @@ public class InvoicingPipeline implements Serializable { /** Transform that converts a {@code BillingEvent} into an invoice CSV row. */ private static class GenerateInvoiceRows extends PTransform, PCollection> { + + private static final long serialVersionUID = -8090619008258393728L; + @Override public PCollection expand(PCollection input) { return input @@ -203,32 +202,13 @@ public class InvoicingPipeline implements Serializable { TextIO.sink().withHeader(BillingEvent.getHeader()))); } - /** Create the Bigquery query for a given project and yearMonth at runtime. */ - static String makeQuery(String yearMonth, String projectId) { - // Get the timestamp endpoints capturing the entire month with microsecond precision - YearMonth reportingMonth = YearMonth.parse(yearMonth); - LocalDateTime firstMoment = reportingMonth.atDay(1).atTime(LocalTime.MIDNIGHT); - LocalDateTime lastMoment = reportingMonth.atEndOfMonth().atTime(LocalTime.MAX); - // Construct the month's query by filling in the billing_events.sql template - return SqlTemplate.create(getQueryFromFile(InvoicingPipeline.class, "billing_events.sql")) - .put("FIRST_TIMESTAMP_OF_MONTH", firstMoment.format(TIMESTAMP_FORMATTER)) - .put("LAST_TIMESTAMP_OF_MONTH", lastMoment.format(TIMESTAMP_FORMATTER)) - .put("PROJECT_ID", projectId) - .put("DATASTORE_EXPORT_DATA_SET", "latest_datastore_export") - .put("ONETIME_TABLE", "OneTime") - .put("REGISTRY_TABLE", "Registry") - .put("REGISTRAR_TABLE", "Registrar") - .put("CANCELLATION_TABLE", "Cancellation") - .build(); - } - /** Create the Cloud SQL query for a given yearMonth at runtime. */ static String makeCloudSqlQuery(String yearMonth) { YearMonth endMonth = YearMonth.parse(yearMonth).plusMonths(1); String queryWithComments = SqlTemplate.create( getQueryFromFile(InvoicingPipeline.class, "cloud_sql_billing_events.sql")) - .put("FIRST_TIMESTAMP_OF_MONTH", yearMonth.concat("-01")) + .put("FIRST_TIMESTAMP_OF_MONTH", yearMonth + "-01") .put( "LAST_TIMESTAMP_OF_MONTH", String.format("%d-%d-01", endMonth.getYear(), endMonth.getMonthValue())) diff --git a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java index bcf392593..76abf1a54 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainCreateFlow.java @@ -333,9 +333,9 @@ public final class DomainCreateFlow implements TransactionalFlow { validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class)); DateTime registrationExpirationTime = leapSafeAddYears(now, years); String repoId = createDomainRepoId(allocateId(), registry.getTldStr()); - Key domainHistoryKey = - Key.create(Key.create(DomainBase.class, repoId), DomainHistory.class, allocateId()); - historyBuilder.setId(domainHistoryKey.getId()); + long historyRevisionId = allocateId(); + DomainHistoryId domainHistoryId = new DomainHistoryId(repoId, historyRevisionId); + historyBuilder.setId(historyRevisionId); // Bill for the create. BillingEvent.OneTime createBillingEvent = createOneTimeBillingEvent( @@ -345,17 +345,17 @@ public final class DomainCreateFlow implements TransactionalFlow { isReserved(domainName, isSunriseCreate), years, feesAndCredits, - domainHistoryKey, + domainHistoryId, allocationToken, now); // Create a new autorenew billing event and poll message starting at the expiration time. BillingEvent.Recurring autorenewBillingEvent = createAutorenewBillingEvent( - domainHistoryKey, + domainHistoryId, registrationExpirationTime, getRenewalPriceInfo(isAnchorTenant, allocationToken, feesAndCredits)); PollMessage.Autorenew autorenewPollMessage = - createAutorenewPollMessage(domainHistoryKey, registrationExpirationTime); + createAutorenewPollMessage(domainHistoryId, registrationExpirationTime); ImmutableSet.Builder entitiesToSave = new ImmutableSet.Builder<>(); entitiesToSave.add(createBillingEvent, autorenewBillingEvent, autorenewPollMessage); // Bill for EAP cost, if any. @@ -552,7 +552,7 @@ public final class DomainCreateFlow implements TransactionalFlow { boolean isReserved, int years, FeesAndCredits feesAndCredits, - Key domainHistoryKey, + DomainHistoryId domainHistoryId, Optional allocationToken, DateTime now) { ImmutableSet.Builder flagsBuilder = new ImmutableSet.Builder<>(); @@ -581,12 +581,12 @@ public final class DomainCreateFlow implements TransactionalFlow { ? registry.getAnchorTenantAddGracePeriodLength() : registry.getAddGracePeriodLength())) .setFlags(flagsBuilder.build()) - .setParent(domainHistoryKey) + .setDomainHistoryId(domainHistoryId) .build(); } private Recurring createAutorenewBillingEvent( - Key domainHistoryKey, + DomainHistoryId domainHistoryId, DateTime registrationExpirationTime, RenewalPriceInfo renewalpriceInfo) { return new BillingEvent.Recurring.Builder() @@ -596,21 +596,20 @@ public final class DomainCreateFlow implements TransactionalFlow { .setRegistrarId(registrarId) .setEventTime(registrationExpirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistoryKey) + .setDomainHistoryId(domainHistoryId) .setRenewalPriceBehavior(renewalpriceInfo.renewalPriceBehavior()) .setRenewalPrice(renewalpriceInfo.renewalPrice()) .build(); } private Autorenew createAutorenewPollMessage( - Key domainHistoryKey, DateTime registrationExpirationTime) { + DomainHistoryId domainHistoryId, DateTime registrationExpirationTime) { return new PollMessage.Autorenew.Builder() .setTargetId(targetId) .setRegistrarId(registrarId) .setEventTime(registrationExpirationTime) .setMsg("Domain was auto-renewed.") - .setDomainHistoryId( - new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) + .setDomainHistoryId(domainHistoryId) .build(); } @@ -625,7 +624,7 @@ public final class DomainCreateFlow implements TransactionalFlow { .setEventTime(createBillingEvent.getEventTime()) .setBillingTime(createBillingEvent.getBillingTime()) .setFlags(createBillingEvent.getFlags()) - .setParent(createBillingEvent.getParentKey()) + .setDomainHistoryId(createBillingEvent.getDomainHistoryId()) .build(); } diff --git a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java index 4b766e1af..4e705e807 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -233,7 +233,12 @@ public final class DomainDeleteFlow implements TransactionalFlow { // No cancellation is written if the grace period was not for a billable event. if (gracePeriod.hasBillingEvent()) { entitiesToSave.add( - BillingEvent.Cancellation.forGracePeriod(gracePeriod, now, domainHistoryKey, targetId)); + BillingEvent.Cancellation.forGracePeriod( + gracePeriod, + now, + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId()), + targetId)); if (gracePeriod.getOneTimeBillingEvent() != null) { // Take the amount of amount of registration time being refunded off the expiration time. // This can be either add grace periods or renew grace periods. diff --git a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java index 4656c434c..08a2ad423 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRenewFlow.java @@ -210,7 +210,9 @@ public final class DomainRenewFlow implements TransactionalFlow { .setEventTime(newExpirationTime) .setRenewalPrice(existingRecurringBillingEvent.getRenewalPrice().orElse(null)) .setRenewalPriceBehavior(existingRecurringBillingEvent.getRenewalPriceBehavior()) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build(); PollMessage.Autorenew newAutorenewPollMessage = newAutorenewPollMessage(existingDomain) @@ -332,7 +334,8 @@ public final class DomainRenewFlow implements TransactionalFlow { .setEventTime(now) .setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null)) .setBillingTime(now.plus(Registry.get(tld).getRenewGracePeriodLength())) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build(); } diff --git a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java index a09547066..84de79e9d 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java @@ -150,6 +150,8 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { verifyRestoreAllowed(command, existingDomain, feeUpdate, feesAndCredits, now); Key domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class); historyBuilder.setId(domainHistoryKey.getId()); + DomainHistoryId domainHistoryId = + new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()); ImmutableSet.Builder entitiesToSave = new ImmutableSet.Builder<>(); DateTime newExpirationTime = @@ -158,17 +160,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { // a year and bill for it immediately, with no grace period. if (isExpired) { entitiesToSave.add( - createRenewBillingEvent(domainHistoryKey, feesAndCredits.getRenewCost(), now)); + createRenewBillingEvent(domainHistoryId, feesAndCredits.getRenewCost(), now)); } // Always bill for the restore itself. entitiesToSave.add( - createRestoreBillingEvent(domainHistoryKey, feesAndCredits.getRestoreCost(), now)); + createRestoreBillingEvent(domainHistoryId, feesAndCredits.getRestoreCost(), now)); BillingEvent.Recurring autorenewEvent = newAutorenewBillingEvent(existingDomain) .setEventTime(newExpirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistoryKey) + .setDomainHistoryId(domainHistoryId) .build(); PollMessage.Autorenew autorenewPollMessage = newAutorenewPollMessage(existingDomain) @@ -259,19 +261,17 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { } private OneTime createRenewBillingEvent( - Key domainHistoryKey, Money renewCost, DateTime now) { - return prepareBillingEvent(domainHistoryKey, renewCost, now).setReason(Reason.RENEW).build(); + DomainHistoryId domainHistoryId, Money renewCost, DateTime now) { + return prepareBillingEvent(domainHistoryId, renewCost, now).setReason(Reason.RENEW).build(); } private BillingEvent.OneTime createRestoreBillingEvent( - Key domainHistoryKey, Money restoreCost, DateTime now) { - return prepareBillingEvent(domainHistoryKey, restoreCost, now) - .setReason(Reason.RESTORE) - .build(); + DomainHistoryId domainHistoryId, Money restoreCost, DateTime now) { + return prepareBillingEvent(domainHistoryId, restoreCost, now).setReason(Reason.RESTORE).build(); } private OneTime.Builder prepareBillingEvent( - Key domainHistoryKey, Money cost, DateTime now) { + DomainHistoryId domainHistoryId, Money cost, DateTime now) { return new BillingEvent.OneTime.Builder() .setTargetId(targetId) .setRegistrarId(registrarId) @@ -279,7 +279,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { .setBillingTime(now) .setPeriodYears(1) .setCost(cost) - .setParent(domainHistoryKey); + .setDomainHistoryId(domainHistoryId); } private static ImmutableList createResponseExtensions( diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java index c89495f0b..2665ac9b1 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferApproveFlow.java @@ -123,7 +123,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { Key domainHistoryKey = createHistoryKey(existingDomain, DomainHistory.class); historyBuilder.setId(domainHistoryKey.getId()); Optional billingEvent = - (transferData.getTransferPeriod().getValue() == 0) + transferData.getTransferPeriod().getValue() == 0 ? Optional.empty() : Optional.of( new BillingEvent.OneTime.Builder() @@ -134,7 +134,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { .setCost(getDomainRenewCost(targetId, transferData.getTransferRequestTime(), 1)) .setEventTime(now) .setBillingTime(now.plus(Registry.get(tld).getTransferGracePeriodLength())) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build()); ImmutableList.Builder entitiesToSave = new ImmutableList.Builder<>(); // If we are within an autorenew grace period, cancel the autorenew billing event and don't @@ -150,7 +152,11 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { if (billingEvent.isPresent()) { entitiesToSave.add( BillingEvent.Cancellation.forGracePeriod( - autorenewGrace, now, domainHistoryKey, targetId)); + autorenewGrace, + now, + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId()), + targetId)); } } // Close the old autorenew event and poll message at the transfer time (aka now). This may end @@ -167,7 +173,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { .setRegistrarId(gainingRegistrarId) .setEventTime(newExpirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build(); // Create a new autorenew poll message. PollMessage.Autorenew gainingClientAutorenewPollMessage = diff --git a/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java b/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java index 514fc6442..a6ada5726 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java +++ b/core/src/main/java/google/registry/flows/domain/DomainTransferUtils.java @@ -250,7 +250,8 @@ public final class DomainTransferUtils { .setRegistrarId(gainingRegistrarId) .setEventTime(serverApproveNewExpirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build(); } @@ -285,7 +286,11 @@ public final class DomainTransferUtils { if (autorenewGracePeriod != null && transferCost.isPresent()) { return Optional.of( BillingEvent.Cancellation.forGracePeriod( - autorenewGracePeriod, now, domainHistoryKey, targetId) + autorenewGracePeriod, + now, + new DomainHistoryId( + domainHistoryKey.getParent().getName(), domainHistoryKey.getId()), + targetId) .asBuilder() .setEventTime(automaticTransferTime) .build()); @@ -308,7 +313,8 @@ public final class DomainTransferUtils { .setPeriodYears(1) .setEventTime(automaticTransferTime) .setBillingTime(automaticTransferTime.plus(registry.getTransferGracePeriodLength())) - .setParent(domainHistoryKey) + .setDomainHistoryId( + new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId())) .build(); } diff --git a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java index a01b4908d..fc3f8fa4c 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainUpdateFlow.java @@ -320,7 +320,7 @@ public final class DomainUpdateFlow implements TransactionalFlow { .setCost(Registry.get(existingDomain.getTld()).getServerStatusChangeCost()) .setEventTime(now) .setBillingTime(now) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build()); } } diff --git a/core/src/main/java/google/registry/model/Buildable.java b/core/src/main/java/google/registry/model/Buildable.java index aaa74efbc..104e3370d 100644 --- a/core/src/main/java/google/registry/model/Buildable.java +++ b/core/src/main/java/google/registry/model/Buildable.java @@ -20,6 +20,7 @@ import static google.registry.model.IdService.allocateId; import static google.registry.model.ModelUtils.getAllFields; import com.googlecode.objectify.annotation.Id; +import google.registry.model.annotations.OfyIdAllocation; import google.registry.util.TypeUtils.TypeInstantiator; import java.lang.reflect.Field; import java.util.Optional; @@ -59,7 +60,10 @@ public interface Buildable { // any entity it has one and only one @Id field in its class hierarchy. Field idField = getAllFields(instance.getClass()).values().stream() - .filter(field -> field.isAnnotationPresent(Id.class)) + .filter( + field -> + field.isAnnotationPresent(Id.class) + || field.isAnnotationPresent(OfyIdAllocation.class)) .findFirst() .orElse(null); if (idField != null diff --git a/core/src/main/java/google/registry/model/EntityClasses.java b/core/src/main/java/google/registry/model/EntityClasses.java index fd504b5cb..0712f6a33 100644 --- a/core/src/main/java/google/registry/model/EntityClasses.java +++ b/core/src/main/java/google/registry/model/EntityClasses.java @@ -16,7 +16,6 @@ package google.registry.model; import com.google.common.collect.ImmutableSet; import google.registry.model.annotations.DeleteAfterMigration; -import google.registry.model.billing.BillingEvent; import google.registry.model.common.EntityGroupRoot; import google.registry.model.common.GaeUserIdConverter; import google.registry.model.contact.ContactHistory; @@ -44,10 +43,6 @@ public final class EntityClasses { public static final ImmutableSet> ALL_CLASSES = ImmutableSet.of( AllocationToken.class, - BillingEvent.Cancellation.class, - BillingEvent.Modification.class, - BillingEvent.OneTime.class, - BillingEvent.Recurring.class, ContactHistory.class, ContactResource.class, DomainBase.class, diff --git a/core/src/main/java/google/registry/model/annotations/OfyIdAllocation.java b/core/src/main/java/google/registry/model/annotations/OfyIdAllocation.java new file mode 100644 index 000000000..38064c9d9 --- /dev/null +++ b/core/src/main/java/google/registry/model/annotations/OfyIdAllocation.java @@ -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. + * + *

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()}. + * + *

It should be removed after we switch to using SQL to directly allocate IDs. + */ +@DeleteAfterMigration +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface OfyIdAllocation {} diff --git a/core/src/main/java/google/registry/model/billing/BillingEvent.java b/core/src/main/java/google/registry/model/billing/BillingEvent.java index a597b54c1..907ad6368 100644 --- a/core/src/main/java/google/registry/model/billing/BillingEvent.java +++ b/core/src/main/java/google/registry/model/billing/BillingEvent.java @@ -18,7 +18,6 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.util.CollectionUtils.forceEmptyToNull; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; @@ -26,31 +25,21 @@ import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Entity; -import com.googlecode.objectify.annotation.Id; -import com.googlecode.objectify.annotation.Ignore; -import com.googlecode.objectify.annotation.IgnoreSave; -import com.googlecode.objectify.annotation.Index; -import com.googlecode.objectify.annotation.Parent; -import com.googlecode.objectify.condition.IfNull; import google.registry.model.Buildable; import google.registry.model.ImmutableObject; import google.registry.model.UnsafeSerializable; +import google.registry.model.annotations.OfyIdAllocation; import google.registry.model.annotations.ReportedOn; import google.registry.model.common.TimeOfYear; -import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory; +import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.domain.GracePeriod; import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.model.domain.token.AllocationToken; import google.registry.model.transfer.TransferData.TransferServerApproveEntity; -import google.registry.persistence.BillingVKey.BillingEventVKey; -import google.registry.persistence.BillingVKey.BillingRecurrenceVKey; import google.registry.persistence.VKey; import google.registry.persistence.WithLongVKey; import google.registry.persistence.converter.JodaMoneyType; -import java.util.Objects; import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; @@ -58,11 +47,13 @@ import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; +import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Index; import javax.persistence.MappedSuperclass; -import javax.persistence.PostLoad; -import javax.persistence.Transient; +import javax.persistence.Table; import org.hibernate.annotations.Columns; import org.hibernate.annotations.Type; import org.joda.money.Money; @@ -76,7 +67,7 @@ public abstract class BillingEvent extends ImmutableObject /** The reason for the bill, which maps 1:1 to skus in go/registry-billing-skus. */ public enum Reason { CREATE(true), - @Deprecated // TODO(b/31676071): remove this legacy value once old data is cleaned up. + @Deprecated // DO NOT USE THIS REASON. IT REMAINS BECAUSE OF HISTORICAL DATA. SEE b/31676071. ERROR(false), FEE_EARLY_ACCESS(true), RENEW(true), @@ -105,9 +96,7 @@ public abstract class BillingEvent extends ImmutableObject ALLOCATION, ANCHOR_TENANT, AUTO_RENEW, - /** - * Landrush billing events are historical only and are no longer created. - */ + /** Landrush billing events are historical only and are no longer created. */ LANDRUSH, /** * This flag is used on create {@link OneTime} billing events for domains that were reserved. @@ -122,7 +111,7 @@ public abstract class BillingEvent extends ImmutableObject * This flag will be added to any {@link OneTime} events that are created via, e.g., an * automated process to expand {@link Recurring} events. */ - SYNTHETIC; + SYNTHETIC } /** @@ -149,37 +138,30 @@ public abstract class BillingEvent extends ImmutableObject */ NONPREMIUM, /** - * This indicates that the renewalPrice in {@link BillingEvent.Recurring} will be used for - * domain renewal. + * This indicates that the renewalPrice in {@link Recurring} will be used for domain renewal. * *

The renewalPrice has a non-null value iff the price behavior is set to "SPECIFIED". This * behavior is used with internal registrations. */ - SPECIFIED; + SPECIFIED } /** Entity id. */ - @Id @javax.persistence.Id Long id; - - @Parent @DoNotHydrate @Transient Key parent; + @OfyIdAllocation @Id Long id; /** The registrar to bill. */ - @Index @Column(name = "registrarId", nullable = false) String clientId; /** Revision id of the entry in DomainHistory table that ths bill belongs to. */ - @Ignore @Column(nullable = false) Long domainHistoryRevisionId; /** ID of the EPP resource that the bill is for. */ - @Ignore @Column(nullable = false) String domainRepoId; /** When this event was created. For recurring events, this is also the recurrence start time. */ - @Index @Column(nullable = false) DateTime eventTime; @@ -192,17 +174,7 @@ public abstract class BillingEvent extends ImmutableObject @Column(name = "domain_name", nullable = false) String targetId; - @Nullable - Set flags; - - @PostLoad - void postLoad() { - parent = - Key.create( - Key.create(DomainBase.class, domainRepoId), - DomainHistory.class, - domainHistoryRevisionId); - } + @Nullable Set flags; public String getRegistrarId() { return clientId; @@ -232,8 +204,8 @@ public abstract class BillingEvent extends ImmutableObject return targetId; } - public Key getParentKey() { - return parent; + public DomainHistoryId getDomainHistoryId() { + return new DomainHistoryId(domainRepoId, domainHistoryRevisionId); } public ImmutableSet getFlags() { @@ -269,16 +241,6 @@ public abstract class BillingEvent extends ImmutableObject return thisCastToDerived(); } - public B setDomainHistoryRevisionId(long domainHistoryRevisionId) { - getInstance().domainHistoryRevisionId = domainHistoryRevisionId; - return thisCastToDerived(); - } - - public B setDomainRepoId(String domainRepoId) { - getInstance().domainRepoId = domainRepoId; - return thisCastToDerived(); - } - public B setEventTime(DateTime eventTime) { getInstance().eventTime = eventTime; return thisCastToDerived(); @@ -294,14 +256,14 @@ public abstract class BillingEvent extends ImmutableObject return thisCastToDerived(); } - public B setParent(DomainHistory parent) { - getInstance().parent = Key.create(parent); + public B setDomainHistoryId(DomainHistoryId domainHistoryId) { + getInstance().domainHistoryRevisionId = domainHistoryId.getId(); + getInstance().domainRepoId = domainHistoryId.getDomainRepoId(); return thisCastToDerived(); } - public B setParent(Key parentKey) { - getInstance().parent = parentKey; - return thisCastToDerived(); + public B setDomainHistory(DomainHistory domainHistory) { + return setDomainHistoryId(domainHistory.getDomainHistoryId()); } @Override @@ -311,29 +273,23 @@ public abstract class BillingEvent extends ImmutableObject checkNotNull(instance.clientId, "Registrar ID must be set"); checkNotNull(instance.eventTime, "Event time must be set"); checkNotNull(instance.targetId, "Target ID must be set"); - checkNotNull(instance.parent, "Parent must be set"); - checkNotNull(instance.parent.getParent(), "parent.getParent() must be set"); - checkNotNull( - instance.parent.getParent().getName(), "parent.getParent().getName() must be set"); - instance.domainHistoryRevisionId = instance.parent.getId(); - instance.domainRepoId = instance.parent.getParent().getName(); + checkNotNull(instance.domainHistoryRevisionId, "Domain History Revision ID must be set"); + checkNotNull(instance.domainRepoId, "Domain Repo ID must be set"); return super.build(); } } /** A one-time billable event. */ - @ReportedOn - @Entity - @javax.persistence.Entity(name = "BillingEvent") - @javax.persistence.Table( + @Entity(name = "BillingEvent") + @Table( indexes = { - @javax.persistence.Index(columnList = "registrarId"), - @javax.persistence.Index(columnList = "eventTime"), - @javax.persistence.Index(columnList = "billingTime"), - @javax.persistence.Index(columnList = "syntheticCreationTime"), - @javax.persistence.Index(columnList = "domainRepoId"), - @javax.persistence.Index(columnList = "allocationToken"), - @javax.persistence.Index(columnList = "cancellation_matching_billing_recurrence_id") + @Index(columnList = "registrarId"), + @Index(columnList = "eventTime"), + @Index(columnList = "billingTime"), + @Index(columnList = "syntheticCreationTime"), + @Index(columnList = "domainRepoId"), + @Index(columnList = "allocationToken"), + @Index(columnList = "cancellation_matching_billing_recurrence_id") }) @AttributeOverride(name = "id", column = @Column(name = "billing_event_id")) @WithLongVKey(compositeKey = true) @@ -345,15 +301,13 @@ public abstract class BillingEvent extends ImmutableObject Money cost; /** When the cost should be billed. */ - @Index DateTime billingTime; /** * The period in years of the action being billed for, if applicable, otherwise null. Used for * financial reporting. */ - @IgnoreSave(IfNull.class) - Integer periodYears = null; + Integer periodYears; /** * For {@link Flag#SYNTHETIC} events, when this event was persisted to Datastore (i.e. the @@ -361,11 +315,10 @@ public abstract class BillingEvent extends ImmutableObject * needs to be undone, a query on this field will return the complete set of potentially bad * events. */ - @Index DateTime syntheticCreationTime; /** - * For {@link Flag#SYNTHETIC} events, a {@link Key} to the {@link Recurring} from which this + * For {@link Flag#SYNTHETIC} events, a {@link VKey} to the {@link Recurring} from which this * {@link OneTime} was created. This is needed in order to properly match billing events against * {@link Cancellation}s. */ @@ -373,20 +326,17 @@ public abstract class BillingEvent extends ImmutableObject VKey cancellationMatchingBillingEvent; /** - * For {@link Flag#SYNTHETIC} events, the {@link DomainHistory} revision ID of the the {@link + * For {@link Flag#SYNTHETIC} events, the {@link DomainHistory} revision ID of the {@link * Recurring} from which this {@link OneTime} was created. This is needed in order to recreate * the {@link VKey} when reading from SQL. */ - @Ignore @Column(name = "recurrence_history_revision_id") Long recurringEventHistoryRevisionId; /** * The {@link AllocationToken} used in the creation of this event, or null if one was not used. */ - @Index - @Nullable - VKey allocationToken; + @Nullable VKey allocationToken; public Money getCost() { return cost; @@ -418,11 +368,11 @@ public abstract class BillingEvent extends ImmutableObject @Override public VKey createVKey() { - return VKey.create(OneTime.class, getId(), Key.create(this)); + return createVKey(getId()); } - public static VKey createVKey(Key key) { - return VKey.create(OneTime.class, key.getId(), key); + public static VKey createVKey(long id) { + return VKey.createSql(OneTime.class, id); } @Override @@ -430,19 +380,6 @@ public abstract class BillingEvent extends ImmutableObject return new Builder(clone(this)); } - @Override - void postLoad() { - super.postLoad(); - if (cancellationMatchingBillingEvent != null) { - cancellationMatchingBillingEvent = - cancellationMatchingBillingEvent.restoreOfy( - DomainBase.class, - domainRepoId, - DomainHistory.class, - recurringEventHistoryRevisionId); - } - } - /** A builder for {@link OneTime} since it is immutable. */ public static class Builder extends BillingEvent.Builder { @@ -475,11 +412,11 @@ public abstract class BillingEvent extends ImmutableObject } public Builder setCancellationMatchingBillingEvent( - VKey cancellationMatchingBillingEvent) { - getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent; - // getOfyKey() here is safe, recurring billing event VKeys have a valid ofy key. + Recurring cancellationMatchingBillingEvent) { + getInstance().cancellationMatchingBillingEvent = + cancellationMatchingBillingEvent.createVKey(); getInstance().recurringEventHistoryRevisionId = - cancellationMatchingBillingEvent.getOfyKey().getParent().getId(); + cancellationMatchingBillingEvent.getDomainHistoryRevisionId(); return this; } @@ -511,12 +448,6 @@ public abstract class BillingEvent extends ImmutableObject == (instance.cancellationMatchingBillingEvent != null), "Cancellation matching billing event must be set if and only if the SYNTHETIC flag " + "is set."); - // getOfyKey() here is safe, billing event VKeys have a valid ofy key. - checkState( - !instance.getFlags().contains(Flag.SYNTHETIC) - || (instance.cancellationMatchingBillingEvent.getOfyKey().getParent().getId() - == instance.recurringEventHistoryRevisionId), - "Cancellation matching billing event and its history revision ID does not match."); return super.build(); } } @@ -526,29 +457,26 @@ public abstract class BillingEvent extends ImmutableObject * A recurring billable event. * *

Unlike {@link OneTime} events, these do not store an explicit cost, since the cost of the - * recurring event might change and each time we bill for it we need to bill at the current cost, + * recurring event might change and each time we bill for it, we need to bill at the current cost, * not the value that was in use at the time the recurrence was created. */ - @ReportedOn - @Entity - @javax.persistence.Entity(name = "BillingRecurrence") - @javax.persistence.Table( + @Entity(name = "BillingRecurrence") + @Table( indexes = { - @javax.persistence.Index(columnList = "registrarId"), - @javax.persistence.Index(columnList = "eventTime"), - @javax.persistence.Index(columnList = "domainRepoId"), - @javax.persistence.Index(columnList = "recurrenceEndTime"), - @javax.persistence.Index(columnList = "recurrence_time_of_year") + @Index(columnList = "registrarId"), + @Index(columnList = "eventTime"), + @Index(columnList = "domainRepoId"), + @Index(columnList = "recurrenceEndTime"), + @Index(columnList = "recurrence_time_of_year") }) @AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id")) @WithLongVKey(compositeKey = true) public static class Recurring extends BillingEvent { /** - * The billing event recurs every year between {@link #eventTime} and this time on the - * [month, day, time] specified in {@link #recurrenceTimeOfYear}. + * The billing event recurs every year between {@link #eventTime} and this time on the [month, + * day, time] specified in {@link #recurrenceTimeOfYear}. */ - @Index DateTime recurrenceEndTime; /** @@ -564,11 +492,9 @@ public abstract class BillingEvent extends ImmutableObject * (same day of year, which can be 365 or 366 days later) which is what {@link TimeOfYear} can * model, whereas the billing time is a fixed {@link org.joda.time.Duration} later. */ - @Index @Embedded - @AttributeOverrides({ - @AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year")) - }) + @AttributeOverrides( + @AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year"))) TimeOfYear recurrenceTimeOfYear; /** @@ -605,11 +531,11 @@ public abstract class BillingEvent extends ImmutableObject @Override public VKey createVKey() { - return VKey.create(Recurring.class, getId(), Key.create(this)); + return createVKey(getId()); } - public static VKey createVKey(Key key) { - return VKey.create(Recurring.class, key.getId(), key); + public static VKey createVKey(Long id) { + return VKey.createSql(Recurring.class, id); } @Override @@ -647,8 +573,8 @@ public abstract class BillingEvent extends ImmutableObject checkNotNull(instance.eventTime); checkNotNull(instance.reason); checkArgument( - (instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED) - ^ (instance.renewalPrice == null), + instance.renewalPriceBehavior == RenewalPriceBehavior.SPECIFIED + ^ instance.renewalPrice == null, "Renewal price can have a value if and only if the renewal price behavior is" + " SPECIFIED"); instance.recurrenceTimeOfYear = TimeOfYear.fromDateTime(instance.eventTime); @@ -666,47 +592,45 @@ public abstract class BillingEvent extends ImmutableObject * preserve the immutability of billing events. */ @ReportedOn - @Entity - @javax.persistence.Entity(name = "BillingCancellation") - @javax.persistence.Table( + @Entity(name = "BillingCancellation") + @Table( indexes = { - @javax.persistence.Index(columnList = "registrarId"), - @javax.persistence.Index(columnList = "eventTime"), - @javax.persistence.Index(columnList = "domainRepoId"), - @javax.persistence.Index(columnList = "billingTime"), - @javax.persistence.Index(columnList = "billing_event_id"), - @javax.persistence.Index(columnList = "billing_recurrence_id") + @Index(columnList = "registrarId"), + @Index(columnList = "eventTime"), + @Index(columnList = "domainRepoId"), + @Index(columnList = "billingTime"), + @Index(columnList = "billing_event_id"), + @Index(columnList = "billing_recurrence_id") }) @AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id")) @WithLongVKey(compositeKey = true) public static class Cancellation extends BillingEvent { /** The billing time of the charge that is being cancelled. */ - @Index DateTime billingTime; /** * The one-time billing event to cancel, or null for autorenew cancellations. * - *

Although the type is {@link Key} the name "ref" is preserved for historical reasons. + *

Although the type is {@link VKey} the name "ref" is preserved for historical reasons. */ - @IgnoreSave(IfNull.class) - BillingEventVKey refOneTime = null; + @Column(name = "billing_event_id") + VKey refOneTime; /** * The recurring billing event to cancel, or null for non-autorenew cancellations. * - *

Although the type is {@link Key} the name "ref" is preserved for historical reasons. + *

Although the type is {@link VKey} the name "ref" is preserved for historical reasons. */ - @IgnoreSave(IfNull.class) - BillingRecurrenceVKey refRecurring = null; + @Column(name = "billing_recurrence_id") + VKey refRecurring; public DateTime getBillingTime() { return billingTime; } public VKey getEventKey() { - return firstNonNull(refOneTime, refRecurring).createVKey(); + return firstNonNull(refOneTime, refRecurring); } /** The mapping from billable grace period types to originating billing event reasons. */ @@ -723,22 +647,23 @@ public abstract class BillingEvent extends ImmutableObject * using the supplied targetId and deriving other metadata (clientId, billing time, and the * cancellation reason) from the grace period. */ - public static BillingEvent.Cancellation forGracePeriod( + public static Cancellation forGracePeriod( GracePeriod gracePeriod, DateTime eventTime, - Key domainHistoryKey, + DomainHistoryId domainHistoryId, String targetId) { - checkArgument(gracePeriod.hasBillingEvent(), + checkArgument( + gracePeriod.hasBillingEvent(), "Cannot create cancellation for grace period without billing event"); - BillingEvent.Cancellation.Builder builder = - new BillingEvent.Cancellation.Builder() + Builder builder = + new Builder() .setReason(checkNotNull(GRACE_PERIOD_TO_REASON.get(gracePeriod.getType()))) .setTargetId(targetId) .setRegistrarId(gracePeriod.getRegistrarId()) .setEventTime(eventTime) // The charge being cancelled will take place at the grace period's expiration time. .setBillingTime(gracePeriod.getExpirationTime()) - .setParent(domainHistoryKey); + .setDomainHistoryId(domainHistoryId); // Set the grace period's billing event using the appropriate Cancellation builder method. if (gracePeriod.getOneTimeBillingEvent() != null) { builder.setOneTimeEventKey(gracePeriod.getOneTimeBillingEvent()); @@ -750,11 +675,11 @@ public abstract class BillingEvent extends ImmutableObject @Override public VKey createVKey() { - return VKey.create(Cancellation.class, getId(), Key.create(this)); + return createVKey(getId()); } - public static VKey createVKey(Key key) { - return VKey.create(Cancellation.class, key.getId(), key); + public static VKey createVKey(long id) { + return VKey.createSql(Cancellation.class, id); } @Override @@ -776,13 +701,13 @@ public abstract class BillingEvent extends ImmutableObject return this; } - public Builder setOneTimeEventKey(VKey eventKey) { - getInstance().refOneTime = BillingEventVKey.create(eventKey); + public Builder setOneTimeEventKey(VKey eventKey) { + getInstance().refOneTime = eventKey; return this; } - public Builder setRecurringEventKey(VKey eventKey) { - getInstance().refRecurring = BillingRecurrenceVKey.create(eventKey); + public Builder setRecurringEventKey(VKey eventKey) { + getInstance().refRecurring = eventKey; return this; } @@ -791,115 +716,11 @@ public abstract class BillingEvent extends ImmutableObject Cancellation instance = getInstance(); checkNotNull(instance.billingTime, "Must set billing time"); checkNotNull(instance.reason, "Must set reason"); - checkState((instance.refOneTime == null) != (instance.refRecurring == null), + checkState( + (instance.refOneTime == null) != (instance.refRecurring == null), "Cancellations must have exactly one billing event key set"); return super.build(); } } } - - /** An event representing a modification of an existing one-time billing event. */ - @ReportedOn - @Entity - @WithLongVKey(compositeKey = true) - public static class Modification extends BillingEvent { - - /** The change in cost that should be applied to the original billing event. */ - Money cost; - - /** The one-time billing event to modify. */ - Key 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 getEventKey() { - return eventRef; - } - - public String getDescription() { - return description; - } - - @Override - public Builder asBuilder() { - return new Builder(clone(this)); - } - - @Override - public VKey createVKey() { - return VKey.create(Modification.class, getId(), Key.create(this)); - } - - public static VKey createVKey(Key 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. - * - *

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 { - - public Builder() {} - - private Builder(Modification instance) { - super(instance); - } - - public Builder setCost(Money cost) { - getInstance().cost = cost; - return this; - } - - public Builder setEventKey(Key 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(); - } - } - } } diff --git a/core/src/main/java/google/registry/model/common/ClassPathManager.java b/core/src/main/java/google/registry/model/common/ClassPathManager.java index ae1280fcb..59af3c2cb 100644 --- a/core/src/main/java/google/registry/model/common/ClassPathManager.java +++ b/core/src/main/java/google/registry/model/common/ClassPathManager.java @@ -53,12 +53,16 @@ public class ClassPathManager { } public static Class 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) CLASS_REGISTRY.get(className); } public static String getClassName(Class 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); } } diff --git a/core/src/main/java/google/registry/model/domain/DomainContent.java b/core/src/main/java/google/registry/model/domain/DomainContent.java index 8366c164c..8b5aaaf51 100644 --- a/core/src/main/java/google/registry/model/domain/DomainContent.java +++ b/core/src/main/java/google/registry/model/domain/DomainContent.java @@ -206,6 +206,7 @@ public class DomainContent extends EppResource * should be created, and this field should be updated to point to the new one. */ @Column(name = "billing_recurrence_id") + @Ignore VKey autorenewBillingEvent; /** diff --git a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java index 57074b3a0..c43636e11 100644 --- a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java +++ b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java @@ -65,6 +65,7 @@ public class GracePeriodBase extends ImmutableObject implements UnsafeSerializab // NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections. @Access(AccessType.FIELD) @Column(name = "billing_event_id") + @Ignore VKey billingEventOneTime = null; /** @@ -74,6 +75,7 @@ public class GracePeriodBase extends ImmutableObject implements UnsafeSerializab // NB: Would @IgnoreSave(IfNull.class), but not allowed for @Embed collections. @Access(AccessType.FIELD) @Column(name = "billing_recurrence_id") + @Ignore VKey billingEventRecurring = null; public long getGracePeriodId() { diff --git a/core/src/main/java/google/registry/model/domain/token/AllocationToken.java b/core/src/main/java/google/registry/model/domain/token/AllocationToken.java index c3ae9ad21..857c64810 100644 --- a/core/src/main/java/google/registry/model/domain/token/AllocationToken.java +++ b/core/src/main/java/google/registry/model/domain/token/AllocationToken.java @@ -168,6 +168,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable { @Enumerated(EnumType.STRING) @Column(name = "renewalPriceBehavior", nullable = false) + @Ignore RenewalPriceBehavior renewalPriceBehavior = RenewalPriceBehavior.DEFAULT; @Enumerated(EnumType.STRING) diff --git a/core/src/main/java/google/registry/model/transfer/DomainTransferData.java b/core/src/main/java/google/registry/model/transfer/DomainTransferData.java index 87545c3eb..fec3755d3 100644 --- a/core/src/main/java/google/registry/model/transfer/DomainTransferData.java +++ b/core/src/main/java/google/registry/model/transfer/DomainTransferData.java @@ -85,8 +85,8 @@ public class DomainTransferData extends TransferData *

This field should be null if there is not currently a pending transfer or if the object * being transferred is not a domain. */ - @IgnoreSave(IfNull.class) @Column(name = "transfer_billing_event_id") + @Ignore VKey serverApproveBillingEvent; /** @@ -95,8 +95,8 @@ public class DomainTransferData extends TransferData *

This field should be null if there is not currently a pending transfer or if the object * being transferred is not a domain. */ - @IgnoreSave(IfNull.class) @Column(name = "transfer_billing_recurrence_id") + @Ignore VKey serverApproveAutorenewEvent; /** diff --git a/core/src/main/java/google/registry/model/translators/EppHistoryVKeyTranslatorFactory.java b/core/src/main/java/google/registry/model/translators/EppHistoryVKeyTranslatorFactory.java index 8ca7627ac..eeda422d3 100644 --- a/core/src/main/java/google/registry/model/translators/EppHistoryVKeyTranslatorFactory.java +++ b/core/src/main/java/google/registry/model/translators/EppHistoryVKeyTranslatorFactory.java @@ -21,8 +21,6 @@ import com.google.appengine.api.datastore.Key; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import google.registry.persistence.BillingVKey.BillingEventVKey; -import google.registry.persistence.BillingVKey.BillingRecurrenceVKey; import google.registry.persistence.DomainHistoryVKey; import google.registry.persistence.EppHistoryVKey; import java.lang.reflect.Constructor; @@ -45,8 +43,7 @@ public class EppHistoryVKeyTranslatorFactory // key, e.g. the map key for ContactPollMessageVKey is "ContactResource/HistoryEntry/PollMessage". @VisibleForTesting static final ImmutableMap> kindPathToVKeyClass = - ImmutableSet.of(DomainHistoryVKey.class, BillingEventVKey.class, BillingRecurrenceVKey.class) - .stream() + ImmutableSet.of(DomainHistoryVKey.class).stream() .collect(toImmutableMap(EppHistoryVKeyTranslatorFactory::getKindPath, identity())); /** diff --git a/core/src/main/java/google/registry/persistence/BillingVKey.java b/core/src/main/java/google/registry/persistence/BillingVKey.java deleted file mode 100644 index cc0b8121b..000000000 --- a/core/src/main/java/google/registry/persistence/BillingVKey.java +++ /dev/null @@ -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 extends EppHistoryVKey { - Long billingId; - - // Hibernate requires a default constructor. - BillingVKey() {} - - BillingVKey(String repoId, long historyRevisionId, long billingId) { - super(repoId, historyRevisionId); - this.billingId = billingId; - } - - Key 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 { - - // 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 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 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 { - - // 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 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 vKey) { - return vKey == null ? null : new BillingRecurrenceVKey(null, 0, (Long) vKey.getSqlKey()); - } - } -} diff --git a/core/src/main/java/google/registry/persistence/converter/VKeyConverter.java b/core/src/main/java/google/registry/persistence/converter/VKeyConverter.java index b6af98c2e..61bce4ee2 100644 --- a/core/src/main/java/google/registry/persistence/converter/VKeyConverter.java +++ b/core/src/main/java/google/registry/persistence/converter/VKeyConverter.java @@ -20,11 +20,12 @@ import java.io.Serializable; import javax.annotation.Nullable; import javax.persistence.AttributeConverter; -/** Converts VKey to a string column. */ +/** Converts VKey to a string or long column. */ public abstract class VKeyConverter implements AttributeConverter, C> { @Override @Nullable + @SuppressWarnings("unchecked") public C convertToDatabaseColumn(@Nullable VKey attribute) { return attribute == null ? null : (C) attribute.getSqlKey(); } @@ -35,8 +36,8 @@ public abstract class VKeyConverter if (dbData == null) { return null; } - Class clazz = getAttributeClass(); - Key ofyKey = null; + Class clazz = getAttributeClass(); + Key ofyKey; if (!hasCompositeOfyKey()) { // If this isn't a composite key, we can create the Ofy key from the SQL key. ofyKey = diff --git a/core/src/main/java/google/registry/tools/DomainLockUtils.java b/core/src/main/java/google/registry/tools/DomainLockUtils.java index a18310535..dfb24abe9 100644 --- a/core/src/main/java/google/registry/tools/DomainLockUtils.java +++ b/core/src/main/java/google/registry/tools/DomainLockUtils.java @@ -415,7 +415,7 @@ public final class DomainLockUtils { .setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost()) .setEventTime(now) .setBillingTime(now) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build(); tm().insert(oneTime); } diff --git a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java index 91c731f4d..a56561e60 100644 --- a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java @@ -208,7 +208,7 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot BillingEvent.Recurring newAutorenewEvent = newAutorenewBillingEvent(domain) .setEventTime(newExpirationTime) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build(); PollMessage.Autorenew newAutorenewPollMessage = newAutorenewPollMessage(domain) diff --git a/core/src/main/resources/META-INF/persistence.xml b/core/src/main/resources/META-INF/persistence.xml index c2768c40b..9c50a9e10 100644 --- a/core/src/main/resources/META-INF/persistence.xml +++ b/core/src/main/resources/META-INF/persistence.xml @@ -99,7 +99,6 @@ google.registry.model.billing.VKeyConverter_Cancellation - google.registry.model.billing.VKeyConverter_Modification google.registry.model.billing.VKeyConverter_OneTime google.registry.model.billing.VKeyConverter_Recurring google.registry.model.contact.VKeyConverter_ContactResource diff --git a/core/src/main/resources/google/registry/beam/invoicing/sql/billing_events.sql b/core/src/main/resources/google/registry/beam/invoicing/sql/billing_events.sql deleted file mode 100644 index 477684696..000000000 --- a/core/src/main/resources/google/registry/beam/invoicing/sql/billing_events.sql +++ /dev/null @@ -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", "", ...' - 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 diff --git a/core/src/main/resources/google/registry/beam/invoicing/sql/cloud_sql_billing_events.sql b/core/src/main/resources/google/registry/beam/invoicing/sql/cloud_sql_billing_events.sql index 8921f123c..09f932798 100644 --- a/core/src/main/resources/google/registry/beam/invoicing/sql/cloud_sql_billing_events.sql +++ b/core/src/main/resources/google/registry/beam/invoicing/sql/cloud_sql_billing_events.sql @@ -29,8 +29,8 @@ SELECT b, r FROM BillingEvent b JOIN Registrar r ON b.clientId = r.clientIdentifier JOIN Domain d ON b.domainRepoId = d.repoId JOIN Tld t ON t.tldStr = d.tld -LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId -LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring.billingId +LEFT JOIN BillingCancellation c ON b.id = c.refOneTime +LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.refRecurring WHERE r.billingAccountMap IS NOT NULL AND r.type = 'REAL' AND t.invoicingEnabled IS TRUE diff --git a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java index 354e14ca5..2e0d0a6e9 100644 --- a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java @@ -200,7 +200,7 @@ class DeleteExpiredDomainsActionTest { .setRegistrarId("TheRegistrar") .setEventTime(clock.nowUtc().plusYears(1)) .setRecurrenceEndTime(END_OF_TIME) - .setParent(createHistoryEntry); + .setDomainHistory(createHistoryEntry); } private PollMessage.Autorenew.Builder createAutorenewPollMessage( diff --git a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java index 4e53151e6..3d266bac2 100644 --- a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java @@ -296,7 +296,7 @@ class DeleteProberDataActionTest { BillingEvent.OneTime billingEvent = persistSimpleResource( new BillingEvent.OneTime.Builder() - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setBillingTime(DELETION_TIME.plusYears(1)) .setCost(Money.parse("USD 10")) .setPeriodYears(1) diff --git a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java index b9b018441..16b3ad84f 100644 --- a/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java +++ b/core/src/test/java/google/registry/batch/ExpandRecurringBillingEventsActionTest.java @@ -105,7 +105,7 @@ public class ExpandRecurringBillingEventsActionTest { .build()); recurring = new BillingEvent.Recurring.Builder() - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setRegistrarId(domain.getCreationRegistrarId()) .setEventTime(DateTime.parse("2000-01-05T00:00:00Z")) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) @@ -171,7 +171,7 @@ public class ExpandRecurringBillingEventsActionTest { .setPeriodYears(1) .setReason(Reason.RENEW) .setSyntheticCreationTime(currentTestTime) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setCancellationMatchingBillingEvent(recurring) .setTargetId(domain.getDomainName()); } @@ -184,7 +184,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -204,7 +205,7 @@ public class ExpandRecurringBillingEventsActionTest { recurring = persistResource( new BillingEvent.Recurring.Builder() - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setRegistrarId(deletedDomain.getCreationRegistrarId()) .setEventTime(DateTime.parse("2000-01-05T00:00:00Z")) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) @@ -225,7 +226,7 @@ public class ExpandRecurringBillingEventsActionTest { true); BillingEvent.OneTime expected = defaultOneTimeBuilder() - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .setTargetId(deletedDomain.getDomainName()) .build(); assertBillingEventsForResource(deletedDomain, expected, recurring); @@ -241,7 +242,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertCursorAt(currentTestTime); DateTime beginningOfSecondRun = clock.nowUtc(); action.response = new FakeResponse(); @@ -254,7 +256,7 @@ public class ExpandRecurringBillingEventsActionTest { void testSuccess_expandSingleEvent_idempotentForExistingOneTime() throws Exception { persistResource(recurring); BillingEvent.OneTime persisted = - persistResource(defaultOneTimeBuilder().setParent(historyEntry).build()); + persistResource(defaultOneTimeBuilder().setDomainHistory(historyEntry).build()); action.cursorTimeParam = Optional.of(START_OF_TIME); runAction(); // No new history entries should be generated @@ -273,7 +275,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); // Persist an otherwise identical billing event that differs only in billing time (and ID). BillingEvent.OneTime persisted = persistResource( @@ -301,13 +304,13 @@ public class ExpandRecurringBillingEventsActionTest { } assertThat(persistedEntries).hasSize(2); BillingEvent.OneTime expected = - defaultOneTimeBuilder().setParent(persistedEntries.get(0)).build(); + defaultOneTimeBuilder().setDomainHistory(persistedEntries.get(0)).build(); // Persist an otherwise identical billing event that differs only in recurring event key. BillingEvent.OneTime persisted = expected .asBuilder() - .setParent(persistedEntries.get(1)) - .setCancellationMatchingBillingEvent(recurring2.createVKey()) + .setDomainHistory(persistedEntries.get(1)) + .setCancellationMatchingBillingEvent(recurring2) .build(); assertCursorAt(currentTestTime); assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2); @@ -350,7 +353,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -364,7 +368,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -401,7 +406,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2002-02-19T00:00:00Z")) .setEventTime(DateTime.parse("2002-01-05T00:00:00Z")) - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); @@ -416,7 +421,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -482,7 +488,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(billingDate.plusYears(year)) .setEventTime(eventDate.plusYears(year)) - .setParent(persistedEntries.get(year)) + .setDomainHistory(persistedEntries.get(year)) .build()); } assertBillingEventsForResource(domain, Iterables.toArray(expectedEvents, BillingEvent.class)); @@ -508,7 +514,7 @@ public class ExpandRecurringBillingEventsActionTest { expectedEvents.add( defaultOneTimeBuilder() .setBillingTime(billingDate.plusYears(year)) - .setParent(persistedEntries.get(year)) + .setDomainHistory(persistedEntries.get(year)) .setEventTime(eventDate.plusYears(year)) .build()); } @@ -554,7 +560,7 @@ public class ExpandRecurringBillingEventsActionTest { BillingEvent.OneTime expected = defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2000-02-19T00:00:00Z")) - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .build(); assertBillingEventsForResource(domain, recurring, expected); assertCursorAt(currentTestTime); @@ -583,7 +589,7 @@ public class ExpandRecurringBillingEventsActionTest { BillingEvent.OneTime expected = defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2000-02-19T00:00:00Z")) - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .build(); assertBillingEventsForResource(domain, recurring, expected); assertCursorAt(currentTestTime); @@ -604,7 +610,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2000-02-29T00:00:00Z")) .setEventTime(DateTime.parse("2000-01-15T00:00:00Z")) - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); @@ -626,7 +632,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2001-03-01T00:00:00Z")) .setEventTime(DateTime.parse("2001-01-15T00:00:00Z")) - .setParent(persistedEntry) + .setDomainHistory(persistedEntry) .build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); @@ -652,7 +658,7 @@ public class ExpandRecurringBillingEventsActionTest { BillingEvent.Recurring recurring2 = persistResource( new BillingEvent.Recurring.Builder() - .setParent(historyEntry2) + .setDomainHistory(historyEntry2) .setRegistrarId(domain2.getCreationRegistrarId()) .setEventTime(DateTime.parse("2000-04-05T00:00:00Z")) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) @@ -677,7 +683,7 @@ public class ExpandRecurringBillingEventsActionTest { BillingEvent.Recurring recurring3 = persistResource( new BillingEvent.Recurring.Builder() - .setParent(historyEntry3) + .setDomainHistory(historyEntry3) .setRegistrarId(domain3.getCreationRegistrarId()) .setEventTime(DateTime.parse("2000-06-05T00:00:00Z")) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) @@ -694,8 +700,8 @@ public class ExpandRecurringBillingEventsActionTest { domain, persistedHistory1, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); BillingEvent.OneTime expected = defaultOneTimeBuilder() - .setParent(persistedHistory1) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setDomainHistory(persistedHistory1) + .setCancellationMatchingBillingEvent(recurring) .build(); DomainHistory persistedHistory2 = getOnlyHistoryEntryOfType(domain2, DOMAIN_AUTORENEW, DomainHistory.class); @@ -705,9 +711,9 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2000-05-20T00:00:00Z")) .setEventTime(DateTime.parse("2000-04-05T00:00:00Z")) - .setParent(persistedHistory2) + .setDomainHistory(persistedHistory2) .setTargetId(domain2.getDomainName()) - .setCancellationMatchingBillingEvent(recurring2.createVKey()) + .setCancellationMatchingBillingEvent(recurring2) .build(); DomainHistory persistedHistory3 = getOnlyHistoryEntryOfType(domain3, DOMAIN_AUTORENEW, DomainHistory.class); @@ -718,8 +724,8 @@ public class ExpandRecurringBillingEventsActionTest { .setBillingTime(DateTime.parse("2000-07-20T00:00:00Z")) .setEventTime(DateTime.parse("2000-06-05T00:00:00Z")) .setTargetId(domain3.getDomainName()) - .setParent(persistedHistory3) - .setCancellationMatchingBillingEvent(recurring3.createVKey()) + .setDomainHistory(persistedHistory3) + .setCancellationMatchingBillingEvent(recurring3) .build(); assertBillingEventsForResource(domain, expected, recurring); assertBillingEventsForResource(domain2, expected2, recurring2); @@ -755,8 +761,8 @@ public class ExpandRecurringBillingEventsActionTest { true); BillingEvent.OneTime expected = defaultOneTimeBuilder() - .setParent(persistedEntries.get(0)) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setDomainHistory(persistedEntries.get(0)) + .setCancellationMatchingBillingEvent(recurring) .build(); assertHistoryEntryMatches( domain, @@ -768,8 +774,8 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(DateTime.parse("2000-05-20T00:00:00Z")) .setEventTime(DateTime.parse("2000-04-05T00:00:00Z")) - .setParent(persistedEntries.get(1)) - .setCancellationMatchingBillingEvent(recurring2.createVKey()) + .setDomainHistory(persistedEntries.get(1)) + .setCancellationMatchingBillingEvent(recurring2) .build(); assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2); assertCursorAt(currentTestTime); @@ -812,8 +818,8 @@ public class ExpandRecurringBillingEventsActionTest { BillingEvent.OneTime expected = defaultOneTimeBuilder() .setCost(Money.of(USD, 4)) - .setParent(persistedEntries.get(0)) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setDomainHistory(persistedEntries.get(0)) + .setCancellationMatchingBillingEvent(recurring) .build(); assertHistoryEntryMatches( domain, @@ -826,8 +832,8 @@ public class ExpandRecurringBillingEventsActionTest { .setCost(Money.of(USD, 4)) .setBillingTime(DateTime.parse("2000-05-20T00:00:00Z")) .setEventTime(DateTime.parse("2000-04-05T00:00:00Z")) - .setParent(persistedEntries.get(1)) - .setCancellationMatchingBillingEvent(recurring2.createVKey()) + .setDomainHistory(persistedEntries.get(1)) + .setCancellationMatchingBillingEvent(recurring2) .build(); assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2); assertCursorAt(currentTestTime); @@ -848,7 +854,10 @@ public class ExpandRecurringBillingEventsActionTest { assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); BillingEvent.OneTime expected = - defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 100)).build(); + defaultOneTimeBuilder() + .setDomainHistory(persistedEntry) + .setCost(Money.of(USD, 100)) + .build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -868,7 +877,7 @@ public class ExpandRecurringBillingEventsActionTest { assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); BillingEvent.OneTime expected = - defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 11)).build(); + defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 11)).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -882,7 +891,8 @@ public class ExpandRecurringBillingEventsActionTest { getOnlyHistoryEntryOfType(domain, DOMAIN_AUTORENEW, DomainHistory.class); assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); - BillingEvent.OneTime expected = defaultOneTimeBuilder().setParent(persistedEntry).build(); + BillingEvent.OneTime expected = + defaultOneTimeBuilder().setDomainHistory(persistedEntry).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -908,7 +918,7 @@ public class ExpandRecurringBillingEventsActionTest { assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); BillingEvent.OneTime expected = - defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 20)).build(); + defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 20)).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -929,7 +939,7 @@ public class ExpandRecurringBillingEventsActionTest { assertHistoryEntryMatches( domain, persistedEntry, "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"), true); BillingEvent.OneTime expected = - defaultOneTimeBuilder().setParent(persistedEntry).setCost(Money.of(USD, 2)).build(); + defaultOneTimeBuilder().setDomainHistory(persistedEntry).setCost(Money.of(USD, 2)).build(); assertBillingEventsForResource(domain, expected, recurring); assertCursorAt(currentTestTime); } @@ -961,7 +971,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(billingDate) .setEventTime(eventDate) - .setParent(persistedEntries.get(0)) + .setDomainHistory(persistedEntries.get(0)) .setCost(Money.of(USD, 8)) .build(); assertHistoryEntryMatches( @@ -972,7 +982,7 @@ public class ExpandRecurringBillingEventsActionTest { .setCost(Money.of(USD, 10)) .setBillingTime(billingDate.plusYears(1)) .setEventTime(eventDate.plusYears(1)) - .setParent(persistedEntries.get(1)) + .setDomainHistory(persistedEntries.get(1)) .build(); assertBillingEventsForResource(domain, recurring, cheaper, expensive); assertCursorAt(currentTestTime); @@ -1006,7 +1016,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(billingDate) .setEventTime(eventDate) - .setParent(persistedEntries.get(0)) + .setDomainHistory(persistedEntries.get(0)) .setCost(Money.of(USD, 8)) .build(); assertHistoryEntryMatches( @@ -1017,7 +1027,7 @@ public class ExpandRecurringBillingEventsActionTest { .setCost(Money.of(USD, 10)) .setBillingTime(billingDate.plusYears(1)) .setEventTime(eventDate.plusYears(1)) - .setParent(persistedEntries.get(1)) + .setDomainHistory(persistedEntries.get(1)) .build(); assertBillingEventsForResource(domain, recurring, cheaper, expensive); assertCursorAt(currentTestTime); @@ -1057,7 +1067,7 @@ public class ExpandRecurringBillingEventsActionTest { defaultOneTimeBuilder() .setBillingTime(billingDate) .setEventTime(eventDate) - .setParent(persistedEntries.get(0)) + .setDomainHistory(persistedEntries.get(0)) .setCost(Money.of(USD, 5)) .build(); assertHistoryEntryMatches( @@ -1068,7 +1078,7 @@ public class ExpandRecurringBillingEventsActionTest { .setCost(Money.of(USD, 5)) .setBillingTime(billingDate.plusYears(1)) .setEventTime(eventDate.plusYears(1)) - .setParent(persistedEntries.get(1)) + .setDomainHistory(persistedEntries.get(1)) .build(); assertBillingEventsForResource(domain, recurring, cheaper, expensive); assertCursorAt(currentTestTime); diff --git a/core/src/test/java/google/registry/beam/invoicing/BillingEventTest.java b/core/src/test/java/google/registry/beam/invoicing/BillingEventTest.java index 15b0924c5..aa152b5fe 100644 --- a/core/src/test/java/google/registry/beam/invoicing/BillingEventTest.java +++ b/core/src/test/java/google/registry/beam/invoicing/BillingEventTest.java @@ -15,7 +15,6 @@ package google.registry.beam.invoicing; import static com.google.common.truth.Truth.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder; @@ -23,108 +22,41 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericRecord; -import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord; import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** Unit tests for {@link BillingEvent} */ class BillingEventTest { - private static final String BILLING_EVENT_SCHEMA = - "{\"name\": \"BillingEvent\", " - + "\"type\": \"record\", " - + "\"fields\": [" - + "{\"name\": \"id\", \"type\": \"long\"}," - + "{\"name\": \"billingTime\", \"type\": \"string\"}," - + "{\"name\": \"eventTime\", \"type\": \"string\"}," - + "{\"name\": \"registrarId\", \"type\": \"string\"}," - + "{\"name\": \"billingId\", \"type\": \"long\"}," - + "{\"name\": \"poNumber\", \"type\": \"string\"}," - + "{\"name\": \"tld\", \"type\": \"string\"}," - + "{\"name\": \"action\", \"type\": \"string\"}," - + "{\"name\": \"domain\", \"type\": \"string\"}," - + "{\"name\": \"repositoryId\", \"type\": \"string\"}," - + "{\"name\": \"years\", \"type\": \"int\"}," - + "{\"name\": \"currency\", \"type\": \"string\"}," - + "{\"name\": \"amount\", \"type\": \"float\"}," - + "{\"name\": \"flags\", \"type\": \"string\"}" - + "]}"; - - private SchemaAndRecord schemaAndRecord; + private BillingEvent event; @BeforeEach void beforeEach() { - // Create a record with a given JSON schema. - schemaAndRecord = new SchemaAndRecord(createRecord(), null); + event = createBillingEvent("", 5); } - private GenericRecord createRecord() { - GenericRecord record = new GenericData.Record(new Schema.Parser().parse(BILLING_EVENT_SCHEMA)); - record.put("id", "1"); - record.put("billingTime", 1508835963000000L); - record.put("eventTime", 1484870383000000L); - record.put("registrarId", "myRegistrar"); - record.put("billingId", "12345-CRRHELLO"); - record.put("poNumber", ""); - record.put("tld", "test"); - record.put("action", "RENEW"); - record.put("domain", "example.test"); - record.put("repositoryId", "123456"); - record.put("years", 5); - record.put("currency", "USD"); - record.put("amount", 20.5); - record.put("flags", "AUTO_RENEW SYNTHETIC"); - return record; - } - - @Test - void testParseBillingEventFromRecord_success() { - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); - assertThat(event.id()).isEqualTo(1); - assertThat(event.billingTime()).isEqualTo(DateTime.parse("2017-10-24T09:06:03Z")); - assertThat(event.eventTime()).isEqualTo(DateTime.parse("2017-01-19T23:59:43Z")); - assertThat(event.registrarId()).isEqualTo("myRegistrar"); - assertThat(event.billingId()).isEqualTo("12345-CRRHELLO"); - assertThat(event.poNumber()).isEmpty(); - assertThat(event.tld()).isEqualTo("test"); - assertThat(event.action()).isEqualTo("RENEW"); - assertThat(event.domain()).isEqualTo("example.test"); - assertThat(event.repositoryId()).isEqualTo("123456"); - assertThat(event.years()).isEqualTo(5); - assertThat(event.currency()).isEqualTo("USD"); - assertThat(event.amount()).isEqualTo(20.5); - assertThat(event.flags()).isEqualTo("AUTO_RENEW SYNTHETIC"); - } - - @Test - void testParseBillingEventFromRecord_sunriseCreate_reducedPrice_success() { - schemaAndRecord.getRecord().put("flags", "SUNRISE"); - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); - assertThat(event.amount()).isEqualTo(17.43); - assertThat(event.flags()).isEqualTo("SUNRISE"); - } - - @Test - void testParseBillingEventFromRecord_anchorTenant_zeroPrice_success() { - schemaAndRecord.getRecord().put("flags", "SUNRISE ANCHOR_TENANT"); - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); - assertThat(event.amount()).isZero(); - assertThat(event.flags()).isEqualTo("SUNRISE ANCHOR_TENANT"); - } - - @Test - void testParseBillingEventFromRecord_nullValue_throwsException() { - schemaAndRecord.getRecord().put("tld", null); - assertThrows(IllegalStateException.class, () -> BillingEvent.parseFromRecord(schemaAndRecord)); + private static BillingEvent createBillingEvent(String pONumber, int years) { + return BillingEvent.create( + 1, + new DateTime(1508835963000L, DateTimeZone.UTC), + new DateTime(1484870383000L, DateTimeZone.UTC), + "myRegistrar", + "12345-CRRHELLO", + pONumber, + "test", + "RENEW", + "example.test", + "123456", + years, + "USD", + 20.5, + "AUTO_RENEW SYNTHETIC"); } @Test void testConvertBillingEvent_toCsv() { - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); assertThat(event.toCsv()) .isEqualTo( "1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar," @@ -133,9 +65,7 @@ class BillingEventTest { @Test void testConvertBillingEvent_nonNullPoNumber_toCsv() { - GenericRecord record = createRecord(); - record.put("poNumber", "905610"); - BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null)); + event = createBillingEvent("905610", 5); assertThat(event.toCsv()) .isEqualTo( "1,2017-10-24 09:06:03 UTC,2017-01-19 23:59:43 UTC,myRegistrar," @@ -144,13 +74,11 @@ class BillingEventTest { @Test void testGenerateBillingEventFilename() { - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); assertThat(event.toFilename("2017-10")).isEqualTo("invoice_details_2017-10_myRegistrar_test"); } @Test void testGetInvoiceGroupingKey_fromBillingEvent() { - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey(); assertThat(invoiceKey.startDate()).isEqualTo("2017-10-01"); assertThat(invoiceKey.endDate()).isEqualTo("2022-09-30"); @@ -164,9 +92,7 @@ class BillingEventTest { @Test void test_nonNullPoNumber() { - GenericRecord record = createRecord(); - record.put("poNumber", "905610"); - BillingEvent event = BillingEvent.parseFromRecord(new SchemaAndRecord(record, null)); + event = createBillingEvent("905610", 5); assertThat(event.poNumber()).isEqualTo("905610"); InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey(); assertThat(invoiceKey.poNumber()).isEqualTo("905610"); @@ -174,7 +100,6 @@ class BillingEventTest { @Test void testConvertInvoiceGroupingKey_toCsv() { - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey(); assertThat(invoiceKey.toCsv(3L)) .isEqualTo( @@ -184,10 +109,7 @@ class BillingEventTest { @Test void testConvertInvoiceGroupingKey_zeroYears_toCsv() { - GenericRecord record = schemaAndRecord.getRecord(); - record.put("years", 0); - schemaAndRecord = new SchemaAndRecord(record, null); - BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord); + event = createBillingEvent("", 0); InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey(); assertThat(invoiceKey.toCsv(3L)) .isEqualTo( @@ -197,8 +119,7 @@ class BillingEventTest { @Test void testInvoiceGroupingKeyCoder_deterministicSerialization() throws IOException { - InvoiceGroupingKey invoiceKey = - BillingEvent.parseFromRecord(schemaAndRecord).getInvoiceGroupingKey(); + InvoiceGroupingKey invoiceKey = event.getInvoiceGroupingKey(); InvoiceGroupingKeyCoder coder = new InvoiceGroupingKeyCoder(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); coder.encode(invoiceKey, outStream); @@ -217,8 +138,9 @@ class BillingEventTest { @Test void testGetOverallInvoiceHeader() { assertThat(InvoiceGroupingKey.invoiceHeader()) - .isEqualTo("StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode," - + "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice," - + "UnitPriceCurrency,PONumber"); + .isEqualTo( + "StartDate,EndDate,ProductAccountKey,Amount,AmountCurrency,BillingProductCode," + + "SalesChannel,LineItemType,UsageGroupingKey,Quantity,Description,UnitPrice," + + "UnitPriceCurrency,PONumber"); } } diff --git a/core/src/test/java/google/registry/beam/invoicing/InvoicingPipelineTest.java b/core/src/test/java/google/registry/beam/invoicing/InvoicingPipelineTest.java index 98af221d0..265bf222d 100644 --- a/core/src/test/java/google/registry/beam/invoicing/InvoicingPipelineTest.java +++ b/core/src/test/java/google/registry/beam/invoicing/InvoicingPipelineTest.java @@ -50,7 +50,6 @@ import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; import google.registry.testing.DatastoreEntityExtension; import google.registry.testing.FakeClock; -import google.registry.testing.TestDataHelper; import google.registry.util.ResourceUtils; import java.io.File; import java.nio.file.Files; @@ -67,7 +66,6 @@ import org.apache.beam.sdk.transforms.MapElements; import org.apache.beam.sdk.transforms.PTransform; import org.apache.beam.sdk.values.PCollection; import org.apache.beam.sdk.values.TypeDescriptor; -import org.joda.money.CurrencyUnit; import org.joda.money.Money; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; @@ -81,8 +79,7 @@ class InvoicingPipelineTest { @RegisterExtension @Order(Order.DEFAULT - 1) - final transient DatastoreEntityExtension datastore = - new DatastoreEntityExtension().allThreads(true); + final DatastoreEntityExtension datastore = new DatastoreEntityExtension().allThreads(true); @RegisterExtension final TestPipelineExtension pipeline = @@ -263,15 +260,6 @@ class InvoicingPipelineTest { pipeline.apply(Create.of(INPUT_EVENTS).withCoder(SerializableCoder.of(BillingEvent.class))); } - @Test - void testSuccess_makeQuery() { - String query = InvoicingPipeline.makeQuery("2017-10", "my-project-id"); - assertThat(query) - .isEqualTo(TestDataHelper.loadFile(this.getClass(), "billing_events_test.sql")); - // This is necessary because the TestPipelineExtension verifies that the pipeline is run. - pipeline.run(); - } - @Test void testSuccess_fullSqlPipeline() throws Exception { setupCloudSql(); @@ -365,14 +353,14 @@ class InvoicingPipelineTest { // Test that comments are removed from the .sql file correctly assertThat(InvoicingPipeline.makeCloudSqlQuery("2017-10")) .isEqualTo( - "\n" + '\n' + "SELECT b, r FROM BillingEvent b\n" + "JOIN Registrar r ON b.clientId = r.clientIdentifier\n" + "JOIN Domain d ON b.domainRepoId = d.repoId\n" + "JOIN Tld t ON t.tldStr = d.tld\n" - + "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime.billingId\n" + + "LEFT JOIN BillingCancellation c ON b.id = c.refOneTime\n" + "LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent =" - + " cr.refRecurring.billingId\n" + + " cr.refRecurring\n" + "WHERE r.billingAccountMap IS NOT NULL\n" + "AND r.type = 'REAL'\n" + "AND t.invoicingEnabled IS TRUE\n" @@ -386,13 +374,12 @@ class InvoicingPipelineTest { private ImmutableList resultFileContents(String filename) throws Exception { File resultFile = new File( - String.format( - "%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath().toString(), filename)); + String.format("%s/invoices/2017-10/%s", billingBucketUrl.getAbsolutePath(), filename)); return ImmutableList.copyOf( ResourceUtils.readResourceUtf8(resultFile.toURI().toURL()).split("\n")); } - private void setupCloudSql() { + private static void setupCloudSql() { // Populate billing events in Cloud SQL to match existing test data for Datastore persistNewRegistrar("NewRegistrar"); persistNewRegistrar("TheRegistrar"); @@ -444,7 +431,7 @@ class InvoicingPipelineTest { registrar1, Reason.CREATE, 5, - Money.ofMajor(CurrencyUnit.JPY, 70), + Money.ofMajor(JPY, 70), DateTime.parse("2017-09-29T00:00:00.0Z"), DateTime.parse("2017-10-02T00:00:00.0Z")); persistOneTimeBillingEvent(4, domain4, registrar2, Reason.RENEW, 1, Money.of(USD, 20.5)); @@ -495,7 +482,7 @@ class InvoicingPipelineTest { registrar1, Reason.CREATE, 5, - Money.ofMajor(CurrencyUnit.JPY, 70), + Money.ofMajor(JPY, 70), DateTime.parse("2017-06-29T00:00:00.0Z"), DateTime.parse("2017-07-02T00:00:00.0Z")); @@ -510,13 +497,12 @@ class InvoicingPipelineTest { .asBuilder() .setId(1) .setRegistrarId(registrar1.getRegistrarId()) - .setDomainHistoryRevisionId(domainHistory.getId()) .setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z")) .setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z")) .setOneTimeEventKey(oneTime.createVKey()) .setTargetId(domain12.getDomainName()) .setReason(Reason.RENEW) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build(); persistResource(cancellation); @@ -530,7 +516,7 @@ class InvoicingPipelineTest { .setRegistrarId(registrar1.getRegistrarId()) .setRecurrenceEndTime(END_OF_TIME) .setId(1) - .setParent(domainHistoryRecurring) + .setDomainHistory(domainHistoryRecurring) .setTargetId(domain13.getDomainName()) .setEventTime(DateTime.parse("2017-10-04T00:00:00.0Z")) .setReason(Reason.RENEW) @@ -541,7 +527,7 @@ class InvoicingPipelineTest { oneTimeRecurring = oneTimeRecurring .asBuilder() - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setCancellationMatchingBillingEvent(recurring) .setFlags(ImmutableSet.of(Flag.SYNTHETIC)) .setSyntheticCreationTime(DateTime.parse("2017-10-03T00:00:00.0Z")) .build(); @@ -552,18 +538,17 @@ class InvoicingPipelineTest { .asBuilder() .setId(2) .setRegistrarId(registrar1.getRegistrarId()) - .setDomainHistoryRevisionId(domainHistoryRecurring.getId()) .setEventTime(DateTime.parse("2017-10-05T00:00:00.0Z")) .setBillingTime(DateTime.parse("2017-10-04T00:00:00.0Z")) .setRecurringEventKey(recurring.createVKey()) .setTargetId(domain13.getDomainName()) .setReason(Reason.RENEW) - .setParent(domainHistoryRecurring) + .setDomainHistory(domainHistoryRecurring) .build(); persistResource(cancellationRecurring); } - private DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) { + private static DomainHistory persistDomainHistory(DomainBase domainBase, Registrar registrar) { DomainHistory domainHistory = new DomainHistory.Builder() .setType(HistoryEntry.Type.DOMAIN_RENEW) @@ -574,7 +559,7 @@ class InvoicingPipelineTest { return persistResource(domainHistory); } - private OneTime persistOneTimeBillingEvent( + private static OneTime persistOneTimeBillingEvent( int id, DomainBase domainBase, Registrar registrar, Reason reason, int years, Money money) { return persistOneTimeBillingEvent( id, @@ -587,7 +572,7 @@ class InvoicingPipelineTest { DateTime.parse("2017-10-04T00:00:00.0Z")); } - private OneTime persistOneTimeBillingEvent( + private static OneTime persistOneTimeBillingEvent( int id, DomainBase domainBase, Registrar registrar, @@ -597,7 +582,7 @@ class InvoicingPipelineTest { DateTime eventTime, DateTime billingTime, Flag... flags) { - google.registry.model.billing.BillingEvent.OneTime.Builder billingEventBuilder = + OneTime.Builder billingEventBuilder = new OneTime() .asBuilder() .setId(id) @@ -606,10 +591,9 @@ class InvoicingPipelineTest { .setRegistrarId(registrar.getRegistrarId()) .setReason(reason) .setTargetId(domainBase.getDomainName()) - .setDomainRepoId("REPO-ID") .setCost(money) .setFlags(Arrays.stream(flags).collect(toImmutableSet())) - .setParent(persistDomainHistory(domainBase, registrar)); + .setDomainHistory(persistDomainHistory(domainBase, registrar)); if (years > 0) { billingEventBuilder.setPeriodYears(years); @@ -620,6 +604,9 @@ class InvoicingPipelineTest { private static class ChangeDomainRepo extends PTransform, PCollection> { + + private static final long serialVersionUID = 2695033474967615250L; + @Override public PCollection expand(PCollection input) { return input.apply( diff --git a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java index 74a4e497f..3c296b847 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java @@ -544,7 +544,8 @@ class EppLifecycleDomainTest extends EppTestCase { .setCost(Money.parse("USD 100.00")) .setEventTime(createTime) .setBillingTime(createTime.plus(Registry.get("tld").getRenewGracePeriodLength())) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class)) + .setDomainHistory( + getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class)) .build(); // The expected one-time billing event, that should have an associated Cancellation. diff --git a/core/src/test/java/google/registry/flows/EppTestCase.java b/core/src/test/java/google/registry/flows/EppTestCase.java index f4100430a..55b23746d 100644 --- a/core/src/test/java/google/registry/flows/EppTestCase.java +++ b/core/src/test/java/google/registry/flows/EppTestCase.java @@ -28,7 +28,6 @@ import static javax.servlet.http.HttpServletResponse.SC_OK; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.net.MediaType; -import com.googlecode.objectify.Key; import google.registry.flows.EppTestComponent.FakesAndMocksModule; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Flag; @@ -327,7 +326,8 @@ public class EppTestCase { .setPeriodYears(2) .setEventTime(createTime) .setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength())) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class)) + .setDomainHistory( + getOnlyHistoryEntryOfType(domain, Type.DOMAIN_CREATE, DomainHistory.class)) .build(); } @@ -341,7 +341,7 @@ public class EppTestCase { .setPeriodYears(3) .setEventTime(renewTime) .setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength())) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class)) + .setDomainHistory(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class)) .build(); } @@ -375,7 +375,7 @@ public class EppTestCase { .setRegistrarId(domain.getCurrentSponsorRegistrarId()) .setEventTime(eventTime) .setRecurrenceEndTime(endTime) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); } @@ -386,10 +386,11 @@ public class EppTestCase { .setTargetId(domain.getDomainName()) .setRegistrarId(domain.getCurrentSponsorRegistrarId()) .setEventTime(deleteTime) - .setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel))) + .setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel)) .setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength())) .setReason(Reason.CREATE) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class)) + .setDomainHistory( + getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class)) .build(); } @@ -400,10 +401,11 @@ public class EppTestCase { .setTargetId(domain.getDomainName()) .setRegistrarId(domain.getCurrentSponsorRegistrarId()) .setEventTime(deleteTime) - .setOneTimeEventKey(VKey.from(findKeyToActualOneTimeBillingEvent(billingEventToCancel))) + .setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel)) .setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength())) .setReason(Reason.RENEW) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class)) + .setDomainHistory( + getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE, DomainHistory.class)) .build(); } @@ -412,11 +414,11 @@ public class EppTestCase { * *

This is used in the situation where we have created an expected billing event associated * with the domain's creation (which is passed as the parameter here), then need to locate the key - * to the actual billing event in Datastore that would be seen on a Cancellation billing event. + * to the actual billing event in the database that would be seen on a Cancellation billing event. * This is necessary because the ID will be different even though all the rest of the fields are * the same. */ - private static Key findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) { + private static VKey findKeyToActualOneTimeBillingEvent(OneTime expectedBillingEvent) { Optional actualCreateBillingEvent = loadAllOf(BillingEvent.OneTime.class).stream() .filter( @@ -425,6 +427,6 @@ public class EppTestCase { stripBillingEventId(b), stripBillingEventId(expectedBillingEvent))) .findFirst(); assertThat(actualCreateBillingEvent).isPresent(); - return Key.create(actualCreateBillingEvent.get()); + return actualCreateBillingEvent.get().createVKey(); } } diff --git a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java index 26439098b..6f8158e03 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java @@ -1440,7 +1440,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase recurringVKey = renewEvent.createVKey(); // Add an AUTO_RENEW grace period to the saved resource. diff --git a/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java b/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java index 3ff3db71a..74f4cabe6 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainPricingLogicTest.java @@ -112,7 +112,7 @@ public class DomainPricingLogicTest { Recurring recurring = persistResource( new BillingEvent.Recurring.Builder() - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setRegistrarId(domain.getCreationRegistrarId()) .setEventTime(DateTime.parse("1999-01-05T00:00:00Z")) .setFlags(ImmutableSet.of(AUTO_RENEW)) diff --git a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java index ef88b905d..863999e96 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainRenewFlowTest.java @@ -170,7 +170,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase builder.setParent(historyEntryTransferApproved).build()), + .map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()), Stream.of( transferBillingEvent, getLosingClientAutorenewEvent() @@ -281,7 +281,7 @@ class DomainTransferApproveFlowTest getGainingClientAutorenewEvent() .asBuilder() .setEventTime(domain.getRegistrationExpirationTime()) - .setParent(historyEntryTransferApproved) + .setDomainHistory(historyEntryTransferApproved) .build())) .toArray(BillingEvent[]::new)); // There should be a grace period for the new transfer billing event. @@ -308,7 +308,7 @@ class DomainTransferApproveFlowTest domain, Streams.concat( Arrays.stream(expectedCancellationBillingEvents) - .map(builder -> builder.setParent(historyEntryTransferApproved).build()), + .map(builder -> builder.setDomainHistory(historyEntryTransferApproved).build()), Stream.of( getLosingClientAutorenewEvent() .asBuilder() @@ -317,7 +317,7 @@ class DomainTransferApproveFlowTest getGainingClientAutorenewEvent() .asBuilder() .setEventTime(domain.getRegistrationExpirationTime()) - .setParent(historyEntryTransferApproved) + .setDomainHistory(historyEntryTransferApproved) .build())) .toArray(BillingEvent[]::new)); // There should be no grace period. diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferFlowTestCase.java b/core/src/test/java/google/registry/flows/domain/DomainTransferFlowTestCase.java index b4ab520d6..d114dfe18 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferFlowTestCase.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferFlowTestCase.java @@ -143,7 +143,7 @@ abstract class DomainTransferFlowTestCase .setRegistrarId("TheRegistrar") .setEventTime(REGISTRATION_EXPIRATION_TIME) .setRecurrenceEndTime(TRANSFER_EXPIRATION_TIME) - .setParent(historyEntryDomainCreate) + .setDomainHistory(historyEntryDomainCreate) .build(); } @@ -156,7 +156,7 @@ abstract class DomainTransferFlowTestCase .setRegistrarId("NewRegistrar") .setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME) .setRecurrenceEndTime(END_OF_TIME) - .setParent( + .setDomainHistory( getOnlyHistoryEntryOfType( domain, HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST, DomainHistory.class)) .build(); diff --git a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java index 675ddd2f4..75e84aff3 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainTransferRequestFlowTest.java @@ -262,7 +262,7 @@ class DomainTransferRequestFlowTest .setRegistrarId("NewRegistrar") .setCost(transferCost.orElse(Money.of(USD, 11))) .setPeriodYears(1) - .setParent(historyEntryTransferRequest) + .setDomainHistory(historyEntryTransferRequest) .build()); } else { // Superuser transfers with no bundled renewal have no transfer billing event. @@ -282,7 +282,7 @@ class DomainTransferRequestFlowTest // Construct extra billing events expected by the specific test. ImmutableSet extraBillingEvents = Stream.of(extraExpectedBillingEvents) - .map(builder -> builder.setParent(historyEntryTransferRequest).build()) + .map(builder -> builder.setDomainHistory(historyEntryTransferRequest).build()) .collect(toImmutableSet()); // Assert that the billing events we constructed above actually exist in Datastore. ImmutableSet expectedBillingEvents = diff --git a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java index 872835b04..1b5e1e0e0 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainUpdateFlowTest.java @@ -815,7 +815,7 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase> E commonInit(B builder) { + private static > E commonInit( + B builder) { return builder.setRegistrarId("TheRegistrar").setTargetId("foo.tld").build(); } @@ -207,7 +207,7 @@ public class BillingEventTest extends EntityTestCase { oneTime .asBuilder() .setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC)) - .setCancellationMatchingBillingEvent(recurring.createVKey()) + .setCancellationMatchingBillingEvent(recurring) .build()); assertThat(thrown) .hasMessageThat() @@ -248,11 +248,7 @@ public class BillingEventTest extends EntityTestCase { IllegalStateException thrown = assertThrows( IllegalStateException.class, - () -> - oneTime - .asBuilder() - .setCancellationMatchingBillingEvent(recurring.createVKey()) - .build()); + () -> oneTime.asBuilder().setCancellationMatchingBillingEvent(recurring).build()); assertThat(thrown) .hasMessageThat() .contains( @@ -266,7 +262,7 @@ public class BillingEventTest extends EntityTestCase { BillingEvent.Cancellation.forGracePeriod( GracePeriod.forBillingEvent(GracePeriodStatus.ADD, domain.getRepoId(), oneTime), domainHistory2.getModificationTime(), - Key.create(domainHistory2), + domainHistory2.getDomainHistoryId(), "foo.tld"); // Set ID to be the same to ignore for the purposes of comparison. assertThat(newCancellation.asBuilder().setId(cancellationOneTime.getId()).build()) @@ -284,7 +280,7 @@ public class BillingEventTest extends EntityTestCase { "TheRegistrar", recurring.createVKey()), domainHistory2.getModificationTime(), - Key.create(domainHistory2), + domainHistory2.getDomainHistoryId(), "foo.tld"); // Set ID to be the same to ignore for the purposes of comparison. assertThat(newCancellation.asBuilder().setId(cancellationRecurring.getId()).build()) @@ -304,7 +300,7 @@ public class BillingEventTest extends EntityTestCase { now.plusDays(1), "a registrar"), domainHistory.getModificationTime(), - Key.create(domainHistory), + domainHistory.getDomainHistoryId(), "foo.tld")); assertThat(thrown).hasMessageThat().contains("grace period without billing event"); } @@ -337,12 +333,6 @@ public class BillingEventTest extends EntityTestCase { assertThat(thrown).hasMessageThat().contains("exactly one billing event"); } - @Test - void testDeadCodeThatDeletedScrapCommandsReference() { - assertThat(recurring.getParentKey()).isEqualTo(Key.create(domainHistory)); - new BillingEvent.OneTime.Builder().setParent(Key.create(domainHistory)); - } - @Test void testReasonRequiringPeriodYears_missingPeriodYears_throwsException() { IllegalStateException thrown = @@ -357,7 +347,7 @@ public class BillingEventTest extends EntityTestCase { .setCost(Money.of(USD, 10)) .setRegistrarId("TheRegistrar") .setTargetId("example.tld") - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()); assertThat(thrown) .hasMessageThat() @@ -379,7 +369,7 @@ public class BillingEventTest extends EntityTestCase { .setCost(Money.of(USD, 10)) .setRegistrarId("TheRegistrar") .setTargetId("example.tld") - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()); assertThat(thrown) .hasMessageThat() @@ -397,7 +387,7 @@ public class BillingEventTest extends EntityTestCase { .setCost(Money.of(USD, 10)) .setRegistrarId("TheRegistrar") .setTargetId("example.tld") - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build(); } @@ -413,7 +403,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -429,7 +419,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -456,7 +446,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -479,7 +469,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -506,7 +496,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -529,7 +519,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -557,7 +547,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -585,7 +575,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -616,7 +606,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -648,7 +638,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -680,7 +670,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -711,7 +701,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -743,7 +733,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -775,7 +765,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -792,7 +782,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -808,7 +798,7 @@ public class BillingEventTest extends EntityTestCase { persistResource( commonInit( new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -826,7 +816,7 @@ public class BillingEventTest extends EntityTestCase { IllegalArgumentException.class, () -> new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -847,7 +837,7 @@ public class BillingEventTest extends EntityTestCase { IllegalArgumentException.class, () -> new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) @@ -869,7 +859,7 @@ public class BillingEventTest extends EntityTestCase { IllegalArgumentException.class, () -> new BillingEvent.Recurring.Builder() - .setParent(domainHistory) + .setDomainHistory(domainHistory) .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setReason(Reason.RENEW) .setEventTime(now.plusYears(1)) diff --git a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java index fcb337ce0..126ee2cdb 100644 --- a/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java +++ b/core/src/test/java/google/registry/model/common/ClassPathManagerTest.java @@ -17,10 +17,6 @@ package google.registry.model.common; import static com.google.common.truth.Truth.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import google.registry.model.billing.BillingEvent.Cancellation; -import google.registry.model.billing.BillingEvent.Modification; -import google.registry.model.billing.BillingEvent.OneTime; -import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory; @@ -44,7 +40,7 @@ import org.junit.jupiter.api.Test; public class ClassPathManagerTest { @Test void getClass_classInClassRegistry_returnsClass() throws ClassNotFoundException { - /** + /* * Class names are used in stringified vkeys, which can be present in task queues. Class name is * required to create a vkey. Changing these names could break task queue entries that are * present during a rollout. If you want to change the names of any of the classses supported in @@ -55,15 +51,11 @@ public class ClassPathManagerTest { */ assertThat(ClassPathManager.getClass("ForeignKeyContactIndex")) .isEqualTo(ForeignKeyContactIndex.class); - assertThat(ClassPathManager.getClass("Modification")).isEqualTo(Modification.class); assertThat(ClassPathManager.getClass("AllocationToken")).isEqualTo(AllocationToken.class); - assertThat(ClassPathManager.getClass("OneTime")).isEqualTo(OneTime.class); assertThat(ClassPathManager.getClass("RdeRevision")).isEqualTo(RdeRevision.class); assertThat(ClassPathManager.getClass("HostResource")).isEqualTo(HostResource.class); - assertThat(ClassPathManager.getClass("Recurring")).isEqualTo(Recurring.class); assertThat(ClassPathManager.getClass("Registrar")).isEqualTo(Registrar.class); assertThat(ClassPathManager.getClass("ContactResource")).isEqualTo(ContactResource.class); - assertThat(ClassPathManager.getClass("Cancellation")).isEqualTo(Cancellation.class); assertThat(ClassPathManager.getClass("GaeUserIdConverter")).isEqualTo(GaeUserIdConverter.class); assertThat(ClassPathManager.getClass("EppResourceIndexBucket")) .isEqualTo(EppResourceIndexBucket.class); @@ -85,7 +77,7 @@ public class ClassPathManagerTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, () -> ClassPathManager.getClass("DomainHistory")); - assertThat(thrown).hasMessageThat().contains("Class not found in class registry"); + assertThat(thrown).hasMessageThat().contains("Class DomainHistory not found in class registry"); } @Test @@ -94,12 +86,14 @@ public class ClassPathManagerTest { assertThrows( IllegalArgumentException.class, () -> ClassPathManager.getClassName(DomainHistory.class)); - assertThat(thrown).hasMessageThat().contains("Class not found in class name registry"); + assertThat(thrown) + .hasMessageThat() + .contains("Class DomainHistory not found in class name registry"); } @Test void getClassName() { - /** + /* * Class names are used in stringified vkeys, which can be present in task queues. Class name is * required to create a vkey. Changing these names could break task queue entries that are * present during a rollout. If you want to change the names of any of the classses supported in @@ -110,15 +104,11 @@ public class ClassPathManagerTest { */ assertThat(ClassPathManager.getClassName(ForeignKeyContactIndex.class)) .isEqualTo("ForeignKeyContactIndex"); - assertThat(ClassPathManager.getClassName(Modification.class)).isEqualTo("Modification"); assertThat(ClassPathManager.getClassName(AllocationToken.class)).isEqualTo("AllocationToken"); - assertThat(ClassPathManager.getClassName(OneTime.class)).isEqualTo("OneTime"); assertThat(ClassPathManager.getClassName(RdeRevision.class)).isEqualTo("RdeRevision"); assertThat(ClassPathManager.getClassName(HostResource.class)).isEqualTo("HostResource"); - assertThat(ClassPathManager.getClassName(Recurring.class)).isEqualTo("Recurring"); assertThat(ClassPathManager.getClassName(Registrar.class)).isEqualTo("Registrar"); assertThat(ClassPathManager.getClassName(ContactResource.class)).isEqualTo("ContactResource"); - assertThat(ClassPathManager.getClassName(Cancellation.class)).isEqualTo("Cancellation"); assertThat(ClassPathManager.getClassName(GaeUserIdConverter.class)) .isEqualTo("GaeUserIdConverter"); assertThat(ClassPathManager.getClassName(EppResourceIndexBucket.class)) diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java index 27a8277a5..a857040e4 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java @@ -36,6 +36,7 @@ import com.googlecode.objectify.Key; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Flag; import google.registry.model.billing.BillingEvent.Reason; +import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.common.EntityGroupRoot; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DesignatedContact.Type; @@ -409,11 +410,9 @@ public class DomainBaseSqlTest { .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setTargetId("example.com") .setRegistrarId("registrar1") - .setDomainRepoId("4-COM") - .setDomainHistoryRevisionId(1L) .setEventTime(DateTime.now(UTC).plusYears(1)) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); PollMessage.Autorenew autorenewPollMessage = new PollMessage.Autorenew.Builder() @@ -436,11 +435,10 @@ public class DomainBaseSqlTest { .setReason(Reason.SERVER_STATUS) .setTargetId("example.com") .setRegistrarId("registrar1") - .setDomainRepoId("4-COM") .setBillingTime(DateTime.now(UTC)) .setCost(Money.of(USD, 100)) .setEventTime(DateTime.now(UTC).plusYears(1)) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); DomainTransferData transferData = new DomainTransferData.Builder() @@ -536,11 +534,9 @@ public class DomainBaseSqlTest { .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setTargetId("example.com") .setRegistrarId("registrar1") - .setDomainRepoId("4-COM") - .setDomainHistoryRevisionId(1L) .setEventTime(DateTime.now(UTC).plusYears(1)) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); PollMessage.Autorenew autorenewPollMessage = new PollMessage.Autorenew.Builder() @@ -563,11 +559,10 @@ public class DomainBaseSqlTest { .setReason(Reason.SERVER_STATUS) .setTargetId("example.com") .setRegistrarId("registrar1") - .setDomainRepoId("4-COM") .setBillingTime(DateTime.now(UTC)) .setCost(Money.of(USD, 100)) .setEventTime(DateTime.now(UTC).plusYears(1)) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); DomainTransferData transferData = createPendingTransferData( @@ -599,8 +594,7 @@ public class DomainBaseSqlTest { domain = domain .asBuilder() - .setAutorenewBillingEvent( - createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId())) + .setAutorenewBillingEvent(Recurring.createVKey(billEvent.getId())) .setAutorenewPollMessage( createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()), autorenewPollMessage.getHistoryRevisionId()) diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java index 850759afa..da58d32d9 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java @@ -106,7 +106,7 @@ public class DomainBaseTest { domainHistory = persistResource( new DomainHistory.Builder() - .setDomainRepoId(domain.createVKey().getOfyKey().getName()) + .setDomainRepoId(domain.getRepoId()) .setModificationTime(fakeClock.nowUtc()) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setRegistrarId("TheRegistrar") @@ -118,11 +118,10 @@ public class DomainBaseTest { .setReason(Reason.SERVER_STATUS) .setTargetId(domain.getDomainName()) .setRegistrarId(domain.getCurrentSponsorRegistrarId()) - .setDomainRepoId(domain.getRepoId()) .setBillingTime(DateTime.now(UTC)) .setCost(Money.of(USD, 100)) .setEventTime(DateTime.now(UTC).plusYears(1)) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()) .createVKey(); DomainHistory historyEntry = @@ -145,11 +144,10 @@ public class DomainBaseTest { .setReason(Reason.SERVER_STATUS) .setTargetId("example.com") .setRegistrarId("registrar1") - .setDomainRepoId("4-COM") .setBillingTime(DateTime.now(UTC)) .setCost(Money.of(USD, 100)) .setEventTime(DateTime.now(UTC).plusYears(1)) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); oneTimeBillKey = oneTimeBill.createVKey(); BillingEvent.Recurring recurringBill = @@ -159,11 +157,9 @@ public class DomainBaseTest { .setFlags(ImmutableSet.of(Flag.AUTO_RENEW)) .setTargetId(domain.getDomainName()) .setRegistrarId(domain.getCurrentSponsorRegistrarId()) - .setDomainRepoId(domain.getRepoId()) - .setDomainHistoryRevisionId(historyEntry.getId()) .setEventTime(DateTime.now(UTC).plusYears(1)) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); insertInDb(historyEntry, oneTimeBill, recurringBill); recurringBillKey = recurringBill.createVKey(); @@ -427,7 +423,7 @@ public class DomainBaseTest { .plus(Registry.get("com").getTransferGracePeriodLength())) .setCost(Money.of(USD, 11)) .setPeriodYears(1) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build()); domain = domain diff --git a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java index ef68e3cea..ac635b95e 100644 --- a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java +++ b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java @@ -18,12 +18,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.joda.time.DateTimeZone.UTC; import static org.junit.jupiter.api.Assertions.assertThrows; -import com.googlecode.objectify.Key; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.billing.BillingEvent.Recurring; +import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.domain.rgp.GracePeriodStatus; -import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; import org.joda.money.CurrencyUnit; @@ -54,20 +53,12 @@ public class GracePeriodTest { .setBillingTime(now.plusDays(1)) .setRegistrarId("TheRegistrar") .setCost(Money.of(CurrencyUnit.USD, 42)) - .setParent( - Key.create(Key.create(DomainBase.class, "domain"), DomainHistory.class, 12345)) + .setDomainHistoryId(new DomainHistoryId("domain", 12345)) .setReason(Reason.CREATE) .setPeriodYears(1) .setTargetId("foo.google") .build(); - recurringKey = - VKey.create( - Recurring.class, - 12345L, - Key.create( - Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L), - Recurring.class, - 12345L)); + recurringKey = Recurring.createVKey(12345L); } @Test diff --git a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java index 16ca7f955..3f3e44067 100644 --- a/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java +++ b/core/src/test/java/google/registry/model/reporting/Spec11ThreatMatchTest.java @@ -60,7 +60,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { String domainRepoId = "4-TLD"; createTld("tld"); - /** Create a domain for the purpose of testing a foreign key reference in the Threat table. */ + // Create a domain for the purpose of testing a foreign key reference in the Threat table. domain = new DomainBase() .asBuilder() @@ -73,7 +73,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { .setContacts(ImmutableSet.of()) .build(); - /** Create a contact for the purpose of testing a foreign key reference in the Domain table. */ + // Create a contact for the purpose of testing a foreign key reference in the Domain table. registrantContact = new ContactResource.Builder() .setRepoId("contact_id") @@ -82,7 +82,7 @@ public final class Spec11ThreatMatchTest extends EntityTestCase { .setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID) .build(); - /** Create a host for the purpose of testing a foreign key reference in the Domain table. */ + // Create a host for the purpose of testing a foreign key reference in the Domain table. */ host = new HostResource.Builder() .setRepoId("host") diff --git a/core/src/test/java/google/registry/model/transfer/TransferDataTest.java b/core/src/test/java/google/registry/model/transfer/TransferDataTest.java index e6827407f..8b243b24f 100644 --- a/core/src/test/java/google/registry/model/transfer/TransferDataTest.java +++ b/core/src/test/java/google/registry/model/transfer/TransferDataTest.java @@ -20,6 +20,9 @@ import static org.joda.time.DateTimeZone.UTC; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; import google.registry.model.billing.BillingEvent; +import google.registry.model.billing.BillingEvent.Cancellation; +import google.registry.model.billing.BillingEvent.OneTime; +import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.domain.DomainBase; import google.registry.model.domain.Period; import google.registry.model.eppcommon.Trid; @@ -50,21 +53,9 @@ public class TransferDataTest { void beforeEach() { Key historyEntryKey = Key.create(Key.create(DomainBase.class, "4-TLD"), HistoryEntry.class, 1356L); - transferBillingEventKey = - VKey.create( - BillingEvent.OneTime.class, - 12345L, - Key.create(historyEntryKey, BillingEvent.OneTime.class, 12345L)); - otherServerApproveBillingEventKey = - VKey.create( - BillingEvent.Cancellation.class, - 2468L, - Key.create(historyEntryKey, BillingEvent.Cancellation.class, 2468L)); - recurringBillingEventKey = - VKey.create( - BillingEvent.Recurring.class, - 13579L, - Key.create(historyEntryKey, BillingEvent.Recurring.class, 13579L)); + transferBillingEventKey = OneTime.createVKey(12345L); + otherServerApproveBillingEventKey = Cancellation.createVKey(2468L); + recurringBillingEventKey = Recurring.createVKey(13579L); autorenewPollMessageKey = VKey.create( PollMessage.Autorenew.class, diff --git a/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java b/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java index 697994b3b..1571f7eb1 100644 --- a/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java +++ b/core/src/test/java/google/registry/model/translators/VKeyTranslatorFactoryTest.java @@ -19,9 +19,10 @@ import static google.registry.testing.DatabaseHelper.newDomainBase; import static google.registry.testing.DatabaseHelper.persistActiveContact; import com.googlecode.objectify.Key; -import google.registry.model.billing.BillingEvent; import google.registry.model.common.ClassPathManager; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; +import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.reporting.HistoryEntry; import google.registry.persistence.VKey; import google.registry.testing.AppEngineExtension; @@ -60,14 +61,12 @@ public class VKeyTranslatorFactoryTest { void testEntityWithAncestor() { Key domainKey = Key.create(DomainBase.class, "ROID-1"); Key historyEntryKey = Key.create(domainKey, HistoryEntry.class, 10L); - Key oneTimeKey = - Key.create(historyEntryKey, BillingEvent.OneTime.class, 200L); - VKey vkey = VKeyTranslatorFactory.createVKey(oneTimeKey); + VKey vkey = VKeyTranslatorFactory.createVKey(historyEntryKey); - assertThat(vkey.getKind()).isEqualTo(BillingEvent.OneTime.class); - assertThat(vkey.getOfyKey()).isEqualTo(oneTimeKey); - assertThat(vkey.getSqlKey()).isEqualTo(200L); + assertThat(vkey.getKind()).isEqualTo(DomainHistory.class); + assertThat(vkey.getOfyKey()).isEqualTo(historyEntryKey); + assertThat(vkey.getSqlKey()).isEqualTo(new DomainHistoryId("ROID-1", 10L)); } @Test diff --git a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java b/core/src/test/java/google/registry/persistence/BillingVKeyTest.java deleted file mode 100644 index 9efa9ec80..000000000 --- a/core/src/test/java/google/registry/persistence/BillingVKeyTest.java +++ /dev/null @@ -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 domainHistoryKey = - Key.create(Key.create(DomainBase.class, "domainRepoId"), HistoryEntry.class, 10L); - - Key oneTimeOfyKey = - Key.create(domainHistoryKey, BillingEvent.OneTime.class, 100L); - VKey oneTimeVKey = - VKey.create(BillingEvent.OneTime.class, 100L, oneTimeOfyKey); - - Key recurringOfyKey = - Key.create(domainHistoryKey, BillingEvent.Recurring.class, 200L); - VKey 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 parent = getCrossTldKey(); - - @Id @javax.persistence.Id String id = "id"; - - BillingEventVKey billingEventVKey; - - BillingRecurrenceVKey billingRecurrenceVKey; - - BillingVKeyTestEntity() {} - - BillingVKeyTestEntity( - VKey onetime, VKey recurring) { - this.billingEventVKey = BillingEventVKey.create(onetime); - this.billingRecurrenceVKey = BillingRecurrenceVKey.create(recurring); - } - - VKey getBillingEventVKey() { - return billingEventVKey.createVKey(); - } - - VKey getBillingRecurrenceVKey() { - return billingRecurrenceVKey.createVKey(); - } - - @Override - public VKey createVKey() { - return VKey.createSql(BillingVKeyTestEntity.class, id); - } - } -} diff --git a/core/src/test/java/google/registry/rde/DomainBaseToXjcConverterTest.java b/core/src/test/java/google/registry/rde/DomainBaseToXjcConverterTest.java index 6886d3c97..35df95bd8 100644 --- a/core/src/test/java/google/registry/rde/DomainBaseToXjcConverterTest.java +++ b/core/src/test/java/google/registry/rde/DomainBaseToXjcConverterTest.java @@ -234,7 +234,7 @@ public class DomainBaseToXjcConverterTest { .setPeriodYears(2) .setEventTime(DateTime.parse("1910-01-01T00:00:00Z")) .setBillingTime(DateTime.parse("1910-01-01T00:00:00Z")) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()); domain = domain @@ -295,7 +295,7 @@ public class DomainBaseToXjcConverterTest { .setPeriodYears(2) .setEventTime(DateTime.parse("1920-01-01T00:00:00Z")) .setBillingTime(DateTime.parse("1920-01-01T00:00:00Z")) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build())), GracePeriod.create( GracePeriodStatus.TRANSFER, @@ -319,7 +319,7 @@ public class DomainBaseToXjcConverterTest { .setRegistrarId("TheRegistrar") .setEventTime(END_OF_TIME) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()) .createVKey()) .setAutorenewPollMessage( @@ -349,7 +349,7 @@ public class DomainBaseToXjcConverterTest { .setRegistrarId("TheRegistrar") .setEventTime(END_OF_TIME) .setRecurrenceEndTime(END_OF_TIME) - .setParent(domainHistory) + .setDomainHistory(domainHistory) .build()) .createVKey()) .setServerApproveAutorenewPollMessage( diff --git a/core/src/test/java/google/registry/rde/RdeFixtures.java b/core/src/test/java/google/registry/rde/RdeFixtures.java index 4a1400a03..4d345ecd1 100644 --- a/core/src/test/java/google/registry/rde/RdeFixtures.java +++ b/core/src/test/java/google/registry/rde/RdeFixtures.java @@ -84,7 +84,7 @@ final class RdeFixtures { .setPeriodYears(2) .setEventTime(DateTime.parse("1990-01-01T00:00:00Z")) .setBillingTime(DateTime.parse("1990-01-01T00:00:00Z")) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build()); domain = domain @@ -138,7 +138,7 @@ final class RdeFixtures { .setPeriodYears(2) .setEventTime(DateTime.parse("1992-01-01T00:00:00Z")) .setBillingTime(DateTime.parse("1992-01-01T00:00:00Z")) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build())), GracePeriod.create( GracePeriodStatus.TRANSFER, @@ -162,7 +162,7 @@ final class RdeFixtures { .setRegistrarId("TheRegistrar") .setEventTime(END_OF_TIME) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build()) .createVKey()) .setAutorenewPollMessage( @@ -192,7 +192,7 @@ final class RdeFixtures { .setRegistrarId("TheRegistrar") .setEventTime(END_OF_TIME) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build()) .createVKey()) .setServerApproveAutorenewPollMessage( diff --git a/core/src/test/java/google/registry/testing/DatabaseHelper.java b/core/src/test/java/google/registry/testing/DatabaseHelper.java index 0f53b54ab..66b8679e2 100644 --- a/core/src/test/java/google/registry/testing/DatabaseHelper.java +++ b/core/src/test/java/google/registry/testing/DatabaseHelper.java @@ -349,7 +349,7 @@ public class DatabaseHelper { Recurring recurring = persistResource( new BillingEvent.Recurring.Builder() - .setParent(historyEntry) + .setDomainHistory(historyEntry) .setRenewalPrice(renewalPrice) .setRenewalPriceBehavior(renewalPriceBehavior) .setRegistrarId(domain.getCreationRegistrarId()) @@ -557,7 +557,7 @@ public class DatabaseHelper { .setRegistrarId("NewRegistrar") .setPeriodYears(1) .setCost(getDomainRenewCost(domain.getDomainName(), costLookupTime, 1)) - .setParent(historyEntry) + .setDomainHistory(historyEntry) .build(); } @@ -654,7 +654,7 @@ public class DatabaseHelper { .setRegistrarId("TheRegistrar") .setEventTime(expirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntryDomainCreate) + .setDomainHistory(historyEntryDomainCreate) .build()); PollMessage.Autorenew autorenewPollMessage = persistResource( @@ -701,7 +701,7 @@ public class DatabaseHelper { .setRegistrarId("NewRegistrar") .setEventTime(extendedRegistrationExpirationTime) .setRecurrenceEndTime(END_OF_TIME) - .setParent(historyEntryDomainTransfer) + .setDomainHistory(historyEntryDomainTransfer) .build()); PollMessage.Autorenew gainingClientAutorenewPollMessage = persistResource( diff --git a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java index b21b06d5b..fec327d29 100644 --- a/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java +++ b/core/src/test/java/google/registry/tools/DomainLockUtilsTest.java @@ -575,7 +575,7 @@ public final class DomainLockUtilsTest { .setCost(Registry.get(domain.getTld()).getRegistryLockOrUnlockBillingCost()) .setEventTime(clock.nowUtc()) .setBillingTime(clock.nowUtc()) - .setParent(entry) + .setDomainHistory(entry) .build()) .collect(Collectors.toSet()); DatabaseHelper.assertBillingEvents(expectedEvents); diff --git a/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java b/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java index 6c1561fb1..0fc69eff0 100644 --- a/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java +++ b/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java @@ -150,7 +150,8 @@ class EppLifecycleToolsTest extends EppTestCase { .setPeriodYears(4) .setEventTime(DateTime.parse("2000-06-07T00:00:00Z")) .setBillingTime(DateTime.parse("2000-06-12T00:00:00Z")) - .setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class)) + .setDomainHistory( + getOnlyHistoryEntryOfType(domain, Type.DOMAIN_RENEW, DomainHistory.class)) .build(); assertBillingEventsForResource( diff --git a/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java b/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java index f0f05a7fc..a60529d1d 100644 --- a/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/UnrenewDomainCommandTest.java @@ -134,7 +134,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase 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 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 parent; - com.googlecode.objectify.Key eventRef; - google.registry.model.billing.BillingEvent$Reason reason; - java.lang.String clientId; - java.lang.String description; - java.lang.String targetId; - java.util.Set 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 parent; - google.registry.model.billing.BillingEvent$Reason reason; - google.registry.persistence.VKey cancellationMatchingBillingEvent; - google.registry.persistence.VKey allocationToken; - java.lang.Integer periodYears; - java.lang.String clientId; - java.lang.String targetId; - java.util.Set 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 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 flags; - org.joda.money.Money renewalPrice; - org.joda.time.DateTime eventTime; - org.joda.time.DateTime recurrenceEndTime; -} -enum google.registry.model.billing.BillingEvent$RenewalPriceBehavior { - DEFAULT; - NONPREMIUM; - SPECIFIED; -} class google.registry.model.common.EntityGroupRoot { @Id java.lang.String id; } @@ -80,9 +5,6 @@ class google.registry.model.common.GaeUserIdConverter { @Id long id; com.google.appengine.api.users.User user; } -class google.registry.model.common.TimeOfYear { - java.lang.String timeString; -} class google.registry.model.contact.ContactAddress { java.lang.String city; java.lang.String countryCode; @@ -183,7 +105,6 @@ class google.registry.model.domain.DomainBase { google.registry.model.domain.DomainAuthInfo authInfo; google.registry.model.domain.launch.LaunchNotice launchNotice; google.registry.model.transfer.DomainTransferData transferData; - google.registry.persistence.VKey autorenewBillingEvent; google.registry.persistence.VKey adminContact; google.registry.persistence.VKey billingContact; google.registry.persistence.VKey registrantContact; @@ -213,7 +134,6 @@ class google.registry.model.domain.DomainContent { google.registry.model.domain.DomainAuthInfo authInfo; google.registry.model.domain.launch.LaunchNotice launchNotice; google.registry.model.transfer.DomainTransferData transferData; - google.registry.persistence.VKey autorenewBillingEvent; google.registry.persistence.VKey adminContact; google.registry.persistence.VKey billingContact; google.registry.persistence.VKey registrantContact; @@ -259,16 +179,12 @@ class google.registry.model.domain.DomainHistory { } class google.registry.model.domain.GracePeriod { google.registry.model.domain.rgp.GracePeriodStatus type; - google.registry.persistence.VKey billingEventOneTime; - google.registry.persistence.VKey billingEventRecurring; java.lang.String clientId; long gracePeriodId; org.joda.time.DateTime expirationTime; } class google.registry.model.domain.GracePeriod$GracePeriodHistory { google.registry.model.domain.rgp.GracePeriodStatus type; - google.registry.persistence.VKey billingEventOneTime; - google.registry.persistence.VKey billingEventRecurring; java.lang.Long domainHistoryRevisionId; java.lang.Long gracePeriodHistoryRevisionId; java.lang.String clientId; @@ -319,7 +235,6 @@ class google.registry.model.domain.token.AllocationToken { @Id java.lang.String token; boolean discountPremiums; double discountFraction; - google.registry.model.billing.BillingEvent$RenewalPriceBehavior renewalPriceBehavior; google.registry.model.common.TimedTransitionProperty tokenStatusTransitions; google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior; google.registry.model.domain.token.AllocationToken$TokenType tokenType; @@ -626,8 +541,6 @@ class google.registry.model.transfer.DomainTransferData { google.registry.model.domain.Period transferPeriod; google.registry.model.eppcommon.Trid transferRequestTrid; google.registry.model.transfer.TransferStatus transferStatus; - google.registry.persistence.VKey serverApproveBillingEvent; - google.registry.persistence.VKey serverApproveAutorenewEvent; google.registry.persistence.VKey serverApproveAutorenewPollMessage; java.lang.String gainingClientId; java.lang.String losingClientId; @@ -643,16 +556,6 @@ enum google.registry.model.transfer.TransferStatus { SERVER_APPROVED; SERVER_CANCELLED; } -class google.registry.persistence.BillingVKey$BillingEventVKey { - java.lang.Long billingId; - java.lang.Long historyRevisionId; - java.lang.String repoId; -} -class google.registry.persistence.BillingVKey$BillingRecurrenceVKey { - java.lang.Long billingId; - java.lang.Long historyRevisionId; - java.lang.String repoId; -} class google.registry.persistence.DomainHistoryVKey { java.lang.Long historyRevisionId; java.lang.String repoId; diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index 402365a75..86515b994 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -42,11 +42,7 @@ domain_name text not null, billing_time timestamptz, billing_event_id int8, - billing_event_history_id int8, - billing_event_domain_repo_id text, billing_recurrence_id int8, - billing_recurrence_history_id int8, - billing_recurrence_domain_repo_id text, primary key (billing_cancellation_id) ); diff --git a/processor/src/main/java/google/registry/processors/LongVKeyProcessor.java b/processor/src/main/java/google/registry/processors/LongVKeyProcessor.java index c3f3c762c..52b904fdf 100644 --- a/processor/src/main/java/google/registry/processors/LongVKeyProcessor.java +++ b/processor/src/main/java/google/registry/processors/LongVKeyProcessor.java @@ -23,7 +23,7 @@ import javax.lang.model.SourceVersion; @SupportedSourceVersion(SourceVersion.RELEASE_8) public class LongVKeyProcessor extends AbstractVKeyProcessor { - private static final String ANNOTATION_SIMPLE_NAME = "WithStringVKey"; + private static final String ANNOTATION_SIMPLE_NAME = "WithLongVKey"; @Override Class getSqlColumnType() {