Begin writing AUTO_RENEW flag alongside reason

Backfill [] to follow, and the Recurring billing events will eventually be replicated as OneTime via a regular job.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119883652
This commit is contained in:
ctingue 2016-04-14 13:19:27 -07:00 committed by Justine Tunney
parent fbe076b5da
commit 4112bca925
18 changed files with 87 additions and 36 deletions

View file

@ -19,9 +19,11 @@ import static com.google.domain.registry.util.DateTimeUtils.END_OF_TIME;
import static com.google.domain.registry.util.DateTimeUtils.leapSafeAddYears;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.dns.DnsQueue;
import com.google.domain.registry.flows.EppException;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.DomainResource.Builder;
@ -59,7 +61,8 @@ public abstract class DomainCreateOrAllocateFlow
DateTime registrationExpirationTime = leapSafeAddYears(now, command.getPeriod().getValue());
// Create a new autorenew billing event and poll message starting at the expiration time.
BillingEvent.Recurring autorenewEvent = new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(getClientId())
.setEventTime(registrationExpirationTime)

View file

@ -49,6 +49,7 @@ import com.google.domain.registry.flows.EppException.StatusProhibitsOperationExc
import com.google.domain.registry.flows.EppException.UnimplementedOptionException;
import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.domain.DesignatedContact;
@ -412,7 +413,8 @@ public class DomainFlowUtils {
*/
static BillingEvent.Recurring.Builder newAutorenewBillingEvent(DomainResource domain) {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId(domain.getCurrentSponsorClientId())
.setEventTime(domain.getRegistrationExpirationTime());

View file

@ -27,6 +27,7 @@ import com.google.common.collect.Iterables;
import com.google.domain.registry.flows.EppException;
import com.google.domain.registry.flows.ResourceTransferApproveFlow;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainCommand.Transfer;
import com.google.domain.registry.model.domain.DomainResource;
@ -104,7 +105,8 @@ public class DomainTransferApproveFlow extends
now, existingResource.getRegistrationExpirationTime(), extraYears);
// Create a new autorenew event starting at the expiration time.
BillingEvent.Recurring autorenewEvent = new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(gainingClientId)
.setEventTime(newExpirationTime)

View file

@ -25,9 +25,11 @@ import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.util.DateTimeUtils.END_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.flows.EppException;
import com.google.domain.registry.flows.ResourceTransferRequestFlow;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainCommand.Transfer;
import com.google.domain.registry.model.domain.DomainResource;
@ -126,7 +128,8 @@ public class DomainTransferRequestFlow
existingResource.getRegistrationExpirationTime(),
command.getPeriod().getValue());
gainingClientAutorenewEvent = new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(gainingClient.getId())
.setEventTime(newExpirationTime)
@ -196,7 +199,8 @@ public class DomainTransferRequestFlow
if (automaticTransferTime.isAfter(expirationTime) && automaticTransferTime.isBefore(
expirationTime.plus(registry.getAutoRenewGracePeriodLength()))) {
BillingEvent.Cancellation autorenewCancellation = new BillingEvent.Cancellation.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(targetId)
.setClientId(existingResource.getCurrentSponsorClientId())
.setEventTime(automaticTransferTime)

View file

@ -19,6 +19,7 @@ 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 com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static com.google.domain.registry.util.CollectionUtils.union;
import static com.google.domain.registry.util.DateTimeUtils.END_OF_TIME;
import com.google.common.base.Optional;
@ -39,6 +40,7 @@ import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.Parent;
import com.googlecode.objectify.condition.IfNull;
@ -282,6 +284,15 @@ public abstract class BillingEvent extends ImmutableObject
@Entity
public static class Recurring extends BillingEvent {
// TODO(b/27777398): Remove after migration is complete and Reason.AUTO_RENEW is removed.
@OnLoad
void setAutorenewFlag() {
if (Reason.AUTO_RENEW.equals(reason)) {
reason = Reason.RENEW;
flags = union(getFlags(), Flag.AUTO_RENEW);
}
}
/**
* The billing event recurs every year between {@link #eventTime} and this time on the
* [month, day, time] specified in {@link #recurrenceTimeOfYear}.
@ -378,7 +389,7 @@ public abstract class BillingEvent extends ImmutableObject
static final ImmutableMap<GracePeriodStatus, Reason> GRACE_PERIOD_TO_REASON =
ImmutableMap.of(
GracePeriodStatus.ADD, Reason.CREATE,
GracePeriodStatus.AUTO_RENEW, Reason.AUTO_RENEW,
GracePeriodStatus.AUTO_RENEW, Reason.RENEW,
GracePeriodStatus.RENEW, Reason.RENEW,
GracePeriodStatus.TRANSFER, Reason.TRANSFER);

View file

@ -197,7 +197,8 @@ public class DomainAllocateFlowTest
assertBillingEvents(
createBillingEvent,
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domainName)
.setClientId(CLIENT_ID)
.setEventTime(domain.getRegistrationExpirationTime())

View file

@ -97,6 +97,7 @@ import com.google.domain.registry.flows.domain.DomainFlowUtils.TooManyNameserver
import com.google.domain.registry.flows.domain.DomainFlowUtils.TrailingDashException;
import com.google.domain.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.GracePeriod;
@ -189,7 +190,8 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
assertBillingEvents(
createBillingEvent,
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setClientId("TheRegistrar")
.setEventTime(domain.getRegistrationExpirationTime())

View file

@ -51,6 +51,7 @@ import com.google.domain.registry.flows.SingleResourceFlow.ResourceStatusProhibi
import com.google.domain.registry.flows.domain.DomainDeleteFlow.DomainToDeleteHasHostsException;
import com.google.domain.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.domain.DomainResource;
@ -196,7 +197,8 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
private BillingEvent.Recurring.Builder createAutorenewBillingEvent(String clientId) {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.tld")
.setClientId(clientId)
.setEventTime(A_MONTH_FROM_NOW)

View file

@ -49,6 +49,7 @@ import com.google.domain.registry.flows.domain.DomainRenewFlow.DomainHasPendingT
import com.google.domain.registry.flows.domain.DomainRenewFlow.ExceedsMaxRegistrationYearsException;
import com.google.domain.registry.flows.domain.DomainRenewFlow.IncorrectCurrentExpirationDateException;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.GracePeriod;
@ -91,7 +92,8 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
.build());
BillingEvent.Recurring autorenewEvent = persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setClientId("TheRegistrar")
.setEventTime(expirationTime)
@ -145,7 +147,8 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
assertBillingEvents(
renewBillingEvent,
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setClientId("TheRegistrar")
.setEventTime(expirationTime)
@ -153,7 +156,8 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
.setParent(getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_CREATE))
.build(),
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(getUniqueIdFromCommand())
.setClientId("TheRegistrar")
.setEventTime(domain.getRegistrationExpirationTime())

View file

@ -49,6 +49,7 @@ import com.google.domain.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAtt
import com.google.domain.registry.flows.domain.DomainRestoreRequestFlow.DomainNotEligibleForRestoreException;
import com.google.domain.registry.flows.domain.DomainRestoreRequestFlow.RestoreCommandIncludesChangesException;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.GracePeriod;
@ -148,7 +149,8 @@ public class DomainRestoreRequestFlowTest extends
// autorenew event.
assertBillingEvents(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.tld")
.setClientId("TheRegistrar")
.setEventTime(domain.getRegistrationExpirationTime())

View file

@ -367,7 +367,7 @@ public class DomainTransferApproveFlowTest
2,
// Expect the grace period for autorenew to be cancelled.
new BillingEvent.Cancellation.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setTargetId("example.tld")
.setClientId("TheRegistrar")
.setEventTime(clock.nowUtc()) // The cancellation happens at the moment of transfer.

View file

@ -31,6 +31,7 @@ import com.google.domain.registry.flows.Flow;
import com.google.domain.registry.flows.ResourceFlowTestCase;
import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.domain.DesignatedContact;
@ -144,7 +145,8 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
.build());
BillingEvent.Recurring autorenewEvent = persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(label + "." + tld)
.setClientId("TheRegistrar")
.setEventTime(REGISTRATION_EXPIRATION_TIME)
@ -190,7 +192,8 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
/** Get the autorenew event that the losing client will have after a SERVER_APPROVED transfer. */
protected BillingEvent.Recurring getLosingClientAutorenewEvent() {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId("TheRegistrar")
.setEventTime(REGISTRATION_EXPIRATION_TIME)
@ -202,7 +205,8 @@ public class DomainTransferFlowTestCase<F extends Flow, R extends EppResource>
/** Get the autorenew event that the gaining client will have after a SERVER_APPROVED transfer. */
protected BillingEvent.Recurring getGainingClientAutorenewEvent() {
return new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId("NewRegistrar")
.setEventTime(EXTENDED_REGISTRATION_EXPIRATION_TIME)

View file

@ -56,6 +56,7 @@ import com.google.domain.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAtt
import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Cancellation.Builder;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactAuthInfo;
import com.google.domain.registry.model.domain.DomainAuthInfo;
@ -399,7 +400,8 @@ public class DomainTransferRequestFlowTest
"domain_transfer_request_response_2_years.xml",
clock.nowUtc().plusDays(1).plusYears(2),
new BillingEvent.Cancellation.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.tld")
.setClientId("TheRegistrar")
// The cancellation happens at the moment of transfer.

View file

@ -25,6 +25,7 @@ import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.model.EntityTestCase;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.GracePeriod;
@ -85,7 +86,8 @@ public class BillingEventTest extends EntityTestCase {
recurring = persistResource(commonInit(
new BillingEvent.Recurring.Builder()
.setParent(historyEntry)
.setReason(Reason.AUTO_RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setReason(Reason.RENEW)
.setEventTime(now.plusYears(1))
.setRecurrenceEndTime(END_OF_TIME)));
cancellationOneTime = persistResource(commonInit(
@ -98,7 +100,7 @@ public class BillingEventTest extends EntityTestCase {
cancellationRecurring = persistResource(commonInit(
new BillingEvent.Cancellation.Builder()
.setParent(historyEntry2)
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setEventTime(now.plusDays(1))
.setBillingTime(now.plusYears(1).plusDays(45))
.setRecurringEventRef(Ref.create(recurring))));

View file

@ -23,6 +23,7 @@ import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableSet;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.poll.PollMessage;
@ -75,7 +76,8 @@ public class TransferDataTest {
recurringBillingEvent = persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setClientId("TheRegistrar")
.setTargetId("foo.tld")
.setEventTime(now)

View file

@ -32,6 +32,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactAddress;
import com.google.domain.registry.model.contact.ContactPhoneNumber;
@ -309,7 +310,8 @@ public class DomainResourceToXjcConverterTest {
.setAutorenewBillingEvent(
Ref.create(persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("lol")
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
@ -335,13 +337,14 @@ public class DomainResourceToXjcConverterTest {
.setServerApproveAutorenewEvent(
Ref.create(persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.setServerApproveAutorenewPollMessage(Ref.create(persistResource(
new Autorenew.Builder()
.setTargetId("example.xn--q9jyb4c")

View file

@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactAddress;
import com.google.domain.registry.model.contact.ContactPhoneNumber;
@ -133,7 +134,8 @@ final class RdeFixtures {
.setAutorenewBillingEvent(
Ref.create(persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId(tld)
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
@ -159,13 +161,14 @@ final class RdeFixtures {
.setServerApproveAutorenewEvent(
Ref.create(persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.setClientId("TheRegistrar")
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.setServerApproveAutorenewPollMessage(Ref.create(persistResource(
new Autorenew.Builder()
.setTargetId("example." + tld)

View file

@ -50,6 +50,7 @@ import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.EppResource.ForeignKeyedEppResource;
import com.google.domain.registry.model.ImmutableObject;
import com.google.domain.registry.model.billing.BillingEvent;
import com.google.domain.registry.model.billing.BillingEvent.Flag;
import com.google.domain.registry.model.billing.BillingEvent.Reason;
import com.google.domain.registry.model.contact.ContactAuthInfo;
import com.google.domain.registry.model.contact.ContactResource;
@ -501,7 +502,8 @@ public class DatastoreHelper {
extendedRegistrationYears));
BillingEvent.Recurring gainingClientAutorenewEvent = persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.AUTO_RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setReason(Reason.RENEW)
.setTargetId(domain.getFullyQualifiedDomainName())
.setClientId("NewRegistrar")
.setEventTime(extendedRegistrationExpirationTime)