mirror of
https://github.com/google/nomulus.git
synced 2025-07-05 02:33:22 +02:00
Remove ofy support from auto timestamp classes (#1708)
Also remove the use of ZonedDateTime, as joda DateTime can already be persisted to SQL with an existing converted.
This commit is contained in:
parent
e0a0030837
commit
badfb29ce1
22 changed files with 100 additions and 512 deletions
|
@ -19,15 +19,13 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import java.time.ZoneId;
|
import java.sql.Date;
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
|
|
||||||
/** Utilities methods and constants related to Joda {@link DateTime} objects. */
|
/** Utilities methods and constants related to Joda {@link DateTime} objects. */
|
||||||
public class DateTimeUtils {
|
public abstract class DateTimeUtils {
|
||||||
|
|
||||||
/** The start of the epoch, in a convenient constant. */
|
/** The start of the epoch, in a convenient constant. */
|
||||||
public static final DateTime START_OF_TIME = new DateTime(0, DateTimeZone.UTC);
|
public static final DateTime START_OF_TIME = new DateTime(0, DateTimeZone.UTC);
|
||||||
|
@ -91,39 +89,11 @@ public class DateTimeUtils {
|
||||||
return years == 0 ? now : now.minusYears(1).minusYears(years - 1);
|
return years == 0 ? now : now.minusYears(1).minusYears(years - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Date toSqlDate(LocalDate localDate) {
|
||||||
* Converts a Joda {@link DateTime} object to an equivalent java.time {@link ZonedDateTime}
|
return new Date(localDate.toDateTimeAtStartOfDay().getMillis());
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
public static ZonedDateTime toZonedDateTime(DateTime dateTime) {
|
|
||||||
java.time.Instant instant = java.time.Instant.ofEpochMilli(dateTime.getMillis());
|
|
||||||
return ZonedDateTime.ofInstant(instant, ZoneId.of(dateTime.getZone().getID()).normalized());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static LocalDate toLocalDate(Date date) {
|
||||||
* Converts a Joda {@link DateTime} object to an equivalent java.time {@link ZonedDateTime}
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
public static ZonedDateTime toZonedDateTime(DateTime dateTime, ZoneId zoneId) {
|
|
||||||
java.time.Instant instant = java.time.Instant.ofEpochMilli(dateTime.getMillis());
|
|
||||||
return ZonedDateTime.ofInstant(instant, zoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a java.time {@link ZonedDateTime} object to an equivalent Joda {@link DateTime}
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
public static DateTime toJodaDateTime(ZonedDateTime zonedDateTime) {
|
|
||||||
return new DateTime(
|
|
||||||
zonedDateTime.toInstant().toEpochMilli(),
|
|
||||||
DateTimeZone.forTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone())));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static java.sql.Date toSqlDate(LocalDate localDate) {
|
|
||||||
return new java.sql.Date(localDate.toDateTimeAtStartOfDay().getMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LocalDate toLocalDate(java.sql.Date date) {
|
|
||||||
return new LocalDate(date.getTime(), DateTimeZone.UTC);
|
return new LocalDate(date.getTime(), DateTimeZone.UTC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,16 +28,16 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.avro.generic.GenericRecord;
|
import org.apache.avro.generic.GenericRecord;
|
||||||
import org.apache.beam.sdk.coders.AtomicCoder;
|
import org.apache.beam.sdk.coders.AtomicCoder;
|
||||||
import org.apache.beam.sdk.coders.Coder;
|
import org.apache.beam.sdk.coders.Coder;
|
||||||
import org.apache.beam.sdk.coders.StringUtf8Coder;
|
import org.apache.beam.sdk.coders.StringUtf8Coder;
|
||||||
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
import org.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}.
|
* A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}.
|
||||||
|
@ -51,7 +51,7 @@ import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||||
public abstract class BillingEvent implements Serializable {
|
public abstract class BillingEvent implements Serializable {
|
||||||
|
|
||||||
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss zzz");
|
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz");
|
||||||
|
|
||||||
/** The amount we multiply the price for sunrise creates. This is currently a 15% discount. */
|
/** 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 double SUNRISE_DISCOUNT_PRICE_MODIFIER = 0.85;
|
||||||
|
@ -77,10 +77,10 @@ public abstract class BillingEvent implements Serializable {
|
||||||
abstract long id();
|
abstract long id();
|
||||||
|
|
||||||
/** Returns the UTC DateTime this event becomes billable. */
|
/** Returns the UTC DateTime this event becomes billable. */
|
||||||
abstract ZonedDateTime billingTime();
|
abstract DateTime billingTime();
|
||||||
|
|
||||||
/** Returns the UTC DateTime this event was generated. */
|
/** Returns the UTC DateTime this event was generated. */
|
||||||
abstract ZonedDateTime eventTime();
|
abstract DateTime eventTime();
|
||||||
|
|
||||||
/** Returns the billed registrar's name. */
|
/** Returns the billed registrar's name. */
|
||||||
abstract String registrarId();
|
abstract String registrarId();
|
||||||
|
@ -132,10 +132,8 @@ public abstract class BillingEvent implements Serializable {
|
||||||
// Objects, which contain a string representation of their underlying types.
|
// Objects, which contain a string representation of their underlying types.
|
||||||
Long.parseLong(extractField(record, "id")),
|
Long.parseLong(extractField(record, "id")),
|
||||||
// Bigquery provides UNIX timestamps with microsecond precision.
|
// Bigquery provides UNIX timestamps with microsecond precision.
|
||||||
Instant.ofEpochMilli(Long.parseLong(extractField(record, "billingTime")) / 1000)
|
new DateTime(Long.parseLong(extractField(record, "billingTime")) / 1000, DateTimeZone.UTC),
|
||||||
.atZone(ZoneId.of("UTC")),
|
new DateTime(Long.parseLong(extractField(record, "eventTime")) / 1000, DateTimeZone.UTC),
|
||||||
Instant.ofEpochMilli(Long.parseLong(extractField(record, "eventTime")) / 1000)
|
|
||||||
.atZone(ZoneId.of("UTC")),
|
|
||||||
extractField(record, "registrarId"),
|
extractField(record, "registrarId"),
|
||||||
extractField(record, "billingId"),
|
extractField(record, "billingId"),
|
||||||
extractField(record, "poNumber"),
|
extractField(record, "poNumber"),
|
||||||
|
@ -180,8 +178,8 @@ public abstract class BillingEvent implements Serializable {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static BillingEvent create(
|
static BillingEvent create(
|
||||||
long id,
|
long id,
|
||||||
ZonedDateTime billingTime,
|
DateTime billingTime,
|
||||||
ZonedDateTime eventTime,
|
DateTime eventTime,
|
||||||
String registrarId,
|
String registrarId,
|
||||||
String billingId,
|
String billingId,
|
||||||
String poNumber,
|
String poNumber,
|
||||||
|
@ -231,8 +229,8 @@ public abstract class BillingEvent implements Serializable {
|
||||||
.join(
|
.join(
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
id(),
|
id(),
|
||||||
DATE_TIME_FORMATTER.format(billingTime()),
|
DATE_TIME_FORMATTER.print(billingTime()),
|
||||||
DATE_TIME_FORMATTER.format(eventTime()),
|
DATE_TIME_FORMATTER.print(eventTime()),
|
||||||
registrarId(),
|
registrarId(),
|
||||||
billingId(),
|
billingId(),
|
||||||
poNumber(),
|
poNumber(),
|
||||||
|
|
|
@ -27,14 +27,12 @@ import google.registry.model.billing.BillingEvent.Flag;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||||
import google.registry.reporting.billing.BillingModule;
|
import google.registry.reporting.billing.BillingModule;
|
||||||
import google.registry.util.DateTimeUtils;
|
|
||||||
import google.registry.util.DomainNameUtils;
|
import google.registry.util.DomainNameUtils;
|
||||||
import google.registry.util.SqlTemplate;
|
import google.registry.util.SqlTemplate;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.YearMonth;
|
import java.time.YearMonth;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -123,8 +121,8 @@ public class InvoicingPipeline implements Serializable {
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
oneTime.getId(),
|
oneTime.getId(),
|
||||||
DateTimeUtils.toZonedDateTime(oneTime.getBillingTime(), ZoneId.of("UTC")),
|
oneTime.getBillingTime(),
|
||||||
DateTimeUtils.toZonedDateTime(oneTime.getEventTime(), ZoneId.of("UTC")),
|
oneTime.getEventTime(),
|
||||||
registrar.getRegistrarId(),
|
registrar.getRegistrarId(),
|
||||||
registrar.getBillingAccountMap().get(currency),
|
registrar.getBillingAccountMap().get(currency),
|
||||||
registrar.getPoNumber().orElse(""),
|
registrar.getPoNumber().orElse(""),
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
import google.registry.util.PreconditionsUtils;
|
import google.registry.util.PreconditionsUtils;
|
||||||
import javax.persistence.Access;
|
import javax.persistence.Access;
|
||||||
import javax.persistence.AccessType;
|
import javax.persistence.AccessType;
|
||||||
|
@ -44,6 +45,7 @@ public abstract class BackupGroupRoot extends ImmutableObject implements UnsafeS
|
||||||
// require an unnecessary non-private setter method.
|
// require an unnecessary non-private setter method.
|
||||||
@Access(AccessType.FIELD)
|
@Access(AccessType.FIELD)
|
||||||
@AttributeOverride(name = "lastUpdateTime", column = @Column(name = "updateTimestamp"))
|
@AttributeOverride(name = "lastUpdateTime", column = @Column(name = "updateTimestamp"))
|
||||||
|
@Ignore
|
||||||
UpdateAutoTimestamp updateTimestamp = UpdateAutoTimestamp.create(null);
|
UpdateAutoTimestamp updateTimestamp = UpdateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** Get the {@link UpdateAutoTimestamp} for this entity. */
|
/** Get the {@link UpdateAutoTimestamp} for this entity. */
|
||||||
|
|
|
@ -10,73 +10,43 @@
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the Licenseschema..
|
||||||
|
|
||||||
package google.registry.model;
|
package google.registry.model;
|
||||||
|
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||||
|
|
||||||
import com.googlecode.objectify.annotation.Ignore;
|
|
||||||
import com.googlecode.objectify.annotation.OnLoad;
|
|
||||||
import google.registry.model.translators.CreateAutoTimestampTranslatorFactory;
|
|
||||||
import google.registry.util.DateTimeUtils;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.PostLoad;
|
|
||||||
import javax.persistence.PrePersist;
|
import javax.persistence.PrePersist;
|
||||||
import javax.persistence.PreUpdate;
|
import javax.persistence.PreUpdate;
|
||||||
import javax.persistence.Transient;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/** A timestamp that auto-updates when first saved to Datastore. */
|
||||||
* A timestamp that auto-updates when first saved to Datastore.
|
|
||||||
*
|
|
||||||
* @see CreateAutoTimestampTranslatorFactory
|
|
||||||
*/
|
|
||||||
@Embeddable
|
@Embeddable
|
||||||
public class CreateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
public class CreateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||||
|
|
||||||
@Transient DateTime timestamp;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Ignore
|
DateTime creationTime;
|
||||||
ZonedDateTime creationTime;
|
|
||||||
|
|
||||||
@PrePersist
|
@PrePersist
|
||||||
@PreUpdate
|
@PreUpdate
|
||||||
void setTimestamp() {
|
void setTimestamp() {
|
||||||
if (creationTime == null) {
|
if (creationTime == null) {
|
||||||
timestamp = jpaTm().getTransactionTime();
|
creationTime = jpaTm().getTransactionTime();
|
||||||
creationTime = DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnLoad
|
|
||||||
void onLoad() {
|
|
||||||
if (timestamp != null) {
|
|
||||||
creationTime = DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostLoad
|
|
||||||
void postLoad() {
|
|
||||||
if (creationTime != null) {
|
|
||||||
timestamp = DateTimeUtils.toJodaDateTime(creationTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the timestamp. */
|
/** Returns the timestamp. */
|
||||||
@Nullable
|
@Nullable
|
||||||
public DateTime getTimestamp() {
|
public DateTime getTimestamp() {
|
||||||
return timestamp;
|
return creationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CreateAutoTimestamp create(@Nullable DateTime timestamp) {
|
public static CreateAutoTimestamp create(@Nullable DateTime creationTime) {
|
||||||
CreateAutoTimestamp instance = new CreateAutoTimestamp();
|
CreateAutoTimestamp instance = new CreateAutoTimestamp();
|
||||||
instance.timestamp = timestamp;
|
instance.creationTime = creationTime;
|
||||||
instance.creationTime = (timestamp == null) ? null : DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
import com.googlecode.objectify.annotation.Index;
|
import com.googlecode.objectify.annotation.Index;
|
||||||
import google.registry.config.RegistryConfig;
|
import google.registry.config.RegistryConfig;
|
||||||
import google.registry.model.CacheUtils.AppEngineEnvironmentCacheLoader;
|
import google.registry.model.CacheUtils.AppEngineEnvironmentCacheLoader;
|
||||||
|
@ -111,7 +112,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||||
* resource fields.
|
* resource fields.
|
||||||
*/
|
*/
|
||||||
@AttributeOverrides(@AttributeOverride(name = "creationTime", column = @Column))
|
@AttributeOverrides(@AttributeOverride(name = "creationTime", column = @Column))
|
||||||
@Index
|
@Ignore
|
||||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,8 +59,7 @@ public final class SchemaVersion {
|
||||||
* types (for classes), or else a list of all possible values (for enums).
|
* types (for classes), or else a list of all possible values (for enums).
|
||||||
*/
|
*/
|
||||||
public static String getSchema() {
|
public static String getSchema() {
|
||||||
return getAllPersistedTypes()
|
return getAllPersistedTypes().stream()
|
||||||
.stream()
|
|
||||||
.filter(or(subtypeOf(Enum.class), subtypeOf(ImmutableObject.class)))
|
.filter(or(subtypeOf(Enum.class), subtypeOf(ImmutableObject.class)))
|
||||||
.map(ModelUtils::getSchema)
|
.map(ModelUtils::getSchema)
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
|
|
|
@ -17,23 +17,15 @@ package google.registry.model;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
|
|
||||||
import com.googlecode.objectify.annotation.Ignore;
|
|
||||||
import com.googlecode.objectify.annotation.OnLoad;
|
|
||||||
import google.registry.util.DateTimeUtils;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.PostLoad;
|
|
||||||
import javax.persistence.PrePersist;
|
import javax.persistence.PrePersist;
|
||||||
import javax.persistence.PreUpdate;
|
import javax.persistence.PreUpdate;
|
||||||
import javax.persistence.Transient;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/** A timestamp that auto-updates on each save to Datastore/Cloud SQL. */
|
||||||
* A timestamp that auto-updates on each save to Datastore/Cloud SQL.
|
|
||||||
*/
|
|
||||||
@Embeddable
|
@Embeddable
|
||||||
public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||||
|
|
||||||
|
@ -42,11 +34,8 @@ public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerial
|
||||||
// during a replay).
|
// during a replay).
|
||||||
private static final ThreadLocal<Boolean> autoUpdateEnabled = ThreadLocal.withInitial(() -> true);
|
private static final ThreadLocal<Boolean> autoUpdateEnabled = ThreadLocal.withInitial(() -> true);
|
||||||
|
|
||||||
@Transient DateTime timestamp;
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
ZonedDateTime lastUpdateTime;
|
DateTime lastUpdateTime;
|
||||||
|
|
||||||
// Unfortunately, we cannot use the @UpdateTimestamp annotation on "lastUpdateTime" in this class
|
// Unfortunately, we cannot use the @UpdateTimestamp annotation on "lastUpdateTime" in this class
|
||||||
// because Hibernate does not allow it to be used on @Embeddable classes, see
|
// because Hibernate does not allow it to be used on @Embeddable classes, see
|
||||||
|
@ -55,34 +44,18 @@ public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerial
|
||||||
@PreUpdate
|
@PreUpdate
|
||||||
void setTimestamp() {
|
void setTimestamp() {
|
||||||
if (autoUpdateEnabled() || lastUpdateTime == null) {
|
if (autoUpdateEnabled() || lastUpdateTime == null) {
|
||||||
timestamp = jpaTm().getTransactionTime();
|
lastUpdateTime = jpaTm().getTransactionTime();
|
||||||
lastUpdateTime = DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnLoad
|
|
||||||
void onLoad() {
|
|
||||||
if (timestamp != null) {
|
|
||||||
lastUpdateTime = DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostLoad
|
|
||||||
void postLoad() {
|
|
||||||
if (lastUpdateTime != null) {
|
|
||||||
timestamp = DateTimeUtils.toJodaDateTime(lastUpdateTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
||||||
public DateTime getTimestamp() {
|
public DateTime getTimestamp() {
|
||||||
return Optional.ofNullable(timestamp).orElse(START_OF_TIME);
|
return Optional.ofNullable(lastUpdateTime).orElse(START_OF_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UpdateAutoTimestamp create(@Nullable DateTime timestamp) {
|
public static UpdateAutoTimestamp create(@Nullable DateTime timestamp) {
|
||||||
UpdateAutoTimestamp instance = new UpdateAutoTimestamp();
|
UpdateAutoTimestamp instance = new UpdateAutoTimestamp();
|
||||||
instance.timestamp = timestamp;
|
instance.lastUpdateTime = timestamp;
|
||||||
instance.lastUpdateTime = timestamp == null ? null : DateTimeUtils.toZonedDateTime(timestamp);
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,12 @@ package google.registry.model.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
import static google.registry.util.DateTimeUtils.toZonedDateTime;
|
|
||||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||||
|
|
||||||
import google.registry.model.Buildable;
|
import google.registry.model.Buildable;
|
||||||
import google.registry.model.CreateAutoTimestamp;
|
import google.registry.model.CreateAutoTimestamp;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.UpdateAutoTimestamp;
|
import google.registry.model.UpdateAutoTimestamp;
|
||||||
import google.registry.util.DateTimeUtils;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.persistence.AttributeOverride;
|
import javax.persistence.AttributeOverride;
|
||||||
|
@ -109,19 +106,19 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
|
||||||
private CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
|
private CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** When the unlock is first requested. */
|
/** When the unlock is first requested. */
|
||||||
private ZonedDateTime unlockRequestTime;
|
private DateTime unlockRequestTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the user has verified the lock. If this field is null, it means the lock has not been
|
* When the user has verified the lock. If this field is null, it means the lock has not been
|
||||||
* verified yet (and thus not been put into effect).
|
* verified yet (and thus not been put into effect).
|
||||||
*/
|
*/
|
||||||
private ZonedDateTime lockCompletionTime;
|
private DateTime lockCompletionTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
|
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
|
||||||
* action has not been verified yet (and has not been put into effect).
|
* action has not been verified yet (and has not been put into effect).
|
||||||
*/
|
*/
|
||||||
private ZonedDateTime unlockCompletionTime;
|
private DateTime unlockCompletionTime;
|
||||||
|
|
||||||
/** The user must provide the random verification code in order to complete the action. */
|
/** The user must provide the random verification code in order to complete the action. */
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@ -168,19 +165,19 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
|
||||||
|
|
||||||
/** Returns the unlock request timestamp or null if an unlock has not been requested yet. */
|
/** Returns the unlock request timestamp or null if an unlock has not been requested yet. */
|
||||||
public Optional<DateTime> getUnlockRequestTime() {
|
public Optional<DateTime> getUnlockRequestTime() {
|
||||||
return Optional.ofNullable(unlockRequestTime).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(unlockRequestTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the completion timestamp, or empty if this lock has not been completed yet. */
|
/** Returns the completion timestamp, or empty if this lock has not been completed yet. */
|
||||||
public Optional<DateTime> getLockCompletionTime() {
|
public Optional<DateTime> getLockCompletionTime() {
|
||||||
return Optional.ofNullable(lockCompletionTime).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(lockCompletionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unlock completion timestamp, or empty if this unlock has not been completed yet.
|
* Returns the unlock completion timestamp, or empty if this unlock has not been completed yet.
|
||||||
*/
|
*/
|
||||||
public Optional<DateTime> getUnlockCompletionTime() {
|
public Optional<DateTime> getUnlockCompletionTime() {
|
||||||
return Optional.ofNullable(unlockCompletionTime).map(DateTimeUtils::toJodaDateTime);
|
return Optional.ofNullable(unlockCompletionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVerificationCode() {
|
public String getVerificationCode() {
|
||||||
|
@ -278,17 +275,17 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setUnlockRequestTime(DateTime unlockRequestTime) {
|
public Builder setUnlockRequestTime(DateTime unlockRequestTime) {
|
||||||
getInstance().unlockRequestTime = toZonedDateTime(unlockRequestTime);
|
getInstance().unlockRequestTime = unlockRequestTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setLockCompletionTime(DateTime lockCompletionTime) {
|
public Builder setLockCompletionTime(DateTime lockCompletionTime) {
|
||||||
getInstance().lockCompletionTime = toZonedDateTime(lockCompletionTime);
|
getInstance().lockCompletionTime = lockCompletionTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setUnlockCompletionTime(DateTime unlockCompletionTime) {
|
public Builder setUnlockCompletionTime(DateTime unlockCompletionTime) {
|
||||||
getInstance().unlockCompletionTime = toZonedDateTime(unlockCompletionTime);
|
getInstance().unlockCompletionTime = unlockCompletionTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import com.google.common.collect.Range;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
import com.googlecode.objectify.annotation.Index;
|
import com.googlecode.objectify.annotation.Index;
|
||||||
import com.googlecode.objectify.annotation.OnLoad;
|
import com.googlecode.objectify.annotation.OnLoad;
|
||||||
import google.registry.flows.EppException;
|
import google.registry.flows.EppException;
|
||||||
|
@ -138,7 +139,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||||
@Nullable @Index String domainName;
|
@Nullable @Index String domainName;
|
||||||
|
|
||||||
/** When this token was created. */
|
/** When this token was created. */
|
||||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
@Ignore CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** Allowed registrar client IDs for this token, or null if all registrars are allowed. */
|
/** Allowed registrar client IDs for this token, or null if all registrars are allowed. */
|
||||||
@Column(name = "allowedRegistrarIds")
|
@Column(name = "allowedRegistrarIds")
|
||||||
|
|
|
@ -38,7 +38,6 @@ import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.annotations.DeleteAfterMigration;
|
import google.registry.model.annotations.DeleteAfterMigration;
|
||||||
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
|
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
|
||||||
import google.registry.model.translators.CidrAddressBlockTranslatorFactory;
|
import google.registry.model.translators.CidrAddressBlockTranslatorFactory;
|
||||||
import google.registry.model.translators.CreateAutoTimestampTranslatorFactory;
|
|
||||||
import google.registry.model.translators.CurrencyUnitTranslatorFactory;
|
import google.registry.model.translators.CurrencyUnitTranslatorFactory;
|
||||||
import google.registry.model.translators.DurationTranslatorFactory;
|
import google.registry.model.translators.DurationTranslatorFactory;
|
||||||
import google.registry.model.translators.EppHistoryVKeyTranslatorFactory;
|
import google.registry.model.translators.EppHistoryVKeyTranslatorFactory;
|
||||||
|
@ -122,7 +121,6 @@ public class ObjectifyService {
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
new BloomFilterOfStringTranslatorFactory(),
|
new BloomFilterOfStringTranslatorFactory(),
|
||||||
new CidrAddressBlockTranslatorFactory(),
|
new CidrAddressBlockTranslatorFactory(),
|
||||||
new CreateAutoTimestampTranslatorFactory(),
|
|
||||||
new CurrencyUnitTranslatorFactory(),
|
new CurrencyUnitTranslatorFactory(),
|
||||||
new DurationTranslatorFactory(),
|
new DurationTranslatorFactory(),
|
||||||
new EppHistoryVKeyTranslatorFactory(),
|
new EppHistoryVKeyTranslatorFactory(),
|
||||||
|
|
|
@ -58,6 +58,7 @@ import com.google.re2j.Pattern;
|
||||||
import com.googlecode.objectify.Key;
|
import com.googlecode.objectify.Key;
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
import com.googlecode.objectify.annotation.Entity;
|
||||||
import com.googlecode.objectify.annotation.Id;
|
import com.googlecode.objectify.annotation.Id;
|
||||||
|
import com.googlecode.objectify.annotation.Ignore;
|
||||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||||
import com.googlecode.objectify.annotation.Index;
|
import com.googlecode.objectify.annotation.Index;
|
||||||
import com.googlecode.objectify.annotation.Parent;
|
import com.googlecode.objectify.annotation.Parent;
|
||||||
|
@ -407,10 +408,10 @@ public class Registrar extends ImmutableObject
|
||||||
// Metadata.
|
// Metadata.
|
||||||
|
|
||||||
/** The time when this registrar was created. */
|
/** The time when this registrar was created. */
|
||||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
@Ignore CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** An automatically managed last-saved timestamp. */
|
/** An automatically managed last-saved timestamp. */
|
||||||
UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null);
|
@Ignore UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null);
|
||||||
|
|
||||||
/** The time that the certificate was last updated. */
|
/** The time that the certificate was last updated. */
|
||||||
DateTime lastCertificateUpdateTime;
|
DateTime lastCertificateUpdateTime;
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
package google.registry.model.translators;
|
|
||||||
|
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
|
||||||
|
|
||||||
import google.registry.model.CreateAutoTimestamp;
|
|
||||||
import java.util.Date;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
|
|
||||||
/** Saves {@link CreateAutoTimestamp} as either its value, or the current time if it was null. */
|
|
||||||
public class CreateAutoTimestampTranslatorFactory
|
|
||||||
extends AbstractSimpleTranslatorFactory<CreateAutoTimestamp, Date> {
|
|
||||||
|
|
||||||
public CreateAutoTimestampTranslatorFactory() {
|
|
||||||
super(CreateAutoTimestamp.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
SimpleTranslator<CreateAutoTimestamp, Date> createTranslator() {
|
|
||||||
return new SimpleTranslator<CreateAutoTimestamp, Date>() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load an existing timestamp. It can be assumed to be non-null since if the field is null in
|
|
||||||
* Datastore then Objectify will skip this translator and directly load a null.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public CreateAutoTimestamp loadValue(Date datastoreValue) {
|
|
||||||
return CreateAutoTimestamp.create(new DateTime(datastoreValue, UTC));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save a timestamp, setting it to the current time if it did not have a previous value. */
|
|
||||||
@Override
|
|
||||||
public Date saveValue(CreateAutoTimestamp pojoValue) {
|
|
||||||
// Note that we use the current transaction manager -- we need to do this under JPA when we
|
|
||||||
// serialize the entity from a Transaction object, but we need to use the JPA transaction
|
|
||||||
// manager in that case.
|
|
||||||
return (pojoValue.getTimestamp() == null
|
|
||||||
? tm().getTransactionTime()
|
|
||||||
: pojoValue.getTimestamp())
|
|
||||||
.toDate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
// Copyright 2019 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.converter;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.persistence.AttributeConverter;
|
|
||||||
import javax.persistence.Converter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JPA converter to for storing/retrieving {@link ZonedDateTime} objects.
|
|
||||||
*
|
|
||||||
* <p>Hibernate provides a default converter for {@link ZonedDateTime}, but it converts timestamp to
|
|
||||||
* a non-normalized format, e.g., 2019-09-01T01:01:01Z will be converted to
|
|
||||||
* 2019-09-01T01:01:01Z[UTC]. This converter solves that problem by explicitly calling {@link
|
|
||||||
* ZoneId#normalized()} to normalize the zone id.
|
|
||||||
*/
|
|
||||||
@Converter(autoApply = true)
|
|
||||||
public class ZonedDateTimeConverter implements AttributeConverter<ZonedDateTime, Timestamp> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Timestamp convertToDatabaseColumn(@Nullable ZonedDateTime attribute) {
|
|
||||||
return attribute == null ? null : Timestamp.from(attribute.toInstant());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public ZonedDateTime convertToEntityAttribute(@Nullable Timestamp dbData) {
|
|
||||||
return dbData == null
|
|
||||||
? null
|
|
||||||
: ZonedDateTime.ofInstant(dbData.toInstant(), ZoneId.of("UTC").normalized());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -96,7 +96,6 @@
|
||||||
<class>google.registry.persistence.converter.StringSetConverter</class>
|
<class>google.registry.persistence.converter.StringSetConverter</class>
|
||||||
<class>google.registry.persistence.converter.TldStateTransitionConverter</class>
|
<class>google.registry.persistence.converter.TldStateTransitionConverter</class>
|
||||||
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
|
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
|
||||||
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
|
||||||
|
|
||||||
<!-- Generated converters for VKey -->
|
<!-- Generated converters for VKey -->
|
||||||
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
||||||
|
|
|
@ -23,12 +23,11 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import org.apache.avro.Schema;
|
import org.apache.avro.Schema;
|
||||||
import org.apache.avro.generic.GenericData;
|
import org.apache.avro.generic.GenericData;
|
||||||
import org.apache.avro.generic.GenericRecord;
|
import org.apache.avro.generic.GenericRecord;
|
||||||
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -86,10 +85,8 @@ class BillingEventTest {
|
||||||
void testParseBillingEventFromRecord_success() {
|
void testParseBillingEventFromRecord_success() {
|
||||||
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
BillingEvent event = BillingEvent.parseFromRecord(schemaAndRecord);
|
||||||
assertThat(event.id()).isEqualTo(1);
|
assertThat(event.id()).isEqualTo(1);
|
||||||
assertThat(event.billingTime())
|
assertThat(event.billingTime()).isEqualTo(DateTime.parse("2017-10-24T09:06:03Z"));
|
||||||
.isEqualTo(ZonedDateTime.of(2017, 10, 24, 9, 6, 3, 0, ZoneId.of("UTC")));
|
assertThat(event.eventTime()).isEqualTo(DateTime.parse("2017-01-19T23:59:43Z"));
|
||||||
assertThat(event.eventTime())
|
|
||||||
.isEqualTo(ZonedDateTime.of(2017, 1, 19, 23, 59, 43, 0, ZoneId.of("UTC")));
|
|
||||||
assertThat(event.registrarId()).isEqualTo("myRegistrar");
|
assertThat(event.registrarId()).isEqualTo("myRegistrar");
|
||||||
assertThat(event.billingId()).isEqualTo("12345-CRRHELLO");
|
assertThat(event.billingId()).isEqualTo("12345-CRRHELLO");
|
||||||
assertThat(event.poNumber()).isEmpty();
|
assertThat(event.poNumber()).isEmpty();
|
||||||
|
|
|
@ -55,8 +55,6 @@ import google.registry.util.ResourceUtils;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -104,8 +102,8 @@ class InvoicingPipelineTest {
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
1,
|
1,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"theRegistrar",
|
"theRegistrar",
|
||||||
"234",
|
"234",
|
||||||
"",
|
"",
|
||||||
|
@ -119,8 +117,8 @@ class InvoicingPipelineTest {
|
||||||
""),
|
""),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
2,
|
2,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"theRegistrar",
|
"theRegistrar",
|
||||||
"234",
|
"234",
|
||||||
"",
|
"",
|
||||||
|
@ -134,8 +132,8 @@ class InvoicingPipelineTest {
|
||||||
""),
|
""),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
3,
|
3,
|
||||||
ZonedDateTime.of(2017, 10, 2, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-02T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 9, 29, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-09-29T00:00:00Z"),
|
||||||
"theRegistrar",
|
"theRegistrar",
|
||||||
"234",
|
"234",
|
||||||
"",
|
"",
|
||||||
|
@ -149,8 +147,8 @@ class InvoicingPipelineTest {
|
||||||
""),
|
""),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
4,
|
4,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"bestdomains",
|
"bestdomains",
|
||||||
"456",
|
"456",
|
||||||
"116688",
|
"116688",
|
||||||
|
@ -164,8 +162,8 @@ class InvoicingPipelineTest {
|
||||||
""),
|
""),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
5,
|
5,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"anotherRegistrar",
|
"anotherRegistrar",
|
||||||
"789",
|
"789",
|
||||||
"",
|
"",
|
||||||
|
@ -179,8 +177,8 @@ class InvoicingPipelineTest {
|
||||||
"SUNRISE ANCHOR_TENANT"),
|
"SUNRISE ANCHOR_TENANT"),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
6,
|
6,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"theRegistrar",
|
"theRegistrar",
|
||||||
"234",
|
"234",
|
||||||
"",
|
"",
|
||||||
|
@ -194,8 +192,8 @@ class InvoicingPipelineTest {
|
||||||
""),
|
""),
|
||||||
BillingEvent.create(
|
BillingEvent.create(
|
||||||
7,
|
7,
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
ZonedDateTime.of(2017, 10, 4, 0, 0, 0, 0, ZoneId.of("UTC")),
|
DateTime.parse("2017-10-04T00:00:00Z"),
|
||||||
"theRegistrar",
|
"theRegistrar",
|
||||||
"234",
|
"234",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -19,10 +19,11 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
|
||||||
import com.googlecode.objectify.annotation.Ignore;
|
|
||||||
import google.registry.model.common.CrossTldSingleton;
|
import google.registry.model.common.CrossTldSingleton;
|
||||||
import google.registry.testing.AppEngineExtension;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
@ -31,22 +32,19 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
public class CreateAutoTimestampTest {
|
public class CreateAutoTimestampTest {
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
public final AppEngineExtension appEngine =
|
public final JpaUnitTestExtension jpaUnitTestExtension =
|
||||||
AppEngineExtension.builder()
|
new JpaTestExtensions.Builder()
|
||||||
.withCloudSql()
|
.withEntityClass(CreateAutoTimestampTestObject.class)
|
||||||
.withOfyTestEntities(CreateAutoTimestampTestObject.class)
|
.buildUnitTestExtension();
|
||||||
.withJpaUnitTestEntities(CreateAutoTimestampTestObject.class)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/** Timestamped class. */
|
/** Timestamped class. */
|
||||||
@Entity(name = "CatTestEntity")
|
@Entity
|
||||||
@javax.persistence.Entity
|
|
||||||
public static class CreateAutoTimestampTestObject extends CrossTldSingleton {
|
public static class CreateAutoTimestampTestObject extends CrossTldSingleton {
|
||||||
@Ignore @javax.persistence.Id long id = SINGLETON_ID;
|
@Id long id = SINGLETON_ID;
|
||||||
CreateAutoTimestamp createTime = CreateAutoTimestamp.create(null);
|
CreateAutoTimestamp createTime = CreateAutoTimestamp.create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CreateAutoTimestampTestObject reload() {
|
private static CreateAutoTimestampTestObject reload() {
|
||||||
return loadByEntity(new CreateAutoTimestampTestObject());
|
return loadByEntity(new CreateAutoTimestampTestObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ public class CreateAutoTimestampTest {
|
||||||
return tm().getTransactionTime();
|
return tm().getTransactionTime();
|
||||||
});
|
});
|
||||||
tm().clearSessionCache();
|
tm().clearSessionCache();
|
||||||
assertThat(reload().createTime.timestamp).isEqualTo(transactionTime);
|
assertThat(reload().createTime.getTimestamp()).isEqualTo(transactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -74,6 +72,6 @@ public class CreateAutoTimestampTest {
|
||||||
tm().put(object);
|
tm().put(object);
|
||||||
});
|
});
|
||||||
tm().clearSessionCache();
|
tm().clearSessionCache();
|
||||||
assertThat(reload().createTime.timestamp).isEqualTo(oldCreateTime);
|
assertThat(reload().createTime.getTimestamp()).isEqualTo(oldCreateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,59 +16,42 @@ package google.registry.model;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static org.joda.time.DateTimeZone.UTC;
|
import static org.joda.time.DateTimeZone.UTC;
|
||||||
|
|
||||||
import com.googlecode.objectify.Key;
|
|
||||||
import com.googlecode.objectify.annotation.Entity;
|
|
||||||
import com.googlecode.objectify.annotation.Ignore;
|
|
||||||
import google.registry.model.common.CrossTldSingleton;
|
import google.registry.model.common.CrossTldSingleton;
|
||||||
import google.registry.model.ofy.Ofy;
|
|
||||||
import google.registry.persistence.VKey;
|
import google.registry.persistence.VKey;
|
||||||
import google.registry.testing.AppEngineExtension;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.InjectExtension;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/** Unit tests for {@link UpdateAutoTimestamp}. */
|
/** Unit tests for {@link UpdateAutoTimestamp}. */
|
||||||
public class UpdateAutoTimestampTest {
|
public class UpdateAutoTimestampTest {
|
||||||
|
|
||||||
FakeClock clock = new FakeClock();
|
private final FakeClock clock = new FakeClock();
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
public final AppEngineExtension appEngine =
|
public final JpaUnitTestExtension jpaUnitTestExtension =
|
||||||
AppEngineExtension.builder()
|
new JpaTestExtensions.Builder()
|
||||||
.withCloudSql()
|
|
||||||
.withJpaUnitTestEntities(UpdateAutoTimestampTestObject.class)
|
|
||||||
.withOfyTestEntities(UpdateAutoTimestampTestObject.class)
|
|
||||||
.withClock(clock)
|
.withClock(clock)
|
||||||
.build();
|
.withEntityClass(UpdateAutoTimestampTestObject.class)
|
||||||
|
.buildUnitTestExtension();
|
||||||
@RegisterExtension public final InjectExtension inject = new InjectExtension();
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void beforeEach() {
|
|
||||||
inject.setStaticField(Ofy.class, "clock", clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Timestamped class. */
|
/** Timestamped class. */
|
||||||
@Entity(name = "UatTestEntity")
|
@Entity
|
||||||
@javax.persistence.Entity
|
|
||||||
public static class UpdateAutoTimestampTestObject extends CrossTldSingleton {
|
public static class UpdateAutoTimestampTestObject extends CrossTldSingleton {
|
||||||
@Ignore @javax.persistence.Id long id = SINGLETON_ID;
|
@Id long id = SINGLETON_ID;
|
||||||
UpdateAutoTimestamp updateTime = UpdateAutoTimestamp.create(null);
|
UpdateAutoTimestamp updateTime = UpdateAutoTimestamp.create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpdateAutoTimestampTestObject reload() {
|
private static UpdateAutoTimestampTestObject reload() {
|
||||||
return tm().transact(
|
return tm().transact(
|
||||||
() ->
|
() -> tm().loadByKey(VKey.createSql(UpdateAutoTimestampTestObject.class, 1L)));
|
||||||
tm().loadByKey(
|
|
||||||
VKey.create(
|
|
||||||
UpdateAutoTimestampTestObject.class,
|
|
||||||
1L,
|
|
||||||
Key.create(new UpdateAutoTimestampTestObject()))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -78,12 +61,12 @@ public class UpdateAutoTimestampTest {
|
||||||
() -> {
|
() -> {
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
UpdateAutoTimestampTestObject object = new UpdateAutoTimestampTestObject();
|
||||||
assertThat(object.updateTime.timestamp).isNull();
|
assertThat(object.updateTime.getTimestamp()).isEqualTo(START_OF_TIME);
|
||||||
tm().insert(object);
|
tm().insert(object);
|
||||||
return tm().getTransactionTime();
|
return tm().getTransactionTime();
|
||||||
});
|
});
|
||||||
tm().clearSessionCache();
|
tm().clearSessionCache();
|
||||||
assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime);
|
assertThat(reload().updateTime.getTimestamp()).isEqualTo(transactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -99,7 +82,7 @@ public class UpdateAutoTimestampTest {
|
||||||
UpdateAutoTimestampTestObject object = reload();
|
UpdateAutoTimestampTestObject object = reload();
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
|
|
||||||
try (UpdateAutoTimestamp.DisableAutoUpdateResource disabler =
|
try (UpdateAutoTimestamp.DisableAutoUpdateResource ignoredDisabler =
|
||||||
new UpdateAutoTimestamp.DisableAutoUpdateResource()) {
|
new UpdateAutoTimestamp.DisableAutoUpdateResource()) {
|
||||||
DateTime secondTransactionTime =
|
DateTime secondTransactionTime =
|
||||||
tm().transact(
|
tm().transact(
|
||||||
|
@ -109,7 +92,7 @@ public class UpdateAutoTimestampTest {
|
||||||
});
|
});
|
||||||
assertThat(secondTransactionTime).isGreaterThan(initialTime);
|
assertThat(secondTransactionTime).isGreaterThan(initialTime);
|
||||||
}
|
}
|
||||||
assertThat(reload().updateTime.timestamp).isEqualTo(initialTime);
|
assertThat(reload().updateTime.getTimestamp()).isEqualTo(initialTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -124,7 +107,7 @@ public class UpdateAutoTimestampTest {
|
||||||
return tm().getTransactionTime();
|
return tm().getTransactionTime();
|
||||||
});
|
});
|
||||||
tm().clearSessionCache();
|
tm().clearSessionCache();
|
||||||
assertThat(reload().updateTime.timestamp).isEqualTo(transactionTime);
|
assertThat(reload().updateTime.getTimestamp()).isEqualTo(transactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
// Copyright 2019 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.converter;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
|
||||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
|
||||||
|
|
||||||
import google.registry.model.ImmutableObject;
|
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/** Unit tests for {@link ZonedDateTimeConverter}. */
|
|
||||||
public class ZonedDateTimeConverterTest {
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
public final JpaUnitTestExtension jpaExtension =
|
|
||||||
new JpaTestExtensions.Builder().withEntityClass(TestEntity.class).buildUnitTestExtension();
|
|
||||||
|
|
||||||
private final ZonedDateTimeConverter converter = new ZonedDateTimeConverter();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void convertToDatabaseColumn_returnsNullIfInputIsNull() {
|
|
||||||
assertThat(converter.convertToDatabaseColumn(null)).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void convertToDatabaseColumn_convertsCorrectly() {
|
|
||||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2019-09-01T01:01:01Z");
|
|
||||||
assertThat(converter.convertToDatabaseColumn(zonedDateTime).toInstant())
|
|
||||||
.isEqualTo(zonedDateTime.toInstant());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void convertToEntityAttribute_returnsNullIfInputIsNull() {
|
|
||||||
assertThat(converter.convertToEntityAttribute(null)).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void convertToEntityAttribute_convertsCorrectly() {
|
|
||||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2019-09-01T01:01:01Z");
|
|
||||||
Instant instant = zonedDateTime.toInstant();
|
|
||||||
assertThat(converter.convertToEntityAttribute(Timestamp.from(instant)))
|
|
||||||
.isEqualTo(zonedDateTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void converter_generatesTimestampWithNormalizedZone() {
|
|
||||||
ZonedDateTime zdt = ZonedDateTime.parse("2019-09-01T01:01:01Z");
|
|
||||||
TestEntity entity = new TestEntity("normalized_utc_time", zdt);
|
|
||||||
insertInDb(entity);
|
|
||||||
TestEntity retrievedEntity =
|
|
||||||
jpaTm()
|
|
||||||
.transact(
|
|
||||||
() -> jpaTm().getEntityManager().find(TestEntity.class, "normalized_utc_time"));
|
|
||||||
assertThat(retrievedEntity.zdt.toString()).isEqualTo("2019-09-01T01:01:01Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void converter_convertsNonNormalizedZoneCorrectly() {
|
|
||||||
ZonedDateTime zdt = ZonedDateTime.parse("2019-09-01T01:01:01Z[UTC]");
|
|
||||||
TestEntity entity = new TestEntity("non_normalized_utc_time", zdt);
|
|
||||||
|
|
||||||
insertInDb(entity);
|
|
||||||
TestEntity retrievedEntity =
|
|
||||||
jpaTm()
|
|
||||||
.transact(
|
|
||||||
() -> jpaTm().getEntityManager().find(TestEntity.class, "non_normalized_utc_time"));
|
|
||||||
assertThat(retrievedEntity.zdt.toString()).isEqualTo("2019-09-01T01:01:01Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void converter_convertsNonUtcZoneCorrectly() {
|
|
||||||
ZonedDateTime zdt = ZonedDateTime.parse("2019-09-01T01:01:01+05:00");
|
|
||||||
TestEntity entity = new TestEntity("new_york_time", zdt);
|
|
||||||
|
|
||||||
insertInDb(entity);
|
|
||||||
TestEntity retrievedEntity =
|
|
||||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "new_york_time"));
|
|
||||||
assertThat(retrievedEntity.zdt.toString()).isEqualTo("2019-08-31T20:01:01Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
|
||||||
private static class TestEntity extends ImmutableObject {
|
|
||||||
|
|
||||||
@Id String name;
|
|
||||||
|
|
||||||
ZonedDateTime zdt;
|
|
||||||
|
|
||||||
public TestEntity() {}
|
|
||||||
|
|
||||||
TestEntity(String name, ZonedDateTime zdt) {
|
|
||||||
this.name = name;
|
|
||||||
this.zdt = zdt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,3 @@
|
||||||
class google.registry.model.CreateAutoTimestamp {
|
|
||||||
org.joda.time.DateTime timestamp;
|
|
||||||
}
|
|
||||||
class google.registry.model.UpdateAutoTimestamp {
|
|
||||||
org.joda.time.DateTime timestamp;
|
|
||||||
}
|
|
||||||
class google.registry.model.billing.BillingEvent$Cancellation {
|
class google.registry.model.billing.BillingEvent$Cancellation {
|
||||||
@Id java.lang.Long id;
|
@Id java.lang.Long id;
|
||||||
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
@Parent com.googlecode.objectify.Key<google.registry.model.domain.DomainHistory> parent;
|
||||||
|
@ -81,7 +75,6 @@ enum google.registry.model.billing.BillingEvent$RenewalPriceBehavior {
|
||||||
}
|
}
|
||||||
class google.registry.model.common.EntityGroupRoot {
|
class google.registry.model.common.EntityGroupRoot {
|
||||||
@Id java.lang.String id;
|
@Id java.lang.String id;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
}
|
}
|
||||||
class google.registry.model.common.GaeUserIdConverter {
|
class google.registry.model.common.GaeUserIdConverter {
|
||||||
@Id long id;
|
@Id long id;
|
||||||
|
@ -102,8 +95,6 @@ class google.registry.model.contact.ContactAuthInfo {
|
||||||
}
|
}
|
||||||
class google.registry.model.contact.ContactBase {
|
class google.registry.model.contact.ContactBase {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.model.contact.ContactAuthInfo authInfo;
|
google.registry.model.contact.ContactAuthInfo authInfo;
|
||||||
google.registry.model.contact.ContactPhoneNumber fax;
|
google.registry.model.contact.ContactPhoneNumber fax;
|
||||||
google.registry.model.contact.ContactPhoneNumber voice;
|
google.registry.model.contact.ContactPhoneNumber voice;
|
||||||
|
@ -144,8 +135,6 @@ class google.registry.model.contact.ContactPhoneNumber {
|
||||||
}
|
}
|
||||||
class google.registry.model.contact.ContactResource {
|
class google.registry.model.contact.ContactResource {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.model.contact.ContactAuthInfo authInfo;
|
google.registry.model.contact.ContactAuthInfo authInfo;
|
||||||
google.registry.model.contact.ContactPhoneNumber fax;
|
google.registry.model.contact.ContactPhoneNumber fax;
|
||||||
google.registry.model.contact.ContactPhoneNumber voice;
|
google.registry.model.contact.ContactPhoneNumber voice;
|
||||||
|
@ -191,8 +180,6 @@ class google.registry.model.domain.DomainAuthInfo {
|
||||||
}
|
}
|
||||||
class google.registry.model.domain.DomainBase {
|
class google.registry.model.domain.DomainBase {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.model.domain.DomainAuthInfo authInfo;
|
google.registry.model.domain.DomainAuthInfo authInfo;
|
||||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||||
google.registry.model.transfer.DomainTransferData transferData;
|
google.registry.model.transfer.DomainTransferData transferData;
|
||||||
|
@ -223,8 +210,6 @@ class google.registry.model.domain.DomainBase {
|
||||||
}
|
}
|
||||||
class google.registry.model.domain.DomainContent {
|
class google.registry.model.domain.DomainContent {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.model.domain.DomainAuthInfo authInfo;
|
google.registry.model.domain.DomainAuthInfo authInfo;
|
||||||
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
google.registry.model.domain.launch.LaunchNotice launchNotice;
|
||||||
google.registry.model.transfer.DomainTransferData transferData;
|
google.registry.model.transfer.DomainTransferData transferData;
|
||||||
|
@ -334,8 +319,6 @@ class google.registry.model.domain.token.AllocationToken {
|
||||||
@Id java.lang.String token;
|
@Id java.lang.String token;
|
||||||
boolean discountPremiums;
|
boolean discountPremiums;
|
||||||
double discountFraction;
|
double discountFraction;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.model.billing.BillingEvent$RenewalPriceBehavior renewalPriceBehavior;
|
google.registry.model.billing.BillingEvent$RenewalPriceBehavior renewalPriceBehavior;
|
||||||
google.registry.model.common.TimedTransitionProperty<google.registry.model.domain.token.AllocationToken$TokenStatus> tokenStatusTransitions;
|
google.registry.model.common.TimedTransitionProperty<google.registry.model.domain.token.AllocationToken$TokenStatus> tokenStatusTransitions;
|
||||||
google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior;
|
google.registry.model.domain.token.AllocationToken$RegistrationBehavior registrationBehavior;
|
||||||
|
@ -393,8 +376,6 @@ class google.registry.model.eppcommon.Trid {
|
||||||
}
|
}
|
||||||
class google.registry.model.host.HostBase {
|
class google.registry.model.host.HostBase {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.persistence.VKey<google.registry.model.domain.DomainBase> superordinateDomain;
|
google.registry.persistence.VKey<google.registry.model.domain.DomainBase> superordinateDomain;
|
||||||
java.lang.String creationClientId;
|
java.lang.String creationClientId;
|
||||||
java.lang.String currentSponsorClientId;
|
java.lang.String currentSponsorClientId;
|
||||||
|
@ -425,8 +406,6 @@ class google.registry.model.host.HostHistory {
|
||||||
}
|
}
|
||||||
class google.registry.model.host.HostResource {
|
class google.registry.model.host.HostResource {
|
||||||
@Id java.lang.String repoId;
|
@Id java.lang.String repoId;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.persistence.VKey<google.registry.model.domain.DomainBase> superordinateDomain;
|
google.registry.persistence.VKey<google.registry.model.domain.DomainBase> superordinateDomain;
|
||||||
java.lang.String creationClientId;
|
java.lang.String creationClientId;
|
||||||
java.lang.String currentSponsorClientId;
|
java.lang.String currentSponsorClientId;
|
||||||
|
@ -443,7 +422,6 @@ class google.registry.model.index.EppResourceIndex {
|
||||||
@Id java.lang.String id;
|
@Id java.lang.String id;
|
||||||
@Parent com.googlecode.objectify.Key<google.registry.model.index.EppResourceIndexBucket> bucket;
|
@Parent com.googlecode.objectify.Key<google.registry.model.index.EppResourceIndexBucket> bucket;
|
||||||
com.googlecode.objectify.Key<? extends google.registry.model.EppResource> reference;
|
com.googlecode.objectify.Key<? extends google.registry.model.EppResource> reference;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
java.lang.String kind;
|
java.lang.String kind;
|
||||||
}
|
}
|
||||||
class google.registry.model.index.EppResourceIndexBucket {
|
class google.registry.model.index.EppResourceIndexBucket {
|
||||||
|
@ -451,19 +429,16 @@ class google.registry.model.index.EppResourceIndexBucket {
|
||||||
}
|
}
|
||||||
class google.registry.model.index.ForeignKeyIndex$ForeignKeyContactIndex {
|
class google.registry.model.index.ForeignKeyIndex$ForeignKeyContactIndex {
|
||||||
@Id java.lang.String foreignKey;
|
@Id java.lang.String foreignKey;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.persistence.VKey<E> topReference;
|
google.registry.persistence.VKey<E> topReference;
|
||||||
org.joda.time.DateTime deletionTime;
|
org.joda.time.DateTime deletionTime;
|
||||||
}
|
}
|
||||||
class google.registry.model.index.ForeignKeyIndex$ForeignKeyDomainIndex {
|
class google.registry.model.index.ForeignKeyIndex$ForeignKeyDomainIndex {
|
||||||
@Id java.lang.String foreignKey;
|
@Id java.lang.String foreignKey;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.persistence.VKey<E> topReference;
|
google.registry.persistence.VKey<E> topReference;
|
||||||
org.joda.time.DateTime deletionTime;
|
org.joda.time.DateTime deletionTime;
|
||||||
}
|
}
|
||||||
class google.registry.model.index.ForeignKeyIndex$ForeignKeyHostIndex {
|
class google.registry.model.index.ForeignKeyIndex$ForeignKeyHostIndex {
|
||||||
@Id java.lang.String foreignKey;
|
@Id java.lang.String foreignKey;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
google.registry.persistence.VKey<E> topReference;
|
google.registry.persistence.VKey<E> topReference;
|
||||||
org.joda.time.DateTime deletionTime;
|
org.joda.time.DateTime deletionTime;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +464,6 @@ class google.registry.model.poll.PollMessage$OneTime {
|
||||||
}
|
}
|
||||||
class google.registry.model.rde.RdeRevision {
|
class google.registry.model.rde.RdeRevision {
|
||||||
@Id java.lang.String id;
|
@Id java.lang.String id;
|
||||||
google.registry.model.UpdateAutoTimestamp updateTimestamp;
|
|
||||||
int revision;
|
int revision;
|
||||||
}
|
}
|
||||||
class google.registry.model.registrar.Registrar {
|
class google.registry.model.registrar.Registrar {
|
||||||
|
@ -498,8 +472,6 @@ class google.registry.model.registrar.Registrar {
|
||||||
boolean blockPremiumNames;
|
boolean blockPremiumNames;
|
||||||
boolean contactsRequireSyncing;
|
boolean contactsRequireSyncing;
|
||||||
boolean registryLockAllowed;
|
boolean registryLockAllowed;
|
||||||
google.registry.model.CreateAutoTimestamp creationTime;
|
|
||||||
google.registry.model.UpdateAutoTimestamp lastUpdateTime;
|
|
||||||
google.registry.model.registrar.Registrar$State state;
|
google.registry.model.registrar.Registrar$State state;
|
||||||
google.registry.model.registrar.Registrar$Type type;
|
google.registry.model.registrar.Registrar$Type type;
|
||||||
google.registry.model.registrar.RegistrarAddress internationalizedAddress;
|
google.registry.model.registrar.RegistrarAddress internationalizedAddress;
|
||||||
|
|
|
@ -23,15 +23,12 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||||
import static google.registry.util.DateTimeUtils.latestOf;
|
import static google.registry.util.DateTimeUtils.latestOf;
|
||||||
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||||
import static google.registry.util.DateTimeUtils.leapSafeSubtractYears;
|
import static google.registry.util.DateTimeUtils.leapSafeSubtractYears;
|
||||||
import static google.registry.util.DateTimeUtils.toJodaDateTime;
|
|
||||||
import static google.registry.util.DateTimeUtils.toLocalDate;
|
import static google.registry.util.DateTimeUtils.toLocalDate;
|
||||||
import static google.registry.util.DateTimeUtils.toSqlDate;
|
import static google.registry.util.DateTimeUtils.toSqlDate;
|
||||||
import static google.registry.util.DateTimeUtils.toZonedDateTime;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -99,48 +96,6 @@ class DateTimeUtilsTest {
|
||||||
assertThrows(IllegalArgumentException.class, () -> earliestOf(ImmutableList.of()));
|
assertThrows(IllegalArgumentException.class, () -> earliestOf(ImmutableList.of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toZonedDateTime_preservesTimeZone() {
|
|
||||||
DateTime dateTime = DateTime.parse("2019-09-06T10:59:36.283-07:00"); // PDT
|
|
||||||
ZonedDateTime zonedDateTime = toZonedDateTime(dateTime);
|
|
||||||
assertThat(zonedDateTime.toString()).isEqualTo("2019-09-06T10:59:36.283-07:00"); // still PDT
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toZonedDateTime_fromStringZulu() {
|
|
||||||
DateTime dateTime = DateTime.parse("2015-10-13T11:22:33.168Z");
|
|
||||||
ZonedDateTime zonedDateTime = toZonedDateTime(dateTime);
|
|
||||||
assertThat(zonedDateTime.toString()).isEqualTo("2015-10-13T11:22:33.168Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toZonedDateTime_leapYear() {
|
|
||||||
DateTime dateTime = DateTime.parse("2016-02-29T11:22:33.168Z");
|
|
||||||
ZonedDateTime zonedDateTime = toZonedDateTime(dateTime);
|
|
||||||
assertThat(zonedDateTime.toString()).isEqualTo("2016-02-29T11:22:33.168Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toJodaDateTime_preservesTimeZone() {
|
|
||||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2019-09-06T10:59:36.283-07:00"); // PDT
|
|
||||||
DateTime dateTime = toJodaDateTime(zonedDateTime);
|
|
||||||
assertThat(dateTime.toString()).isEqualTo("2019-09-06T10:59:36.283-07:00"); // still PDT
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toJodaDateTime_fromStringZulu() {
|
|
||||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2015-10-13T11:22:33.168Z");
|
|
||||||
DateTime dateTime = toJodaDateTime(zonedDateTime);
|
|
||||||
assertThat(dateTime.toString()).isEqualTo("2015-10-13T11:22:33.168Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_toJodaDateTime_leapYear() {
|
|
||||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2016-02-29T11:22:33.168Z");
|
|
||||||
DateTime dateTime = toJodaDateTime(zonedDateTime);
|
|
||||||
assertThat(dateTime.toString()).isEqualTo("2016-02-29T11:22:33.168Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_toSqlDate() {
|
void testSuccess_toSqlDate() {
|
||||||
LocalDate localDate = LocalDate.parse("2020-02-29");
|
LocalDate localDate = LocalDate.parse("2020-02-29");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue