mirror of
https://github.com/google/nomulus
synced 2026-09-05 23:57:01 +00: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:
@@ -28,16 +28,16 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
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 org.apache.avro.generic.GenericRecord;
|
||||
import org.apache.beam.sdk.coders.AtomicCoder;
|
||||
import org.apache.beam.sdk.coders.Coder;
|
||||
import org.apache.beam.sdk.coders.StringUtf8Coder;
|
||||
import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}.
|
||||
@@ -51,7 +51,7 @@ import org.apache.beam.sdk.io.gcp.bigquery.SchemaAndRecord;
|
||||
public abstract class BillingEvent implements Serializable {
|
||||
|
||||
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. */
|
||||
private static final double SUNRISE_DISCOUNT_PRICE_MODIFIER = 0.85;
|
||||
@@ -77,10 +77,10 @@ public abstract class BillingEvent implements Serializable {
|
||||
abstract long id();
|
||||
|
||||
/** Returns the UTC DateTime this event becomes billable. */
|
||||
abstract ZonedDateTime billingTime();
|
||||
abstract DateTime billingTime();
|
||||
|
||||
/** Returns the UTC DateTime this event was generated. */
|
||||
abstract ZonedDateTime eventTime();
|
||||
abstract DateTime eventTime();
|
||||
|
||||
/** Returns the billed registrar's name. */
|
||||
abstract String registrarId();
|
||||
@@ -132,10 +132,8 @@ public abstract class BillingEvent implements Serializable {
|
||||
// Objects, which contain a string representation of their underlying types.
|
||||
Long.parseLong(extractField(record, "id")),
|
||||
// Bigquery provides UNIX timestamps with microsecond precision.
|
||||
Instant.ofEpochMilli(Long.parseLong(extractField(record, "billingTime")) / 1000)
|
||||
.atZone(ZoneId.of("UTC")),
|
||||
Instant.ofEpochMilli(Long.parseLong(extractField(record, "eventTime")) / 1000)
|
||||
.atZone(ZoneId.of("UTC")),
|
||||
new DateTime(Long.parseLong(extractField(record, "billingTime")) / 1000, DateTimeZone.UTC),
|
||||
new DateTime(Long.parseLong(extractField(record, "eventTime")) / 1000, DateTimeZone.UTC),
|
||||
extractField(record, "registrarId"),
|
||||
extractField(record, "billingId"),
|
||||
extractField(record, "poNumber"),
|
||||
@@ -180,8 +178,8 @@ public abstract class BillingEvent implements Serializable {
|
||||
@VisibleForTesting
|
||||
static BillingEvent create(
|
||||
long id,
|
||||
ZonedDateTime billingTime,
|
||||
ZonedDateTime eventTime,
|
||||
DateTime billingTime,
|
||||
DateTime eventTime,
|
||||
String registrarId,
|
||||
String billingId,
|
||||
String poNumber,
|
||||
@@ -231,8 +229,8 @@ public abstract class BillingEvent implements Serializable {
|
||||
.join(
|
||||
ImmutableList.of(
|
||||
id(),
|
||||
DATE_TIME_FORMATTER.format(billingTime()),
|
||||
DATE_TIME_FORMATTER.format(eventTime()),
|
||||
DATE_TIME_FORMATTER.print(billingTime()),
|
||||
DATE_TIME_FORMATTER.print(eventTime()),
|
||||
registrarId(),
|
||||
billingId(),
|
||||
poNumber(),
|
||||
|
||||
@@ -27,14 +27,12 @@ import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||
import google.registry.reporting.billing.BillingModule;
|
||||
import google.registry.util.DateTimeUtils;
|
||||
import google.registry.util.DomainNameUtils;
|
||||
import google.registry.util.SqlTemplate;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -123,8 +121,8 @@ public class InvoicingPipeline implements Serializable {
|
||||
return Optional.of(
|
||||
BillingEvent.create(
|
||||
oneTime.getId(),
|
||||
DateTimeUtils.toZonedDateTime(oneTime.getBillingTime(), ZoneId.of("UTC")),
|
||||
DateTimeUtils.toZonedDateTime(oneTime.getEventTime(), ZoneId.of("UTC")),
|
||||
oneTime.getBillingTime(),
|
||||
oneTime.getEventTime(),
|
||||
registrar.getRegistrarId(),
|
||||
registrar.getBillingAccountMap().get(currency),
|
||||
registrar.getPoNumber().orElse(""),
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.model;
|
||||
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.util.PreconditionsUtils;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
@@ -44,6 +45,7 @@ public abstract class BackupGroupRoot extends ImmutableObject implements UnsafeS
|
||||
// require an unnecessary non-private setter method.
|
||||
@Access(AccessType.FIELD)
|
||||
@AttributeOverride(name = "lastUpdateTime", column = @Column(name = "updateTimestamp"))
|
||||
@Ignore
|
||||
UpdateAutoTimestamp updateTimestamp = UpdateAutoTimestamp.create(null);
|
||||
|
||||
/** Get the {@link UpdateAutoTimestamp} for this entity. */
|
||||
|
||||
@@ -10,73 +10,43 @@
|
||||
// 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.
|
||||
// limitations under the Licenseschema..
|
||||
|
||||
package google.registry.model;
|
||||
|
||||
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.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.persistence.PreUpdate;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A timestamp that auto-updates when first saved to Datastore.
|
||||
*
|
||||
* @see CreateAutoTimestampTranslatorFactory
|
||||
*/
|
||||
/** A timestamp that auto-updates when first saved to Datastore. */
|
||||
@Embeddable
|
||||
public class CreateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@Transient DateTime timestamp;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Ignore
|
||||
ZonedDateTime creationTime;
|
||||
DateTime creationTime;
|
||||
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
void setTimestamp() {
|
||||
if (creationTime == null) {
|
||||
timestamp = 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);
|
||||
creationTime = jpaTm().getTransactionTime();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the timestamp. */
|
||||
@Nullable
|
||||
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();
|
||||
instance.timestamp = timestamp;
|
||||
instance.creationTime = (timestamp == null) ? null : DateTimeUtils.toZonedDateTime(timestamp);
|
||||
instance.creationTime = creationTime;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.config.RegistryConfig;
|
||||
import google.registry.model.CacheUtils.AppEngineEnvironmentCacheLoader;
|
||||
@@ -111,7 +112,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
* resource fields.
|
||||
*/
|
||||
@AttributeOverrides(@AttributeOverride(name = "creationTime", column = @Column))
|
||||
@Index
|
||||
@Ignore
|
||||
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).
|
||||
*/
|
||||
public static String getSchema() {
|
||||
return getAllPersistedTypes()
|
||||
.stream()
|
||||
return getAllPersistedTypes().stream()
|
||||
.filter(or(subtypeOf(Enum.class), subtypeOf(ImmutableObject.class)))
|
||||
.map(ModelUtils::getSchema)
|
||||
.collect(joining("\n"));
|
||||
|
||||
@@ -17,23 +17,15 @@ package google.registry.model;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
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 javax.annotation.Nullable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.persistence.PreUpdate;
|
||||
import javax.persistence.Transient;
|
||||
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
|
||||
public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@@ -42,11 +34,8 @@ public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerial
|
||||
// during a replay).
|
||||
private static final ThreadLocal<Boolean> autoUpdateEnabled = ThreadLocal.withInitial(() -> true);
|
||||
|
||||
@Transient DateTime timestamp;
|
||||
|
||||
@Ignore
|
||||
@Column(nullable = false)
|
||||
ZonedDateTime lastUpdateTime;
|
||||
DateTime lastUpdateTime;
|
||||
|
||||
// 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
|
||||
@@ -55,34 +44,18 @@ public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerial
|
||||
@PreUpdate
|
||||
void setTimestamp() {
|
||||
if (autoUpdateEnabled() || lastUpdateTime == null) {
|
||||
timestamp = 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);
|
||||
lastUpdateTime = jpaTm().getTransactionTime();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
||||
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) {
|
||||
UpdateAutoTimestamp instance = new UpdateAutoTimestamp();
|
||||
instance.timestamp = timestamp;
|
||||
instance.lastUpdateTime = timestamp == null ? null : DateTimeUtils.toZonedDateTime(timestamp);
|
||||
instance.lastUpdateTime = timestamp;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,12 @@ package google.registry.model.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import static google.registry.util.DateTimeUtils.toZonedDateTime;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UpdateAutoTimestamp;
|
||||
import google.registry.util.DateTimeUtils;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeOverride;
|
||||
@@ -109,19 +106,19 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
|
||||
private CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
* 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. */
|
||||
@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. */
|
||||
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. */
|
||||
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.
|
||||
*/
|
||||
public Optional<DateTime> getUnlockCompletionTime() {
|
||||
return Optional.ofNullable(unlockCompletionTime).map(DateTimeUtils::toJodaDateTime);
|
||||
return Optional.ofNullable(unlockCompletionTime);
|
||||
}
|
||||
|
||||
public String getVerificationCode() {
|
||||
@@ -278,17 +275,17 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
|
||||
}
|
||||
|
||||
public Builder setUnlockRequestTime(DateTime unlockRequestTime) {
|
||||
getInstance().unlockRequestTime = toZonedDateTime(unlockRequestTime);
|
||||
getInstance().unlockRequestTime = unlockRequestTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setLockCompletionTime(DateTime lockCompletionTime) {
|
||||
getInstance().lockCompletionTime = toZonedDateTime(lockCompletionTime);
|
||||
getInstance().lockCompletionTime = lockCompletionTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUnlockCompletionTime(DateTime unlockCompletionTime) {
|
||||
getInstance().unlockCompletionTime = toZonedDateTime(unlockCompletionTime);
|
||||
getInstance().unlockCompletionTime = unlockCompletionTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.google.common.collect.Range;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.OnLoad;
|
||||
import google.registry.flows.EppException;
|
||||
@@ -138,7 +139,7 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||
@Nullable @Index String domainName;
|
||||
|
||||
/** 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. */
|
||||
@Column(name = "allowedRegistrarIds")
|
||||
|
||||
@@ -38,7 +38,6 @@ import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.annotations.DeleteAfterMigration;
|
||||
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
|
||||
import google.registry.model.translators.CidrAddressBlockTranslatorFactory;
|
||||
import google.registry.model.translators.CreateAutoTimestampTranslatorFactory;
|
||||
import google.registry.model.translators.CurrencyUnitTranslatorFactory;
|
||||
import google.registry.model.translators.DurationTranslatorFactory;
|
||||
import google.registry.model.translators.EppHistoryVKeyTranslatorFactory;
|
||||
@@ -122,7 +121,6 @@ public class ObjectifyService {
|
||||
ImmutableList.of(
|
||||
new BloomFilterOfStringTranslatorFactory(),
|
||||
new CidrAddressBlockTranslatorFactory(),
|
||||
new CreateAutoTimestampTranslatorFactory(),
|
||||
new CurrencyUnitTranslatorFactory(),
|
||||
new DurationTranslatorFactory(),
|
||||
new EppHistoryVKeyTranslatorFactory(),
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.google.re2j.Pattern;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
@@ -407,10 +408,10 @@ public class Registrar extends ImmutableObject
|
||||
// Metadata.
|
||||
|
||||
/** The time when this registrar was created. */
|
||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||
@Ignore CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
/** 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. */
|
||||
DateTime lastCertificateUpdateTime;
|
||||
|
||||
-58
@@ -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.TldStateTransitionConverter</class>
|
||||
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
|
||||
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
||||
|
||||
<!-- Generated converters for VKey -->
|
||||
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
||||
|
||||
Reference in New Issue
Block a user