mirror of
https://github.com/google/nomulus.git
synced 2025-07-19 17:26:09 +02:00
Generate sql schema for PollMessage (#582)
* Generate sql schema for PollMessage * Rework columns and resolve comments * Fix datastore schema
This commit is contained in:
parent
b42ded9451
commit
b1241b98b2
12 changed files with 424 additions and 16 deletions
|
@ -19,6 +19,7 @@ import com.googlecode.objectify.annotation.Embed;
|
|||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseData;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
@ -29,11 +30,12 @@ import org.joda.time.DateTime;
|
|||
|
||||
/** The {@link ResponseData} returned when completing a pending action on a domain. */
|
||||
@XmlTransient
|
||||
public abstract class PendingActionNotificationResponse
|
||||
extends ImmutableObject implements ResponseData {
|
||||
@Embeddable
|
||||
public class PendingActionNotificationResponse extends ImmutableObject implements ResponseData {
|
||||
|
||||
/** The inner name type that contains a name and the result boolean. */
|
||||
@Embed
|
||||
@Embeddable
|
||||
static class NameOrId extends ImmutableObject {
|
||||
@XmlValue
|
||||
String value;
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.googlecode.objectify.Key;
|
|||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.Buildable;
|
||||
|
@ -39,10 +40,23 @@ import google.registry.model.poll.PendingActionNotificationResponse.DomainPendin
|
|||
import google.registry.model.poll.PendingActionNotificationResponse.HostPendingActionNotificationResponse;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferResponse.ContactTransferResponse;
|
||||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.persistence.WithLongVKey;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
|
@ -68,28 +82,52 @@ import org.joda.time.DateTime;
|
|||
@Entity
|
||||
@ReportedOn
|
||||
@ExternalMessagingName("message")
|
||||
@javax.persistence.Entity
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
@DiscriminatorColumn(name = "type")
|
||||
@javax.persistence.Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrar_id"),
|
||||
@javax.persistence.Index(columnList = "eventTime")
|
||||
})
|
||||
public abstract class PollMessage extends ImmutableObject
|
||||
implements Buildable, TransferServerApproveEntity {
|
||||
|
||||
/** Entity id. */
|
||||
@Id
|
||||
long id;
|
||||
@javax.persistence.Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "poll_message_id")
|
||||
Long id;
|
||||
|
||||
@Parent
|
||||
@DoNotHydrate
|
||||
Key<HistoryEntry> parent;
|
||||
@Parent @DoNotHydrate @Transient Key<HistoryEntry> parent;
|
||||
|
||||
/** The registrar that this poll message will be delivered to. */
|
||||
@Index
|
||||
@Column(name = "registrar_id", nullable = false)
|
||||
String clientId;
|
||||
|
||||
/** The time when the poll message should be delivered. May be in the future. */
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
DateTime eventTime;
|
||||
|
||||
/** Human readable message that will be returned with this poll message. */
|
||||
@Column(name = "message")
|
||||
String msg;
|
||||
|
||||
@Ignore String domainRepoId;
|
||||
|
||||
@Ignore String contactRepoId;
|
||||
|
||||
@Ignore String hostRepoId;
|
||||
|
||||
@Ignore Long domainRevisionId;
|
||||
|
||||
@Ignore Long contactRevisionId;
|
||||
|
||||
@Ignore Long hostRevisionId;
|
||||
|
||||
public Key<HistoryEntry> getParentKey() {
|
||||
return parent;
|
||||
}
|
||||
|
@ -180,15 +218,78 @@ public abstract class PollMessage extends ImmutableObject
|
|||
* <p>One-time poll messages are deleted from Datastore once they have been delivered and ACKed.
|
||||
*/
|
||||
@EntitySubclass(index = false)
|
||||
@javax.persistence.Entity
|
||||
@DiscriminatorValue("ONE_TIME")
|
||||
@WithLongVKey
|
||||
public static class OneTime extends PollMessage {
|
||||
|
||||
// Response data. Objectify cannot persist a base class type, so we must have a separate field
|
||||
// to hold every possible derived type of ResponseData that we might store.
|
||||
@Transient
|
||||
List<ContactPendingActionNotificationResponse> contactPendingActionNotificationResponses;
|
||||
List<ContactTransferResponse> contactTransferResponses;
|
||||
|
||||
@Transient List<ContactTransferResponse> contactTransferResponses;
|
||||
|
||||
@Transient
|
||||
List<DomainPendingActionNotificationResponse> domainPendingActionNotificationResponses;
|
||||
List<DomainTransferResponse> domainTransferResponses;
|
||||
List<HostPendingActionNotificationResponse> hostPendingActionNotificationResponses;
|
||||
|
||||
@Transient List<DomainTransferResponse> domainTransferResponses;
|
||||
|
||||
@Transient List<HostPendingActionNotificationResponse> hostPendingActionNotificationResponses;
|
||||
|
||||
@Ignore
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
name = "nameOrId.value",
|
||||
column = @Column(name = "pending_action_response_name_or_id")),
|
||||
@AttributeOverride(
|
||||
name = "nameOrId.actionResult",
|
||||
column = @Column(name = "pending_action_response_action_result")),
|
||||
@AttributeOverride(
|
||||
name = "trid.serverTransactionId",
|
||||
column = @Column(name = "pending_action_response_server_txn_id")),
|
||||
@AttributeOverride(
|
||||
name = "trid.clientTransactionId",
|
||||
column = @Column(name = "pending_action_response_client_txn_id")),
|
||||
@AttributeOverride(
|
||||
name = "processedDate",
|
||||
column = @Column(name = "pending_action_response_processed_date"))
|
||||
})
|
||||
PendingActionNotificationResponse pendingActionNotificationResponse;
|
||||
|
||||
@Ignore
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
name = "transferStatus",
|
||||
column = @Column(name = "transfer_response_transfer_status")),
|
||||
@AttributeOverride(
|
||||
name = "gainingClientId",
|
||||
column = @Column(name = "transfer_response_gaining_registrar_id")),
|
||||
@AttributeOverride(
|
||||
name = "transferRequestTime",
|
||||
column = @Column(name = "transfer_response_transfer_request_time")),
|
||||
@AttributeOverride(
|
||||
name = "losingClientId",
|
||||
column = @Column(name = "transfer_response_losing_registrar_id")),
|
||||
@AttributeOverride(
|
||||
name = "pendingTransferExpirationTime",
|
||||
column = @Column(name = "transfer_response_pending_transfer_expiration_time"))
|
||||
})
|
||||
TransferResponse transferResponse;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_domain_name")
|
||||
String fullyQualifiedDomainName;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_domain_expiration_time")
|
||||
DateTime extendedRegistrationExpirationTime;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_contact_id")
|
||||
String contactId;
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
|
@ -265,9 +366,13 @@ public abstract class PollMessage extends ImmutableObject
|
|||
* happens.
|
||||
*/
|
||||
@EntitySubclass(index = false)
|
||||
@javax.persistence.Entity
|
||||
@DiscriminatorValue("AUTORENEW")
|
||||
@WithLongVKey
|
||||
public static class Autorenew extends PollMessage {
|
||||
|
||||
/** The target id of the autorenew event. */
|
||||
@Column(name = "autorenew_domain_name")
|
||||
String targetId;
|
||||
|
||||
/** The autorenew recurs annually between {@link #eventTime} and this time. */
|
||||
|
|
|
@ -16,6 +16,8 @@ package google.registry.model.transfer;
|
|||
|
||||
import google.registry.model.Buildable.GenericBuilder;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
@ -31,6 +33,7 @@ public abstract class BaseTransferObject extends ImmutableObject {
|
|||
* will always be non-null.
|
||||
*/
|
||||
@XmlElement(name = "trStatus")
|
||||
@Enumerated(EnumType.STRING)
|
||||
TransferStatus transferStatus;
|
||||
|
||||
/** The gaining registrar of the current or last transfer. Can be null if never transferred. */
|
||||
|
|
|
@ -17,6 +17,7 @@ package google.registry.model.transfer;
|
|||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseData;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
@ -28,7 +29,8 @@ import org.joda.time.DateTime;
|
|||
* are common to all transfer responses; derived classes add resource specific fields.
|
||||
*/
|
||||
@XmlTransient
|
||||
public abstract class TransferResponse extends BaseTransferObject implements ResponseData {
|
||||
@Embeddable
|
||||
public class TransferResponse extends BaseTransferObject implements ResponseData {
|
||||
|
||||
/** An adapter to output the XML in response to a transfer command on a domain. */
|
||||
@Embed
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
<class>google.registry.schema.tld.ReservedList</class>
|
||||
<class>google.registry.model.domain.secdns.DelegationSignerData</class>
|
||||
<class>google.registry.model.domain.GracePeriod</class>
|
||||
<class>google.registry.model.poll.PollMessage</class>
|
||||
<class>google.registry.model.poll.PollMessage$OneTime</class>
|
||||
<class>google.registry.model.poll.PollMessage$Autorenew</class>
|
||||
|
||||
<!-- Customized type converters -->
|
||||
<class>google.registry.persistence.converter.BillingCostTransitionConverter</class>
|
||||
|
|
|
@ -16,24 +16,31 @@ package google.registry.model.poll;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import google.registry.persistence.VKey;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link PollMessage}. */
|
||||
public class PollMessageTest extends EntityTestCase {
|
||||
|
||||
HistoryEntry historyEntry;
|
||||
|
||||
@Before
|
||||
public PollMessageTest() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
createTld("foobar");
|
||||
historyEntry =
|
||||
|
@ -52,6 +59,50 @@ public class PollMessageTest extends EntityTestCase {
|
|||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistenceOneTime() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
PollMessage.OneTime pollMessage =
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setClientId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
pollMessage.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(pollMessage));
|
||||
PollMessage.OneTime persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(PollMessage.OneTime.class, pollMessage.id)));
|
||||
persisted.id = pollMessage.id;
|
||||
persisted.parent = pollMessage.parent;
|
||||
assertThat(persisted).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistenceAutorenew() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
PollMessage.Autorenew pollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setClientId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.setAutorenewEndTime(fakeClock.nowUtc().plusDays(365))
|
||||
.setTargetId("foobar.foo")
|
||||
.build();
|
||||
pollMessage.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(pollMessage));
|
||||
PollMessage.Autorenew persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(PollMessage.Autorenew.class, pollMessage.id)));
|
||||
persisted.id = pollMessage.id;
|
||||
persisted.parent = pollMessage.parent;
|
||||
assertThat(persisted).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistenceOneTime() {
|
||||
PollMessage.OneTime pollMessage =
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import org.junit.rules.ExternalResource;
|
||||
|
||||
|
@ -46,6 +47,7 @@ public class JpaEntityCoverage extends ExternalResource {
|
|||
PersistenceXmlUtility.getManagedClasses().stream()
|
||||
.filter(e -> !IGNORE_ENTITIES.contains(e.getSimpleName()))
|
||||
.filter(e -> e.isAnnotationPresent(Entity.class))
|
||||
.filter(e -> !e.isAnnotationPresent(DiscriminatorValue.class))
|
||||
.collect(ImmutableSet.toImmutableSet());
|
||||
private static final Set<Class> allCoveredJpaEntities = Sets.newHashSet();
|
||||
// Map of test class name to boolean flag indicating if it tests any JPA entities.
|
||||
|
|
|
@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assert_;
|
|||
import google.registry.model.billing.BillingEventTest;
|
||||
import google.registry.model.contact.ContactResourceTest;
|
||||
import google.registry.model.domain.DomainBaseSqlTest;
|
||||
import google.registry.model.poll.PollMessageTest;
|
||||
import google.registry.model.registry.RegistryLockDaoTest;
|
||||
import google.registry.persistence.transaction.JpaEntityCoverage;
|
||||
import google.registry.schema.cursor.CursorDaoTest;
|
||||
|
@ -75,6 +76,7 @@ import org.junit.runner.RunWith;
|
|||
CursorDaoTest.class,
|
||||
DomainBaseSqlTest.class,
|
||||
LockDaoTest.class,
|
||||
PollMessageTest.class,
|
||||
PremiumListDaoTest.class,
|
||||
RegistrarDaoTest.class,
|
||||
RegistryLockDaoTest.class,
|
||||
|
|
|
@ -373,14 +373,14 @@ class google.registry.model.poll.PendingActionNotificationResponse$NameOrId {
|
|||
java.lang.String value;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage {
|
||||
@Id long id;
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.reporting.HistoryEntry> parent;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage$Autorenew {
|
||||
@Id long id;
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.reporting.HistoryEntry> parent;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
|
@ -389,7 +389,7 @@ class google.registry.model.poll.PollMessage$Autorenew {
|
|||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage$OneTime {
|
||||
@Id long id;
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.reporting.HistoryEntry> parent;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue