mirror of
https://github.com/google/nomulus
synced 2026-07-10 18:13:02 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 17a1387184 | |||
| 2e230664fd | |||
| 299b093f78 | |||
| 61e7fa89f7 | |||
| 6ab69d4226 | |||
| 0f09a4a0ab | |||
| 95f6ccc657 | |||
| 77fabe4dc4 | |||
| 71fa12f773 | |||
| fd40a6a2b9 | |||
| 71f86c9970 | |||
| 6f75dfd116 |
+1
-1
@@ -191,7 +191,7 @@ allprojects {
|
||||
}
|
||||
|
||||
task runPresubmits(type: Exec) {
|
||||
executable '/usr/bin/python'
|
||||
executable '/usr/bin/python3'
|
||||
args('config/presubmits.py')
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Error Prone) so we must write them manually.
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import List, Tuple
|
||||
import sys
|
||||
import re
|
||||
|
||||
@@ -178,6 +179,90 @@ PRESUBMITS = {
|
||||
"JavaScript files should not include console logging."
|
||||
}
|
||||
|
||||
# Note that this regex only works for one kind of Flyway file. If we want to
|
||||
# start using "R" and "U" files we'll need to update this script.
|
||||
FLYWAY_FILE_RX = re.compile(r'V(\d+)__.*')
|
||||
|
||||
|
||||
def get_seqnum(filename: str, location: str) -> int:
|
||||
"""Extracts the sequence number from a filename."""
|
||||
m = FLYWAY_FILE_RX.match(filename)
|
||||
if m is None:
|
||||
raise ValueError('Illegal Flyway filename: %s in %s' % (filename, location))
|
||||
return int(m.group(1))
|
||||
|
||||
|
||||
def files_by_seqnum(files: List[str], location: str) -> List[Tuple[int, str]]:
|
||||
"""Returns the list of seqnum, filename sorted by sequence number."""
|
||||
return [(get_seqnum(filename, location), filename) for filename in files]
|
||||
|
||||
|
||||
def has_valid_order(indexed_files: List[Tuple[int, str]], location: str) -> bool:
|
||||
"""Verify that sequence numbers are in order without gaps or duplicates.
|
||||
|
||||
Args:
|
||||
files: List of seqnum, filename for a list of Flyway files.
|
||||
location: Where the list of files came from (for error reporting).
|
||||
|
||||
Returns:
|
||||
True if the file list is valid.
|
||||
"""
|
||||
last_index = 0
|
||||
valid = True
|
||||
for seqnum, filename in indexed_files:
|
||||
if seqnum == last_index:
|
||||
print('duplicate Flyway file sequence number found in %s: %s' %
|
||||
(location, filename))
|
||||
valid = False
|
||||
elif seqnum < last_index:
|
||||
print('File %s in %s is out of order.' % (filename, location))
|
||||
valid = False
|
||||
elif seqnum != last_index + 1:
|
||||
print('Missing Flyway sequence number %d in %s. Next file is %s' %
|
||||
(last_index + 1, location, filename))
|
||||
valid = False
|
||||
last_index = seqnum
|
||||
return valid
|
||||
|
||||
|
||||
def verify_flyway_index():
|
||||
"""Verifies that the Flyway index file is in sync with the directory."""
|
||||
success = True
|
||||
|
||||
# Sort the files in the Flyway directory by their sequence number.
|
||||
files = sorted(
|
||||
files_by_seqnum(os.listdir('db/src/main/resources/sql/flyway'),
|
||||
'Flyway directory'))
|
||||
|
||||
# Make sure that there are no gaps and no duplicate sequence numbers in the
|
||||
# files themselves.
|
||||
if not has_valid_order(files, 'Flyway directory'):
|
||||
success = False
|
||||
|
||||
# Remove the sequence numbers and compare against the index file contents.
|
||||
files = [filename[1] for filename in sorted(files)]
|
||||
with open('db/src/main/resources/sql/flyway.txt') as index:
|
||||
indexed_files = index.read().splitlines()
|
||||
if files != indexed_files:
|
||||
unindexed = set(files) - set(indexed_files)
|
||||
if unindexed:
|
||||
print('The following Flyway files are not in flyway.txt: %s' % unindexed)
|
||||
|
||||
nonexistent = set(indexed_files) - set(files)
|
||||
if nonexistent:
|
||||
print('The following files are in flyway.txt but not in the Flyway '
|
||||
'directory: %s' % nonexistent)
|
||||
|
||||
# Do an ordering check on the index file (ignore the result, we're failing
|
||||
# anyway).
|
||||
has_valid_order(files_by_seqnum(indexed_files, 'flyway.txt'), 'flyway.txt')
|
||||
success = False
|
||||
|
||||
if not success:
|
||||
print('Please fix any conflicts and run "./nom_build :db:generateFlywayIndex"')
|
||||
|
||||
return not success
|
||||
|
||||
|
||||
def get_files():
|
||||
for root, dirnames, filenames in os.walk("."):
|
||||
@@ -197,5 +282,10 @@ if __name__ == "__main__":
|
||||
failed = True
|
||||
print("%s had errors: \n %s" % (file, "\n ".join(error_messages)))
|
||||
|
||||
# And now for something completely different: check to see if the Flyway
|
||||
# index is up-to-date. It's quicker to do it here than in the unit tests:
|
||||
# when we put it here it fails fast before all of the tests are run.
|
||||
failed |= verify_flyway_index()
|
||||
|
||||
if failed:
|
||||
sys.exit(1)
|
||||
|
||||
@@ -202,6 +202,7 @@ org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -200,6 +200,7 @@ org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -204,6 +204,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -202,6 +202,7 @@ org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -201,6 +201,7 @@ org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -55,7 +55,7 @@ FROM (
|
||||
FROM
|
||||
`%PROJECT_ID%.%DATASTORE_EXPORT_DATA_SET%.%REGISTRY_TABLE%`
|
||||
WHERE
|
||||
enableInvoicing IS TRUE) ) AS BillingEvent
|
||||
invoicingEnabled IS TRUE) ) AS BillingEvent
|
||||
-- Gather billing ID from registrar table
|
||||
-- This is a 'JOIN' as opposed to 'LEFT JOIN' to filter out
|
||||
-- non-billable registrars
|
||||
|
||||
@@ -252,7 +252,8 @@ public final class OteAccountBuilder {
|
||||
private void saveAllEntities() {
|
||||
tm().assertInTransaction();
|
||||
|
||||
ImmutableList<Registry> registries = ImmutableList.of(sunriseTld, gaTld, eapTld);
|
||||
// use ImmutableObject instead of Registry so that the Key generation doesn't break
|
||||
ImmutableList<ImmutableObject> registries = ImmutableList.of(sunriseTld, gaTld, eapTld);
|
||||
ImmutableList<RegistrarContact> contacts = contactsBuilder.build();
|
||||
|
||||
if (!replaceExisting) {
|
||||
|
||||
@@ -67,7 +67,6 @@ import org.joda.time.DateTime;
|
||||
|
||||
/** A billable event in a domain's lifecycle. */
|
||||
@MappedSuperclass
|
||||
@WithLongVKey
|
||||
public abstract class BillingEvent extends ImmutableObject
|
||||
implements Buildable, TransferServerApproveEntity {
|
||||
|
||||
@@ -292,6 +291,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
@javax.persistence.Index(columnList = "allocation_token_id")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_event_id"))
|
||||
@WithLongVKey
|
||||
public static class OneTime extends BillingEvent implements DatastoreAndSqlEntity {
|
||||
|
||||
/** The billable value. */
|
||||
@@ -327,7 +327,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
* Cancellation}s.
|
||||
*/
|
||||
@Column(name = "cancellation_matching_billing_recurrence_id")
|
||||
VKey<? extends BillingEvent> cancellationMatchingBillingEvent;
|
||||
VKey<Recurring> cancellationMatchingBillingEvent;
|
||||
|
||||
/**
|
||||
* The {@link AllocationToken} used in the creation of this event, or null if one was not used.
|
||||
@@ -409,7 +409,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
|
||||
public Builder setCancellationMatchingBillingEvent(
|
||||
VKey<? extends BillingEvent> cancellationMatchingBillingEvent) {
|
||||
VKey<Recurring> cancellationMatchingBillingEvent) {
|
||||
getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent;
|
||||
return this;
|
||||
}
|
||||
@@ -468,6 +468,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
@javax.persistence.Index(columnList = "recurrence_time_of_year")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id"))
|
||||
@WithLongVKey
|
||||
public static class Recurring extends BillingEvent implements DatastoreAndSqlEntity {
|
||||
|
||||
/**
|
||||
@@ -562,6 +563,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
@javax.persistence.Index(columnList = "billingTime")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id"))
|
||||
@WithLongVKey
|
||||
public static class Cancellation extends BillingEvent implements DatastoreAndSqlEntity {
|
||||
|
||||
/** The billing time of the charge that is being cancelled. */
|
||||
@@ -682,6 +684,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
/** An event representing a modification of an existing one-time billing event. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@WithLongVKey
|
||||
public static class Modification extends BillingEvent implements DatastoreAndSqlEntity {
|
||||
|
||||
/** The change in cost that should be applied to the original billing event. */
|
||||
|
||||
@@ -14,20 +14,25 @@
|
||||
|
||||
package google.registry.model.contact;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.contact.ContactHistory.ContactHistoryId;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.schema.replay.DatastoreEntity;
|
||||
import google.registry.schema.replay.SqlEntity;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.PostLoad;
|
||||
|
||||
/**
|
||||
@@ -47,16 +52,15 @@ import javax.persistence.PostLoad;
|
||||
})
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
public class ContactHistory extends HistoryEntry {
|
||||
@IdClass(ContactHistoryId.class)
|
||||
public class ContactHistory extends HistoryEntry implements SqlEntity {
|
||||
|
||||
// Store ContactBase instead of ContactResource so we don't pick up its @Id
|
||||
@Nullable ContactBase contactBase;
|
||||
|
||||
@Column(nullable = false)
|
||||
VKey<ContactResource> contactRepoId;
|
||||
@Id String contactRepoId;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
|
||||
@Column(name = "historyRevisionId")
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Override
|
||||
@@ -76,7 +80,14 @@ public class ContactHistory extends HistoryEntry {
|
||||
|
||||
/** The key to the {@link ContactResource} this is based off of. */
|
||||
public VKey<ContactResource> getContactRepoId() {
|
||||
return contactRepoId;
|
||||
return VKey.create(
|
||||
ContactResource.class, contactRepoId, Key.create(ContactResource.class, contactRepoId));
|
||||
}
|
||||
|
||||
/** Creates a {@link VKey} instance for this entity. */
|
||||
public VKey<ContactHistory> createVKey() {
|
||||
return VKey.create(
|
||||
ContactHistory.class, new ContactHistoryId(contactRepoId, getId()), Key.create(this));
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
@@ -87,10 +98,71 @@ public class ContactHistory extends HistoryEntry {
|
||||
contactBase = null;
|
||||
}
|
||||
// Fill in the full, symmetric, parent repo ID key
|
||||
Key<ContactResource> parentKey =
|
||||
Key.create(ContactResource.class, (String) contactRepoId.getSqlKey());
|
||||
parent = parentKey;
|
||||
contactRepoId = VKey.create(ContactResource.class, contactRepoId.getSqlKey(), parentKey);
|
||||
parent = Key.create(ContactResource.class, contactRepoId);
|
||||
}
|
||||
|
||||
// In Datastore, save as a HistoryEntry object regardless of this object's type
|
||||
@Override
|
||||
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
|
||||
return ImmutableList.of(asHistoryEntry());
|
||||
}
|
||||
|
||||
/** Class to represent the composite primary key of {@link ContactHistory} entity. */
|
||||
static class ContactHistoryId extends ImmutableObject implements Serializable {
|
||||
|
||||
private String contactRepoId;
|
||||
|
||||
private Long id;
|
||||
|
||||
/** Hibernate requires this default constructor. */
|
||||
private ContactHistoryId() {}
|
||||
|
||||
ContactHistoryId(String contactRepoId, long id) {
|
||||
this.contactRepoId = contactRepoId;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contact repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private String getContactRepoId() {
|
||||
return contactRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contact repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setContactRepoId(String contactRepoId) {
|
||||
this.contactRepoId = contactRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,9 +183,9 @@ public class ContactHistory extends HistoryEntry {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setContactRepoId(VKey<ContactResource> contactRepoId) {
|
||||
public Builder setContactRepoId(String contactRepoId) {
|
||||
getInstance().contactRepoId = contactRepoId;
|
||||
contactRepoId.maybeGetOfyKey().ifPresent(parent -> getInstance().parent = parent);
|
||||
getInstance().parent = Key.create(ContactResource.class, contactRepoId);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -121,8 +193,7 @@ public class ContactHistory extends HistoryEntry {
|
||||
@Override
|
||||
public Builder setParent(Key<? extends EppResource> parent) {
|
||||
super.setParent(parent);
|
||||
getInstance().contactRepoId =
|
||||
VKey.create(ContactResource.class, parent.getName(), (Key<ContactResource>) parent);
|
||||
getInstance().contactRepoId = parent.getName();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ public class ContactResource extends ContactBase
|
||||
|
||||
@Override
|
||||
public VKey<ContactResource> createVKey() {
|
||||
// TODO(mmuller): create symmetric keys if we can ever reload both sides.
|
||||
return VKey.create(ContactResource.class, getRepoId(), Key.create(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.Table;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@@ -106,6 +107,12 @@ public class DomainBase extends DomainContent
|
||||
return gracePeriods;
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
private final void postLoad() {
|
||||
restoreOfyKeys(getRepoId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public VKey<DomainBase> createVKey() {
|
||||
return VKey.create(DomainBase.class, getRepoId(), Key.create(this));
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
@@ -49,6 +50,7 @@ import google.registry.flows.ResourceFlowUtils;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.EppResource.ResourceWithTransferData;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.launch.LaunchNotice;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
@@ -57,6 +59,7 @@ import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.DomainTransferData;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
@@ -209,6 +212,15 @@ public class DomainContent extends EppResource
|
||||
@Column(name = "deletion_poll_message_id")
|
||||
VKey<PollMessage.OneTime> deletePollMessage;
|
||||
|
||||
/**
|
||||
* History record for the delete poll message.
|
||||
*
|
||||
* <p>Here so we can restore the original ofy key from sql.
|
||||
*/
|
||||
@Column(name = "deletion_poll_message_history_id")
|
||||
@Ignore
|
||||
Long deletePollMessageHistoryId;
|
||||
|
||||
/**
|
||||
* The recurring billing event associated with this domain's autorenewals.
|
||||
*
|
||||
@@ -220,6 +232,15 @@ public class DomainContent extends EppResource
|
||||
@Column(name = "billing_recurrence_id")
|
||||
VKey<BillingEvent.Recurring> autorenewBillingEvent;
|
||||
|
||||
/**
|
||||
* History record for the autorenew billing event.
|
||||
*
|
||||
* <p>Here so we can restore the original ofy key from sql.
|
||||
*/
|
||||
@Column(name = "billing_recurrence_history_id")
|
||||
@Ignore
|
||||
Long autorenewBillingEventHistoryId;
|
||||
|
||||
/**
|
||||
* The recurring poll message associated with this domain's autorenewals.
|
||||
*
|
||||
@@ -231,6 +252,13 @@ public class DomainContent extends EppResource
|
||||
@Column(name = "autorenew_poll_message_id")
|
||||
VKey<PollMessage.Autorenew> autorenewPollMessage;
|
||||
|
||||
/**
|
||||
* History record for the autorenew poll message.
|
||||
*
|
||||
* <p>Here so we can restore the original ofy key from sql.
|
||||
*/
|
||||
@Ignore Long autorenewPollMessageHistoryId;
|
||||
|
||||
/** The unexpired grace periods for this domain (some of which may not be active yet). */
|
||||
@Transient Set<GracePeriod> gracePeriods;
|
||||
|
||||
@@ -284,10 +312,22 @@ public class DomainContent extends EppResource
|
||||
nullToEmptyImmutableCopy(gracePeriods).stream()
|
||||
.map(gracePeriod -> gracePeriod.cloneWithDomainRepoId(getRepoId()))
|
||||
.collect(toImmutableSet());
|
||||
|
||||
// Restore history record ids.
|
||||
autorenewPollMessageHistoryId = getHistoryId(autorenewPollMessage);
|
||||
autorenewBillingEventHistoryId = getHistoryId(autorenewBillingEvent);
|
||||
deletePollMessageHistoryId = getHistoryId(deletePollMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link javax.persistence.PostLoad} method for {@link DomainContent}.
|
||||
*
|
||||
* <p>We name this domainContentPostLoad to distinguish it from the {@link PostLoad} method in
|
||||
* DomainBase (if they share the same name, this one is never called).
|
||||
*/
|
||||
@PostLoad
|
||||
void postLoad() {
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
private final void domainContentPostLoad() {
|
||||
// Reconstitute the contact list.
|
||||
ImmutableSet.Builder<DesignatedContact> contactsBuilder = new ImmutableSet.Builder<>();
|
||||
|
||||
@@ -308,6 +348,48 @@ public class DomainContent extends EppResource
|
||||
allContacts = contactsBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the composite ofy keys from SQL data.
|
||||
*
|
||||
* <p>MUST ONLY BE CALLED FROM A PostLoad method. This is a package-visible method that
|
||||
* effectively mutates an immutable object.
|
||||
*
|
||||
* <p>We have to do this because:
|
||||
*
|
||||
* <ul>
|
||||
* <li>We've changed the {@link PostLoad} method behavior to make all {@link PostLoad} calls in
|
||||
* the class hierarchy (and not merely the most specific one) be called after an object is
|
||||
* loaded.
|
||||
* <li>When restoring a {@link DomainBase} object (which is a subclass) the repo id is not
|
||||
* populated until after our {@link PostLoad} method is called. Therefore, we need to
|
||||
* restore these ofy keys (which depend on the repo id) from {@link DomainBase}'s {@link
|
||||
* PostLoad} method.
|
||||
* <li>When restoring a {@link DomainHistory} object, hibernate restores a {@link DomainContent}
|
||||
* instance, therefore we need our own {@link PostLoad} method to restore the other fields.
|
||||
* In order to restore the ofy keys, we need to invoke this method separately from {@link
|
||||
* DomainHistory}'s {@link PostLoad} method and pass in the repo id, which is stored in a
|
||||
* different field in {@link DomainHistory}.
|
||||
* </ul>
|
||||
*/
|
||||
void restoreOfyKeys(String repoId) {
|
||||
// Reconstitute the ofy keys.
|
||||
Key<DomainBase> myKey = Key.create(DomainBase.class, repoId);
|
||||
deletePollMessage = restoreOfyFrom(myKey, deletePollMessage, deletePollMessageHistoryId);
|
||||
autorenewBillingEvent =
|
||||
restoreOfyFrom(myKey, autorenewBillingEvent, autorenewBillingEventHistoryId);
|
||||
autorenewPollMessage =
|
||||
restoreOfyFrom(myKey, autorenewPollMessage, autorenewPollMessageHistoryId);
|
||||
}
|
||||
|
||||
private <T> VKey<T> restoreOfyFrom(Key<DomainBase> domainKey, VKey<T> key, Long historyId) {
|
||||
if (historyId == null) {
|
||||
// This is a legacy key (or a null key, in which case this works too)
|
||||
return VKey.restoreOfyFrom(key, EntityGroupRoot.class, "per-tld");
|
||||
} else {
|
||||
return VKey.restoreOfyFrom(key, domainKey, HistoryEntry.class, historyId);
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableSet<String> getSubordinateHosts() {
|
||||
return nullToEmptyImmutableCopy(subordinateHosts);
|
||||
}
|
||||
@@ -655,6 +737,17 @@ public class DomainContent extends EppResource
|
||||
+ " use DomainBase instead");
|
||||
}
|
||||
|
||||
private static Long getHistoryId(VKey<?> key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Key<?> parent = key.getOfyKey().getParent();
|
||||
if (parent == null || parent.getKind().equals("EntityGroupRoot")) {
|
||||
return null;
|
||||
}
|
||||
return parent.getId();
|
||||
}
|
||||
|
||||
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
|
||||
static final Predicate<DesignatedContact> IS_REGISTRANT =
|
||||
(DesignatedContact contact) -> DesignatedContact.Type.REGISTRANT.equals(contact.type);
|
||||
@@ -824,16 +917,19 @@ public class DomainContent extends EppResource
|
||||
|
||||
public B setDeletePollMessage(VKey<PollMessage.OneTime> deletePollMessage) {
|
||||
getInstance().deletePollMessage = deletePollMessage;
|
||||
getInstance().deletePollMessageHistoryId = getHistoryId(deletePollMessage);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setAutorenewBillingEvent(VKey<BillingEvent.Recurring> autorenewBillingEvent) {
|
||||
getInstance().autorenewBillingEvent = autorenewBillingEvent;
|
||||
getInstance().autorenewBillingEventHistoryId = getHistoryId(autorenewBillingEvent);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setAutorenewPollMessage(VKey<PollMessage.Autorenew> autorenewPollMessage) {
|
||||
getInstance().autorenewPollMessage = autorenewPollMessage;
|
||||
getInstance().autorenewPollMessageHistoryId = getHistoryId(autorenewPollMessage);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.domain;
|
||||
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
@@ -26,6 +27,8 @@ import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.schema.replay.DatastoreEntity;
|
||||
import google.registry.schema.replay.SqlEntity;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -38,8 +41,6 @@ import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Index;
|
||||
@@ -67,7 +68,7 @@ import javax.persistence.Table;
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
@IdClass(DomainHistoryId.class)
|
||||
public class DomainHistory extends HistoryEntry {
|
||||
public class DomainHistory extends HistoryEntry implements SqlEntity {
|
||||
|
||||
// Store DomainContent instead of DomainBase so we don't pick up its @Id
|
||||
@Nullable DomainContent domainContent;
|
||||
@@ -128,7 +129,6 @@ public class DomainHistory extends HistoryEntry {
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
|
||||
@Column(name = "historyRevisionId")
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Override
|
||||
@@ -156,8 +156,10 @@ public class DomainHistory extends HistoryEntry {
|
||||
return VKey.create(DomainBase.class, domainRepoId, Key.create(DomainBase.class, domainRepoId));
|
||||
}
|
||||
|
||||
/** Creates a {@link VKey} instance for this entity. */
|
||||
public VKey<DomainHistory> createVKey() {
|
||||
return VKey.createSql(DomainHistory.class, new DomainHistoryId(domainRepoId, getId()));
|
||||
return VKey.create(
|
||||
DomainHistory.class, new DomainHistoryId(domainRepoId, getId()), Key.create(this));
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
@@ -168,11 +170,19 @@ public class DomainHistory extends HistoryEntry {
|
||||
// domainContent with a null object. Unfortunately, the updateTimestamp is never null in SQL.
|
||||
if (domainContent.getDomainName() == null) {
|
||||
domainContent = null;
|
||||
} else {
|
||||
domainContent.restoreOfyKeys(domainRepoId);
|
||||
}
|
||||
}
|
||||
parent = Key.create(DomainBase.class, domainRepoId);
|
||||
}
|
||||
|
||||
// In Datastore, save as a HistoryEntry object regardless of this object's type
|
||||
@Override
|
||||
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
|
||||
return ImmutableList.of(asHistoryEntry());
|
||||
}
|
||||
|
||||
/** Class to represent the composite primary key of {@link DomainHistory} entity. */
|
||||
static class DomainHistoryId extends ImmutableObject implements Serializable {
|
||||
|
||||
@@ -188,19 +198,45 @@ public class DomainHistory extends HistoryEntry {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
String getDomainRepoId() {
|
||||
/**
|
||||
* Returns the domain repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private String getDomainRepoId() {
|
||||
return domainRepoId;
|
||||
}
|
||||
|
||||
void setDomainRepoId(String domainRepoId) {
|
||||
this.domainRepoId = domainRepoId;
|
||||
}
|
||||
|
||||
long getId() {
|
||||
/**
|
||||
* Returns the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(long id) {
|
||||
/**
|
||||
* Sets the domain repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDomainRepoId(String domainRepoId) {
|
||||
this.domainRepoId = domainRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
@@ -37,7 +38,7 @@ import org.joda.time.DateTime;
|
||||
@Embed
|
||||
@Entity
|
||||
@Table(indexes = @Index(columnList = "domainRepoId"))
|
||||
public class GracePeriod extends GracePeriodBase {
|
||||
public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntity {
|
||||
|
||||
private static GracePeriod createInternal(
|
||||
GracePeriodStatus type,
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.domain.secdns;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
@@ -31,7 +32,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@Embed
|
||||
@XmlType(name = "dsData")
|
||||
@javax.persistence.Entity
|
||||
public class DelegationSignerData extends ImmutableObject {
|
||||
public class DelegationSignerData extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
|
||||
private DelegationSignerData() {}
|
||||
|
||||
|
||||
@@ -14,20 +14,26 @@
|
||||
|
||||
package google.registry.model.host;
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.host.HostHistory.HostHistoryId;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.schema.replay.DatastoreEntity;
|
||||
import google.registry.schema.replay.SqlEntity;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.PostLoad;
|
||||
|
||||
/**
|
||||
@@ -48,16 +54,15 @@ import javax.persistence.PostLoad;
|
||||
})
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
public class HostHistory extends HistoryEntry {
|
||||
@IdClass(HostHistoryId.class)
|
||||
public class HostHistory extends HistoryEntry implements SqlEntity {
|
||||
|
||||
// Store HostBase instead of HostResource so we don't pick up its @Id
|
||||
@Nullable HostBase hostBase;
|
||||
|
||||
@Column(nullable = false)
|
||||
VKey<HostResource> hostRepoId;
|
||||
@Id String hostRepoId;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
|
||||
@Column(name = "historyRevisionId")
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Override
|
||||
@@ -77,7 +82,12 @@ public class HostHistory extends HistoryEntry {
|
||||
|
||||
/** The key to the {@link google.registry.model.host.HostResource} this is based off of. */
|
||||
public VKey<HostResource> getHostRepoId() {
|
||||
return hostRepoId;
|
||||
return VKey.create(HostResource.class, hostRepoId, Key.create(HostResource.class, hostRepoId));
|
||||
}
|
||||
|
||||
/** Creates a {@link VKey} instance for this entity. */
|
||||
public VKey<HostHistory> createVKey() {
|
||||
return VKey.create(HostHistory.class, new HostHistoryId(hostRepoId, getId()), Key.create(this));
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
@@ -88,9 +98,71 @@ public class HostHistory extends HistoryEntry {
|
||||
hostBase = null;
|
||||
}
|
||||
// Fill in the full, symmetric, parent repo ID key
|
||||
Key<HostResource> parentKey = Key.create(HostResource.class, (String) hostRepoId.getSqlKey());
|
||||
parent = parentKey;
|
||||
hostRepoId = VKey.create(HostResource.class, hostRepoId.getSqlKey(), parentKey);
|
||||
parent = Key.create(HostResource.class, hostRepoId);
|
||||
}
|
||||
|
||||
// In Datastore, save as a HistoryEntry object regardless of this object's type
|
||||
@Override
|
||||
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
|
||||
return ImmutableList.of(asHistoryEntry());
|
||||
}
|
||||
|
||||
/** Class to represent the composite primary key of {@link HostHistory} entity. */
|
||||
static class HostHistoryId extends ImmutableObject implements Serializable {
|
||||
|
||||
private String hostRepoId;
|
||||
|
||||
private Long id;
|
||||
|
||||
/** Hibernate requires this default constructor. */
|
||||
private HostHistoryId() {}
|
||||
|
||||
HostHistoryId(String hostRepoId, long id) {
|
||||
this.hostRepoId = hostRepoId;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private String getHostRepoId() {
|
||||
return hostRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host repository id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setHostRepoId(String hostRepoId) {
|
||||
this.hostRepoId = hostRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the history revision id.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate and should not be used
|
||||
* externally to keep immutability.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,9 +183,9 @@ public class HostHistory extends HistoryEntry {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setHostRepoId(VKey<HostResource> hostRepoId) {
|
||||
public Builder setHostRepoId(String hostRepoId) {
|
||||
getInstance().hostRepoId = hostRepoId;
|
||||
hostRepoId.maybeGetOfyKey().ifPresent(parent -> getInstance().parent = parent);
|
||||
getInstance().parent = Key.create(HostResource.class, hostRepoId);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -121,8 +193,7 @@ public class HostHistory extends HistoryEntry {
|
||||
@Override
|
||||
public Builder setParent(Key<? extends EppResource> parent) {
|
||||
super.setParent(parent);
|
||||
getInstance().hostRepoId =
|
||||
VKey.create(HostResource.class, parent.getName(), (Key<HostResource>) parent);
|
||||
getInstance().hostRepoId = parent.getName();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,18 @@ 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.OnLoad;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.annotations.ExternalMessagingName;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainRenewData;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseData;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.ContactPendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.HostPendingActionNotificationResponse;
|
||||
@@ -54,10 +58,9 @@ 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.PostLoad;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@@ -98,7 +101,6 @@ public abstract class PollMessage extends ImmutableObject
|
||||
/** Entity id. */
|
||||
@Id
|
||||
@javax.persistence.Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "poll_message_id")
|
||||
Long id;
|
||||
|
||||
@@ -124,11 +126,11 @@ public abstract class PollMessage extends ImmutableObject
|
||||
|
||||
@Ignore String hostRepoId;
|
||||
|
||||
@Ignore Long domainRevisionId;
|
||||
@Ignore Long domainHistoryRevisionId;
|
||||
|
||||
@Ignore Long contactRevisionId;
|
||||
@Ignore Long contactHistoryRevisionId;
|
||||
|
||||
@Ignore Long hostRevisionId;
|
||||
@Ignore Long hostHistoryRevisionId;
|
||||
|
||||
public Key<HistoryEntry> getParentKey() {
|
||||
return parent;
|
||||
@@ -152,6 +154,34 @@ public abstract class PollMessage extends ImmutableObject
|
||||
|
||||
public abstract ImmutableList<ResponseData> getResponseData();
|
||||
|
||||
@PostLoad
|
||||
void postLoad() {
|
||||
if (domainRepoId != null) {
|
||||
parent =
|
||||
Key.create(
|
||||
Key.create(DomainBase.class, domainRepoId),
|
||||
HistoryEntry.class,
|
||||
domainHistoryRevisionId);
|
||||
} else if (contactRepoId != null) {
|
||||
parent =
|
||||
Key.create(
|
||||
Key.create(ContactResource.class, contactRepoId),
|
||||
HistoryEntry.class,
|
||||
contactHistoryRevisionId);
|
||||
} else if (hostHistoryRevisionId != null) {
|
||||
parent =
|
||||
Key.create(
|
||||
Key.create(HostResource.class, hostRepoId),
|
||||
HistoryEntry.class,
|
||||
hostHistoryRevisionId);
|
||||
}
|
||||
}
|
||||
|
||||
@OnLoad
|
||||
void onLoad() {
|
||||
setSqlForeignKeys(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract VKey<? extends PollMessage> createVKey();
|
||||
|
||||
@@ -217,10 +247,30 @@ public abstract class PollMessage extends ImmutableObject
|
||||
checkArgumentNotNull(instance.clientId, "clientId must be specified");
|
||||
checkArgumentNotNull(instance.eventTime, "eventTime must be specified");
|
||||
checkArgumentNotNull(instance.parent, "parent must be specified");
|
||||
checkArgumentNotNull(instance.parent.getParent(), "parent.getParent() must be specified");
|
||||
setSqlForeignKeys(instance);
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSqlForeignKeys(PollMessage pollMessage) {
|
||||
String grandparentKind = pollMessage.parent.getParent().getKind();
|
||||
String repoId = pollMessage.parent.getParent().getName();
|
||||
long historyRevisionId = pollMessage.parent.getId();
|
||||
if (Key.getKind(DomainBase.class).equals(grandparentKind)) {
|
||||
pollMessage.domainRepoId = repoId;
|
||||
pollMessage.domainHistoryRevisionId = historyRevisionId;
|
||||
} else if (Key.getKind(ContactResource.class).equals(grandparentKind)) {
|
||||
pollMessage.contactRepoId = repoId;
|
||||
pollMessage.contactHistoryRevisionId = historyRevisionId;
|
||||
} else if (Key.getKind(HostResource.class).equals(grandparentKind)) {
|
||||
pollMessage.hostRepoId = repoId;
|
||||
pollMessage.hostHistoryRevisionId = historyRevisionId;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown grandparent kind: " + grandparentKind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A one-time poll message.
|
||||
*
|
||||
|
||||
@@ -62,6 +62,7 @@ import google.registry.model.domain.fee.BaseFee.FeeType;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.registry.label.PremiumList;
|
||||
import google.registry.model.registry.label.ReservedList;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.util.Idn;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -86,7 +87,7 @@ import org.joda.time.Duration;
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "Tld")
|
||||
public class Registry extends ImmutableObject implements Buildable {
|
||||
public class Registry extends ImmutableObject implements Buildable, DatastoreAndSqlEntity {
|
||||
|
||||
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
@@ -43,7 +44,8 @@ import org.joda.time.DateTime;
|
||||
*/
|
||||
@Embed
|
||||
@Entity
|
||||
public class DomainTransactionRecord extends ImmutableObject implements Buildable {
|
||||
public class DomainTransactionRecord extends ImmutableObject
|
||||
implements Buildable, DatastoreAndSqlEntity {
|
||||
|
||||
@Id
|
||||
@Ignore
|
||||
|
||||
@@ -62,7 +62,7 @@ import org.joda.time.DateTime;
|
||||
@MappedSuperclass
|
||||
@WithStringVKey // TODO(b/162229294): This should be resolved during the course of that bug
|
||||
@Access(AccessType.FIELD)
|
||||
public class HistoryEntry extends ImmutableObject implements Buildable, DatastoreEntity, SqlEntity {
|
||||
public class HistoryEntry extends ImmutableObject implements Buildable, DatastoreEntity {
|
||||
|
||||
/** Represents the type of history entry. */
|
||||
public enum Type {
|
||||
@@ -308,19 +308,10 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
|
||||
new DomainHistory.Builder().copyFrom(this).setDomainRepoId(parent.getName()).build();
|
||||
} else if (parentKind.equals(getKind(HostResource.class))) {
|
||||
resultEntity =
|
||||
new HostHistory.Builder()
|
||||
.copyFrom(this)
|
||||
.setHostRepoId(
|
||||
VKey.create(HostResource.class, parent.getName(), (Key<HostResource>) parent))
|
||||
.build();
|
||||
new HostHistory.Builder().copyFrom(this).setHostRepoId(parent.getName()).build();
|
||||
} else if (parentKind.equals(getKind(ContactResource.class))) {
|
||||
resultEntity =
|
||||
new ContactHistory.Builder()
|
||||
.copyFrom(this)
|
||||
.setContactRepoId(
|
||||
VKey.create(
|
||||
ContactResource.class, parent.getName(), (Key<ContactResource>) parent))
|
||||
.build();
|
||||
new ContactHistory.Builder().copyFrom(this).setContactRepoId(parent.getName()).build();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
String.format("Unknown kind of HistoryEntry parent %s", parentKind));
|
||||
@@ -331,13 +322,7 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
|
||||
// In SQL, save the child type
|
||||
@Override
|
||||
public ImmutableList<SqlEntity> toSqlEntities() {
|
||||
return ImmutableList.of(toChildHistoryEntity());
|
||||
}
|
||||
|
||||
// In Datastore, save as a HistoryEntry object regardless of this object's type
|
||||
@Override
|
||||
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
|
||||
return ImmutableList.of(asHistoryEntry());
|
||||
return ImmutableList.of((SqlEntity) toChildHistoryEntity());
|
||||
}
|
||||
|
||||
/** A builder for {@link HistoryEntry} since it is immutable */
|
||||
|
||||
@@ -46,6 +46,7 @@ import google.registry.model.annotations.NotBackedUp;
|
||||
import google.registry.model.annotations.NotBackedUp.Reason;
|
||||
import google.registry.model.annotations.VirtualEntity;
|
||||
import google.registry.model.common.CrossTldSingleton;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.schema.replay.DatastoreEntity;
|
||||
import google.registry.schema.replay.SqlEntity;
|
||||
import google.registry.util.CollectionUtils;
|
||||
@@ -97,7 +98,7 @@ import org.joda.time.DateTime;
|
||||
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
|
||||
@javax.persistence.Entity(name = "ClaimsList")
|
||||
@Table
|
||||
public class ClaimsListShard extends ImmutableObject implements DatastoreEntity {
|
||||
public class ClaimsListShard extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
@@ -354,11 +355,6 @@ public class ClaimsListShard extends ImmutableObject implements DatastoreEntity
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<SqlEntity> toSqlEntities() {
|
||||
return ImmutableList.of(); // ClaimsLists are dually written
|
||||
}
|
||||
|
||||
/** Virtual parent entity for claims list shards of a specific revision. */
|
||||
@Entity
|
||||
@VirtualEntity
|
||||
|
||||
@@ -113,6 +113,83 @@ public class VKey<T> extends ImmutableObject implements Serializable {
|
||||
return new VKey<T>(kind, Key.create(kind, name), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with an ofy key restored from {@code ancestors}.
|
||||
*
|
||||
* <p>The arguments should generally consist of pairs of Class and value, where the Class is the
|
||||
* kind of the ancestor key and the value is either a String or a Long.
|
||||
*
|
||||
* <p>For example, to restore the objectify key for
|
||||
* DomainBase("COM-1234")/HistoryEntry(123)/PollEvent(567), one might use:
|
||||
*
|
||||
* <pre>{@code
|
||||
* pollEvent.restoreOfy(DomainBase.class, "COM-1234", HistoryEntry.class, 567)
|
||||
* }</pre>
|
||||
*
|
||||
* <p>The final key id or name is obtained from the SQL key. It is assumed that this value must be
|
||||
* either a long integer or a {@code String} and that this proper identifier for the objectify
|
||||
* key.
|
||||
*
|
||||
* <p>As a special case, an objectify Key may be used as the first ancestor instead of a Class,
|
||||
* value pair.
|
||||
*/
|
||||
public VKey<T> restoreOfy(Object... ancestors) {
|
||||
Class lastClass = null;
|
||||
Key<?> lastKey = null;
|
||||
for (Object ancestor : ancestors) {
|
||||
if (ancestor instanceof Class) {
|
||||
if (lastClass != null) {
|
||||
throw new IllegalArgumentException(ancestor + " used as a key value.");
|
||||
}
|
||||
lastClass = (Class) ancestor;
|
||||
continue;
|
||||
} else if (ancestor instanceof Key) {
|
||||
if (lastKey != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Objectify keys may only be used for the first argument");
|
||||
}
|
||||
lastKey = (Key) ancestor;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The argument should be a value.
|
||||
if (lastClass == null) {
|
||||
throw new IllegalArgumentException("Argument " + ancestor + " should be a class.");
|
||||
}
|
||||
if (ancestor instanceof Long) {
|
||||
lastKey = Key.create(lastKey, lastClass, (Long) ancestor);
|
||||
} else if (ancestor instanceof String) {
|
||||
lastKey = Key.create(lastKey, lastClass, (String) ancestor);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Key value " + ancestor + " must be a string or long.");
|
||||
}
|
||||
lastClass = null;
|
||||
}
|
||||
|
||||
// Make sure we didn't end up with a dangling class with no value.
|
||||
if (lastClass != null) {
|
||||
throw new IllegalArgumentException("Missing value for last key of type " + lastClass);
|
||||
}
|
||||
|
||||
Object sqlKey = getSqlKey();
|
||||
Key<T> ofyKey =
|
||||
sqlKey instanceof Long
|
||||
? Key.create(lastKey, getKind(), (Long) sqlKey)
|
||||
: Key.create(lastKey, getKind(), (String) sqlKey);
|
||||
|
||||
return VKey.create((Class<T>) getKind(), sqlKey, ofyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of {@code key} with an ofy key restored from {@code ancestors}.
|
||||
*
|
||||
* <p>This is the static form of the method restoreOfy() above. If {@code key} is null, it returns
|
||||
* null.
|
||||
*/
|
||||
public static <T> VKey<T> restoreOfyFrom(@Nullable VKey<T> key, Object... ancestors) {
|
||||
return key == null ? null : key.restoreOfy(ancestors);
|
||||
}
|
||||
|
||||
/** Returns the type of the entity. */
|
||||
public Class<? extends T> getKind() {
|
||||
return this.kind;
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
</attributes>
|
||||
</embeddable>
|
||||
|
||||
<sequence-generator name="HistorySequenceGenerator" sequence-name="history_id_sequence"/>
|
||||
|
||||
<!-- TODO(shicong): Drop this sequence and change all history tables to use the above one. -->
|
||||
<sequence-generator name="TempHistorySequenceGenerator" sequence-name="temp_history_id_sequence"/>
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
|
||||
@@ -94,7 +94,10 @@
|
||||
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
||||
|
||||
<!-- Generated converters for VKey -->
|
||||
<class>google.registry.model.billing.VKeyConverter_BillingEvent</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_Cancellation</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_Modification</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_OneTime</class>
|
||||
<class>google.registry.model.billing.VKeyConverter_Recurring</class>
|
||||
<class>google.registry.model.contact.VKeyConverter_ContactResource</class>
|
||||
<class>google.registry.model.domain.VKeyConverter_DomainBase</class>
|
||||
<class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
|
||||
|
||||
@@ -273,8 +273,11 @@ class InitSqlPipelineTest {
|
||||
"revisions",
|
||||
"updateTimestamp",
|
||||
"autorenewBillingEvent",
|
||||
"autorenewBillingEventHistoryId",
|
||||
"autorenewPollMessage",
|
||||
"autorenewPollMessageHistoryId",
|
||||
"deletePollMessage",
|
||||
"deletePollMessageHistoryId",
|
||||
"nsHosts",
|
||||
"transferData");
|
||||
assertThat(actual.getAdminContact().getSqlKey())
|
||||
|
||||
@@ -25,6 +25,11 @@ import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
import google.registry.model.domain.launch.LaunchNotice;
|
||||
@@ -33,6 +38,8 @@ import google.registry.model.domain.secdns.DelegationSignerData;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.ContactTransferData;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
@@ -60,6 +67,7 @@ public class DomainBaseSqlTest {
|
||||
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
|
||||
|
||||
private DomainBase domain;
|
||||
private DomainHistory historyEntry;
|
||||
private VKey<ContactResource> contactKey;
|
||||
private VKey<ContactResource> contact2Key;
|
||||
private VKey<HostResource> host1VKey;
|
||||
@@ -395,6 +403,174 @@ public class DomainBaseSqlTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistDomainWithCompositeVKeys() {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
historyEntry =
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.setModificationTime(DateTime.now(UTC))
|
||||
.setParent(Key.create(DomainBase.class, "4-COM"))
|
||||
.setDomainRepoId("4-COM")
|
||||
|
||||
// These are non-null, but I don't think some tests set them.
|
||||
.setReason("felt like it")
|
||||
.setRequestedByRegistrar(false)
|
||||
.setXmlBytes(new byte[0])
|
||||
.build();
|
||||
BillingEvent.Recurring billEvent =
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.com")
|
||||
.setClientId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setClientId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
PollMessage.OneTime deletePollMessage =
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setClientId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(contact2);
|
||||
jpaTm().insert(host);
|
||||
domain =
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(billEvent.createVKey())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.setDeletePollMessage(deletePollMessage.createVKey())
|
||||
.build();
|
||||
historyEntry = historyEntry.asBuilder().setDomainContent(domain).build();
|
||||
jpaTm().insert(historyEntry);
|
||||
jpaTm().insert(autorenewPollMessage);
|
||||
jpaTm().insert(billEvent);
|
||||
jpaTm().insert(deletePollMessage);
|
||||
jpaTm().insert(domain);
|
||||
});
|
||||
|
||||
// Store the existing BillingRecurrence VKey. This happens after the event has been persisted.
|
||||
DomainBase persisted = jpaTm().transact(() -> jpaTm().load(domain.createVKey()));
|
||||
|
||||
// Verify that the domain data has been persisted.
|
||||
// dsData still isn't persisted. gracePeriods appears to have the same values but for some
|
||||
// reason is showing up as different.
|
||||
assertEqualDomainExcept(persisted, "creationTime", "dsData", "gracePeriods");
|
||||
|
||||
// Verify that the DomainContent object from the history record sets the fields correctly.
|
||||
DomainHistory persistedHistoryEntry =
|
||||
jpaTm().transact(() -> jpaTm().load(historyEntry.createVKey()));
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getAutorenewPollMessage())
|
||||
.isEqualTo(domain.getAutorenewPollMessage());
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getAutorenewBillingEvent())
|
||||
.isEqualTo(domain.getAutorenewBillingEvent());
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getDeletePollMessage())
|
||||
.isEqualTo(domain.getDeletePollMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistDomainWithLegacyVKeys() {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
historyEntry =
|
||||
new DomainHistory.Builder()
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.setModificationTime(DateTime.now(UTC))
|
||||
.setParent(Key.create(DomainBase.class, "4-COM"))
|
||||
.setDomainRepoId("4-COM")
|
||||
|
||||
// These are non-null, but I don't think some tests set them.
|
||||
.setReason("felt like it")
|
||||
.setRequestedByRegistrar(false)
|
||||
.setXmlBytes(new byte[0])
|
||||
.build();
|
||||
BillingEvent.Recurring billEvent =
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.com")
|
||||
.setClientId("registrar1")
|
||||
.setDomainRepoId("4-COM")
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setClientId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
PollMessage.OneTime deletePollMessage =
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setClientId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(contact2);
|
||||
jpaTm().insert(host);
|
||||
domain =
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(
|
||||
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))
|
||||
.setAutorenewPollMessage(
|
||||
createLegacyVKey(PollMessage.Autorenew.class, deletePollMessage.getId()))
|
||||
.setDeletePollMessage(
|
||||
createLegacyVKey(PollMessage.OneTime.class, autorenewPollMessage.getId()))
|
||||
.build();
|
||||
historyEntry = historyEntry.asBuilder().setDomainContent(domain).build();
|
||||
jpaTm().insert(historyEntry);
|
||||
jpaTm().insert(autorenewPollMessage);
|
||||
jpaTm().insert(billEvent);
|
||||
jpaTm().insert(deletePollMessage);
|
||||
jpaTm().insert(domain);
|
||||
});
|
||||
|
||||
// Store the existing BillingRecurrence VKey. This happens after the event has been persisted.
|
||||
DomainBase persisted = jpaTm().transact(() -> jpaTm().load(domain.createVKey()));
|
||||
|
||||
// Verify that the domain data has been persisted.
|
||||
// dsData still isn't persisted. gracePeriods appears to have the same values but for some
|
||||
// reason is showing up as different.
|
||||
assertEqualDomainExcept(persisted, "creationTime", "dsData", "gracePeriods");
|
||||
|
||||
// Verify that the DomainContent object from the history record sets the fields correctly.
|
||||
DomainHistory persistedHistoryEntry =
|
||||
jpaTm().transact(() -> jpaTm().load(historyEntry.createVKey()));
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getAutorenewPollMessage())
|
||||
.isEqualTo(domain.getAutorenewPollMessage());
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getAutorenewBillingEvent())
|
||||
.isEqualTo(domain.getAutorenewBillingEvent());
|
||||
assertThat(persistedHistoryEntry.getDomainContent().get().getDeletePollMessage())
|
||||
.isEqualTo(domain.getDeletePollMessage());
|
||||
}
|
||||
|
||||
private <T> VKey<T> createLegacyVKey(Class<T> clazz, long id) {
|
||||
return VKey.create(
|
||||
clazz, id, Key.create(Key.create(EntityGroupRoot.class, "per-tld"), clazz, id));
|
||||
}
|
||||
|
||||
private void assertEqualDomainExcept(DomainBase thatDomain, String... excepts) {
|
||||
// Fix DS data, since we can't persist it yet.
|
||||
thatDomain =
|
||||
|
||||
@@ -47,14 +47,12 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
jpaTm().transact(() -> jpaTm().insert(contact));
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = jpaTm().transact(() -> jpaTm().load(contactVKey));
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contactVKey);
|
||||
contactHistory.id = null;
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contact.getRepoId());
|
||||
jpaTm().transact(() -> jpaTm().insert(contactHistory));
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
ContactHistory fromDatabase =
|
||||
jpaTm().load(VKey.createSql(ContactHistory.class, contactHistory.getId()));
|
||||
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
|
||||
assertContactHistoriesEqual(fromDatabase, contactHistory);
|
||||
assertThat(fromDatabase.getContactRepoId().getSqlKey())
|
||||
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
|
||||
@@ -70,15 +68,16 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = jpaTm().transact(() -> jpaTm().load(contactVKey));
|
||||
ContactHistory contactHistory =
|
||||
createContactHistory(contactFromDb, contactVKey).asBuilder().setContactBase(null).build();
|
||||
contactHistory.id = null;
|
||||
createContactHistory(contactFromDb, contact.getRepoId())
|
||||
.asBuilder()
|
||||
.setContactBase(null)
|
||||
.build();
|
||||
jpaTm().transact(() -> jpaTm().insert(contactHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
ContactHistory fromDatabase =
|
||||
jpaTm().load(VKey.createSql(ContactHistory.class, contactHistory.getId()));
|
||||
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
|
||||
assertContactHistoriesEqual(fromDatabase, contactHistory);
|
||||
assertThat(fromDatabase.getContactRepoId().getSqlKey())
|
||||
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
|
||||
@@ -94,14 +93,13 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = tm().transact(() -> tm().load(contactVKey));
|
||||
fakeClock.advanceOneMilli();
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contactVKey);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contact.getRepoId());
|
||||
tm().transact(() -> tm().insert(contactHistory));
|
||||
|
||||
// retrieving a HistoryEntry or a ContactHistory with the same key should return the same object
|
||||
// note: due to the @EntitySubclass annotation. all Keys for ContactHistory objects will have
|
||||
// type HistoryEntry
|
||||
VKey<ContactHistory> contactHistoryVKey =
|
||||
VKey.createOfy(ContactHistory.class, Key.create(contactHistory));
|
||||
VKey<ContactHistory> contactHistoryVKey = contactHistory.createVKey();
|
||||
VKey<HistoryEntry> historyEntryVKey =
|
||||
VKey.createOfy(HistoryEntry.class, Key.create(contactHistory.asHistoryEntry()));
|
||||
ContactHistory hostHistoryFromDb = tm().transact(() -> tm().load(contactHistoryVKey));
|
||||
@@ -110,8 +108,7 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
assertThat(hostHistoryFromDb).isEqualTo(historyEntryFromDb);
|
||||
}
|
||||
|
||||
private ContactHistory createContactHistory(
|
||||
ContactBase contact, VKey<ContactResource> contactVKey) {
|
||||
private ContactHistory createContactHistory(ContactBase contact, String contactRepoId) {
|
||||
return new ContactHistory.Builder()
|
||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
@@ -122,14 +119,14 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setContactBase(contact)
|
||||
.setContactRepoId(contactVKey)
|
||||
.setContactRepoId(contactRepoId)
|
||||
.build();
|
||||
}
|
||||
|
||||
static void assertContactHistoriesEqual(ContactHistory one, ContactHistory two) {
|
||||
assertAboutImmutableObjects()
|
||||
.that(one)
|
||||
.isEqualExceptFields(two, "contactBase", "contactRepoId", "parent");
|
||||
.isEqualExceptFields(two, "contactBase", "contactRepoId");
|
||||
assertAboutImmutableObjects()
|
||||
.that(one.getContactBase().orElse(null))
|
||||
.isEqualExceptFields(two.getContactBase().orElse(null), "repoId");
|
||||
|
||||
@@ -59,7 +59,6 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
void testPersistence() {
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
domainHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().insert(domainHistory));
|
||||
|
||||
jpaTm()
|
||||
@@ -77,7 +76,6 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
DomainHistory domainHistory =
|
||||
createDomainHistory(domain).asBuilder().setDomainContent(null).build();
|
||||
domainHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().insert(domainHistory));
|
||||
|
||||
jpaTm()
|
||||
@@ -121,8 +119,7 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
// retrieving a HistoryEntry or a DomainHistory with the same key should return the same object
|
||||
// note: due to the @EntitySubclass annotation. all Keys for DomainHistory objects will have
|
||||
// type HistoryEntry
|
||||
VKey<DomainHistory> domainHistoryVKey =
|
||||
VKey.createOfy(DomainHistory.class, Key.create(domainHistory));
|
||||
VKey<DomainHistory> domainHistoryVKey = domainHistory.createVKey();
|
||||
VKey<HistoryEntry> historyEntryVKey =
|
||||
VKey.createOfy(HistoryEntry.class, Key.create(domainHistory.asHistoryEntry()));
|
||||
DomainHistory domainHistoryFromDb = tm().transact(() -> tm().load(domainHistoryVKey));
|
||||
@@ -155,7 +152,7 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
assertAboutImmutableObjects()
|
||||
.that(one)
|
||||
.isEqualExceptFields(
|
||||
two, "domainContent", "domainRepoId", "parent", "nsHosts", "domainTransactionRecords");
|
||||
two, "domainContent", "domainRepoId", "nsHosts", "domainTransactionRecords");
|
||||
assertThat(one.getDomainContent().map(DomainContent::getDomainName))
|
||||
.isEqualTo(two.getDomainContent().map(DomainContent::getDomainName));
|
||||
// NB: the record's ID gets reset by Hibernate, causing the hash code to differ so we have to
|
||||
|
||||
@@ -48,14 +48,12 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
VKey<HostResource> hostVKey =
|
||||
VKey.create(HostResource.class, "host1", Key.create(HostResource.class, "host1"));
|
||||
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(hostVKey));
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, hostVKey);
|
||||
hostHistory.id = null;
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, host.getRepoId());
|
||||
jpaTm().transact(() -> jpaTm().insert(hostHistory));
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
HostHistory fromDatabase =
|
||||
jpaTm().load(VKey.createSql(HostHistory.class, hostHistory.getId()));
|
||||
HostHistory fromDatabase = jpaTm().load(hostHistory.createVKey());
|
||||
assertHostHistoriesEqual(fromDatabase, hostHistory);
|
||||
assertThat(fromDatabase.getHostRepoId().getSqlKey())
|
||||
.isEqualTo(hostHistory.getHostRepoId().getSqlKey());
|
||||
@@ -68,20 +66,15 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
jpaTm().transact(() -> jpaTm().insert(host));
|
||||
|
||||
VKey<HostResource> hostVKey =
|
||||
VKey.create(HostResource.class, "host1", Key.create(HostResource.class, "host1"));
|
||||
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(hostVKey));
|
||||
|
||||
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(host.createVKey()));
|
||||
HostHistory hostHistory =
|
||||
createHostHistory(hostFromDb, hostVKey).asBuilder().setHostBase(null).build();
|
||||
hostHistory.id = null;
|
||||
createHostHistory(hostFromDb, host.getRepoId()).asBuilder().setHostBase(null).build();
|
||||
jpaTm().transact(() -> jpaTm().insert(hostHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
HostHistory fromDatabase =
|
||||
jpaTm().load(VKey.createSql(HostHistory.class, hostHistory.getId()));
|
||||
HostHistory fromDatabase = jpaTm().load(hostHistory.createVKey());
|
||||
assertHostHistoriesEqual(fromDatabase, hostHistory);
|
||||
assertThat(fromDatabase.getHostRepoId().getSqlKey())
|
||||
.isEqualTo(hostHistory.getHostRepoId().getSqlKey());
|
||||
@@ -97,14 +90,14 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
VKey<HostResource> hostVKey =
|
||||
VKey.create(HostResource.class, "host1", Key.create(HostResource.class, "host1"));
|
||||
HostResource hostFromDb = tm().transact(() -> tm().load(hostVKey));
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, hostVKey);
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, host.getRepoId());
|
||||
fakeClock.advanceOneMilli();
|
||||
tm().transact(() -> tm().insert(hostHistory));
|
||||
|
||||
// retrieving a HistoryEntry or a HostHistory with the same key should return the same object
|
||||
// note: due to the @EntitySubclass annotation. all Keys for HostHistory objects will have
|
||||
// type HistoryEntry
|
||||
VKey<HostHistory> hostHistoryVKey = VKey.createOfy(HostHistory.class, Key.create(hostHistory));
|
||||
VKey<HostHistory> hostHistoryVKey = hostHistory.createVKey();
|
||||
VKey<HistoryEntry> historyEntryVKey =
|
||||
VKey.createOfy(HistoryEntry.class, Key.create(hostHistory.asHistoryEntry()));
|
||||
HostHistory hostHistoryFromDb = tm().transact(() -> tm().load(hostHistoryVKey));
|
||||
@@ -120,7 +113,7 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
.isEqualExceptFields(two.getHostBase().orElse(null), "repoId");
|
||||
}
|
||||
|
||||
private HostHistory createHostHistory(HostBase hostBase, VKey<HostResource> hostVKey) {
|
||||
private HostHistory createHostHistory(HostBase hostBase, String hostRepoId) {
|
||||
return new HostHistory.Builder()
|
||||
.setType(HistoryEntry.Type.HOST_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
@@ -131,7 +124,7 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setHostBase(hostBase)
|
||||
.setHostRepoId(hostVKey)
|
||||
.setHostRepoId(hostRepoId)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||
ContactHistory legacyContactHistory = (ContactHistory) fromObjectify;
|
||||
|
||||
// Next, save that from-Datastore object in SQL and verify we can load it back in
|
||||
legacyContactHistory.id = null;
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
@@ -88,11 +87,7 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||
jpaTm().insert(legacyContactHistory);
|
||||
});
|
||||
ContactHistory legacyHistoryFromSql =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
jpaTm()
|
||||
.load(VKey.createSql(ContactHistory.class, legacyContactHistory.getId())));
|
||||
jpaTm().transact(() -> jpaTm().load(legacyContactHistory.createVKey()));
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyContactHistory)
|
||||
.isEqualExceptFields(legacyHistoryFromSql);
|
||||
@@ -164,7 +159,6 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||
HostHistory legacyHostHistory = (HostHistory) fromObjectify;
|
||||
|
||||
// Next, save that from-Datastore object in SQL and verify we can load it back in
|
||||
legacyHostHistory.id = null;
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
@@ -172,9 +166,7 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||
jpaTm().insert(legacyHostHistory);
|
||||
});
|
||||
HostHistory legacyHistoryFromSql =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(HostHistory.class, legacyHostHistory.getId())));
|
||||
jpaTm().transact(() -> jpaTm().load(legacyHostHistory.createVKey()));
|
||||
assertAboutImmutableObjects().that(legacyHostHistory).isEqualExceptFields(legacyHistoryFromSql);
|
||||
// can't compare hostRepoId directly since it doesn't save the ofy key in SQL
|
||||
assertThat(legacyHostHistory.getHostRepoId().getSqlKey())
|
||||
|
||||
@@ -18,12 +18,15 @@ 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.newDomainBase;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveContact;
|
||||
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.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
@@ -34,6 +37,7 @@ import org.junit.jupiter.api.Test;
|
||||
/** Unit tests for {@link PollMessage}. */
|
||||
public class PollMessageTest extends EntityTestCase {
|
||||
|
||||
private DomainBase domain;
|
||||
private HistoryEntry historyEntry;
|
||||
private PollMessage.OneTime oneTime;
|
||||
private PollMessage.Autorenew autoRenew;
|
||||
@@ -45,15 +49,17 @@ public class PollMessageTest extends EntityTestCase {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
createTld("foobar");
|
||||
ContactResource contact = persistActiveContact("contact1234");
|
||||
domain = persistResource(newDomainBase("foo.foobar", contact));
|
||||
historyEntry =
|
||||
persistResource(
|
||||
new HistoryEntry.Builder()
|
||||
.setParent(persistActiveDomain("foo.foobar"))
|
||||
.setParent(domain)
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setClientId("foo")
|
||||
.setClientId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
@@ -61,6 +67,7 @@ public class PollMessageTest extends EntityTestCase {
|
||||
.build());
|
||||
oneTime =
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setId(100L)
|
||||
.setClientId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
@@ -68,6 +75,7 @@ public class PollMessageTest extends EntityTestCase {
|
||||
.build();
|
||||
autoRenew =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setId(200L)
|
||||
.setClientId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
@@ -75,50 +83,46 @@ public class PollMessageTest extends EntityTestCase {
|
||||
.setAutorenewEndTime(fakeClock.nowUtc().plusDays(365))
|
||||
.setTargetId("foobar.foo")
|
||||
.build();
|
||||
// TODO(shicong): Remove these two lines after we use symmetric vkey and change the cloud sql
|
||||
// schema
|
||||
oneTime.id = null;
|
||||
autoRenew.id = null;
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
saveRegistrar("TheRegistrar");
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(domain);
|
||||
jpaTm().insert(historyEntry.toChildHistoryEntity());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistenceOneTime() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
jpaTm().transact(() -> jpaTm().insert(oneTime));
|
||||
PollMessage.OneTime persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(PollMessage.OneTime.class, oneTime.id)));
|
||||
persisted.parent = oneTime.parent;
|
||||
assertThat(persisted).isEqualTo(oneTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistenceAutorenew() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
jpaTm().transact(() -> jpaTm().insert(autoRenew));
|
||||
PollMessage.Autorenew persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(PollMessage.Autorenew.class, autoRenew.id)));
|
||||
persisted.parent = autoRenew.parent;
|
||||
assertThat(persisted).isEqualTo(autoRenew);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlSupportForPolymorphicVKey() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
jpaTm().transact(() -> jpaTm().insert(oneTime));
|
||||
PollMessage persistedOneTime =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(PollMessage.class, oneTime.getId())));
|
||||
assertThat(persistedOneTime).isInstanceOf(PollMessage.OneTime.class);
|
||||
persistedOneTime.parent = oneTime.parent;
|
||||
assertThat(persistedOneTime).isEqualTo(oneTime);
|
||||
|
||||
jpaTm().transact(() -> jpaTm().insert(autoRenew));
|
||||
PollMessage persistedAutoRenew =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(PollMessage.class, autoRenew.getId())));
|
||||
assertThat(persistedAutoRenew).isInstanceOf(PollMessage.Autorenew.class);
|
||||
persistedAutoRenew.parent = oneTime.parent;
|
||||
assertThat(persistedAutoRenew).isEqualTo(autoRenew);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth8.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.registrar.RegistrarContact;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
@@ -59,4 +60,60 @@ class VKeyTest {
|
||||
() -> VKey.create(RegistrarContact.class, "fake@example.com"));
|
||||
assertThat(thrown).hasMessageThat().contains("BackupGroupRoot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRestoreOfy() {
|
||||
assertThat(VKey.restoreOfyFrom(null, TestObject.class, 100)).isNull();
|
||||
|
||||
VKey<TestObject> key = VKey.createSql(TestObject.class, "foo");
|
||||
VKey<TestObject> restored = key.restoreOfy(TestObject.class, "bar");
|
||||
assertThat(restored.getOfyKey())
|
||||
.isEqualTo(Key.create(Key.create(TestObject.class, "bar"), TestObject.class, "foo"));
|
||||
assertThat(restored.getSqlKey()).isEqualTo("foo");
|
||||
|
||||
assertThat(VKey.restoreOfyFrom(key).getOfyKey()).isEqualTo(Key.create(TestObject.class, "foo"));
|
||||
|
||||
restored = key.restoreOfy(OtherObject.class, "baz", TestObject.class, "bar");
|
||||
assertThat(restored.getOfyKey())
|
||||
.isEqualTo(
|
||||
Key.create(
|
||||
Key.create(Key.create(OtherObject.class, "baz"), TestObject.class, "bar"),
|
||||
TestObject.class,
|
||||
"foo"));
|
||||
|
||||
// Verify that we can use a key as the first argument.
|
||||
restored = key.restoreOfy(Key.create(TestObject.class, "bar"));
|
||||
assertThat(restored.getOfyKey())
|
||||
.isEqualTo(Key.create(Key.create(TestObject.class, "bar"), TestObject.class, "foo"));
|
||||
|
||||
// Verify that we get an exception when a key is not the first argument.
|
||||
IllegalArgumentException thrown =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> key.restoreOfy(TestObject.class, "foo", Key.create(TestObject.class, "bar")));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains("Objectify keys may only be used for the first argument");
|
||||
|
||||
// Verify other exception cases.
|
||||
thrown =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> key.restoreOfy(TestObject.class, TestObject.class));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains("class google.registry.testing.TestObject used as a key value.");
|
||||
|
||||
thrown =
|
||||
assertThrows(IllegalArgumentException.class, () -> key.restoreOfy(TestObject.class, 1.5));
|
||||
assertThat(thrown).hasMessageThat().contains("Key value 1.5 must be a string or long.");
|
||||
|
||||
thrown = assertThrows(IllegalArgumentException.class, () -> key.restoreOfy(TestObject.class));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains("Missing value for last key of type class google.registry.testing.TestObject");
|
||||
}
|
||||
|
||||
@Entity
|
||||
static class OtherObject {}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ClassInfo;
|
||||
import io.github.classgraph.ClassInfoList;
|
||||
@@ -72,6 +73,7 @@ public class EntityTest {
|
||||
.filter(ClassInfo::isStandardClass)
|
||||
.map(ClassInfo::loadClass)
|
||||
.filter(clazz -> !clazz.isAnnotationPresent(EntityForTesting.class))
|
||||
.filter(clazz -> !clazz.isAnnotationPresent(Embed.class))
|
||||
.map(Class::getName)
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.appengine.repackaged.com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.monitoring.metrics.contrib.LongMetricSubject.assertThat;
|
||||
import static google.registry.config.RegistryConfig.getGSuiteOutgoingEmailAddress;
|
||||
import static google.registry.config.RegistryConfig.getGSuiteOutgoingEmailDisplayName;
|
||||
|
||||
@@ -55,7 +55,7 @@ FROM (
|
||||
FROM
|
||||
`my-project-id.latest_datastore_export.Registry`
|
||||
WHERE
|
||||
enableInvoicing IS TRUE) ) AS BillingEvent
|
||||
invoicingEnabled IS TRUE) ) AS BillingEvent
|
||||
-- Gather billing ID from registrar table
|
||||
-- This is a 'JOIN' as opposed to 'LEFT JOIN' to filter out
|
||||
-- non-billable registrars
|
||||
|
||||
@@ -41,7 +41,7 @@ class google.registry.model.billing.BillingEvent$OneTime {
|
||||
@Id java.lang.Long id;
|
||||
@Parent com.googlecode.objectify.Key<google.registry.model.reporting.HistoryEntry> parent;
|
||||
google.registry.model.billing.BillingEvent$Reason reason;
|
||||
google.registry.persistence.VKey<? extends google.registry.model.billing.BillingEvent> cancellationMatchingBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> cancellationMatchingBillingEvent;
|
||||
google.registry.persistence.VKey<google.registry.model.domain.token.AllocationToken> allocationToken;
|
||||
java.lang.Integer periodYears;
|
||||
java.lang.String clientId;
|
||||
@@ -131,9 +131,9 @@ class google.registry.model.contact.ContactHistory {
|
||||
google.registry.model.domain.Period period;
|
||||
google.registry.model.eppcommon.Trid trid;
|
||||
google.registry.model.reporting.HistoryEntry$Type type;
|
||||
google.registry.persistence.VKey<google.registry.model.contact.ContactResource> contactRepoId;
|
||||
java.lang.Boolean requestedByRegistrar;
|
||||
java.lang.String clientId;
|
||||
java.lang.String contactRepoId;
|
||||
java.lang.String otherClientId;
|
||||
java.lang.String reason;
|
||||
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
|
||||
@@ -401,9 +401,9 @@ class google.registry.model.host.HostHistory {
|
||||
google.registry.model.eppcommon.Trid trid;
|
||||
google.registry.model.host.HostBase hostBase;
|
||||
google.registry.model.reporting.HistoryEntry$Type type;
|
||||
google.registry.persistence.VKey<google.registry.model.host.HostResource> hostRepoId;
|
||||
java.lang.Boolean requestedByRegistrar;
|
||||
java.lang.String clientId;
|
||||
java.lang.String hostRepoId;
|
||||
java.lang.String otherClientId;
|
||||
java.lang.String reason;
|
||||
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
|
||||
|
||||
@@ -61,6 +61,11 @@ Below are the steps to submit a schema change:
|
||||
You'll want to have a look at the diffs in the golden schema to verify that
|
||||
all changes are intentional.
|
||||
|
||||
5. Run ./nom_build :db:generateFlywayIndex to regenerate the Flyway index.
|
||||
This is a file listing all of the current Flyway files. Its purpose is to
|
||||
produce a merge conflict when more than one person adds a Flyway file with
|
||||
the same sequence number.
|
||||
|
||||
Relevant files (under db/src/main/resources/sql/schema/):
|
||||
|
||||
* nomulus.golden.sql is the schema dump (pg_dump for postgres) of the final
|
||||
|
||||
@@ -170,6 +170,28 @@ dependencies {
|
||||
testCompile project(path: ':common', configuration: 'testing')
|
||||
}
|
||||
|
||||
task generateFlywayIndex {
|
||||
def flywayBase = "$projectDir/src/main/resources/sql/flyway"
|
||||
def filenamePattern = /V(\d+)__.*\.sql/
|
||||
|
||||
def getSeqNum = { file ->
|
||||
def match = file.getName() =~ filenamePattern
|
||||
if (match.size() != 1) {
|
||||
throw new IllegalArgumentException("Bad Flyway filename: $file")
|
||||
}
|
||||
return match[0][1] as int
|
||||
}
|
||||
|
||||
doLast {
|
||||
def files = new File(flywayBase).listFiles()
|
||||
def indexFile = new File("${flywayBase}.txt")
|
||||
indexFile.write ''
|
||||
for (def file : files.sort{a, b -> getSeqNum(a) <=> getSeqNum(b)}) {
|
||||
indexFile << "${file.name}\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flywayInfo.dependsOn('buildNeeded')
|
||||
flywayValidate.dependsOn('buildNeeded')
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
V1__create_claims_list_and_entry.sql
|
||||
V2__create_premium_list_and_entry.sql
|
||||
V3__create_registry_lock.sql
|
||||
V4__registry_lock_add_index_on_verification_code.sql
|
||||
V5__update_premium_list.sql
|
||||
V6__premium_list_bloom_filter.sql
|
||||
V7__update_claims_list.sql
|
||||
V8__registry_lock_registrar_index.sql
|
||||
V9__premium_list_currency_type.sql
|
||||
V10__create_reserved_list_and_entry.sql
|
||||
V11__premium_entry_reorder_column.sql
|
||||
V12__create_cursor.sql
|
||||
V13__refactor_registry_lock.sql
|
||||
V14__load_extension_for_hstore.sql
|
||||
V15__add_epp_resources.sql
|
||||
V16__create_registrar.sql
|
||||
V17__create_registrar_poc.sql
|
||||
V18__create_lock.sql
|
||||
V19__add_registry_relock_reference.sql
|
||||
V20__add_relock_duration.sql
|
||||
V21__add_registry_lock_email_to_poc.sql
|
||||
V22__update_ns_hosts.sql
|
||||
V23__create_contact.sql
|
||||
V24__domain_base_contacts.sql
|
||||
V25__rename_vkey_fields.sql
|
||||
V26__create_billing_event.sql
|
||||
V27__create_pollmessage.sql
|
||||
V28__superordinate_domain_vkey.sql
|
||||
V29__add_columns_for_transfer_data.sql
|
||||
V30__inet_address_converter.sql
|
||||
V31__client_id_to_registrar_id.sql
|
||||
V32__drop_unused_transafer_data_columns_in_contact.sql
|
||||
V33__create_host_history.sql
|
||||
V34__rename_fully_qualified_names.sql
|
||||
V35__rename_allow_list.sql
|
||||
V36__create_safebrowsing_threats.sql
|
||||
V37__update_spec11threatmatch.sql
|
||||
V38__create_contact_history.sql
|
||||
V39__add_updatetime_column.sql
|
||||
V40__spec11threatmatch_remove_registrar_foreign_key.sql
|
||||
V41__add_columns_to_domain.sql
|
||||
V42__add_txn_table.sql
|
||||
V43__update_relock_duration_type.sql
|
||||
V44__create_domain_history.sql
|
||||
V45__add_grace_period_table.sql
|
||||
V46__Contact_contactId_index_to_non_unique.sql
|
||||
V47__remove_spec11_domain_foreign_key.sql
|
||||
V48__domain_add_autorenew_end_time_column.sql
|
||||
V49__create_allocation_token.sql
|
||||
V50__use_composite_key_for_registrar_poc.sql
|
||||
V51__use_composite_primary_key_for_domain_history_table.sql
|
||||
V52__update_billing_constraint.sql
|
||||
V53__add_temp_history_id_sequence.sql
|
||||
V54__add_tld_table.sql
|
||||
V55__domain_history_fields.sql
|
||||
V56__rename_host_table.sql
|
||||
V57__history_null_content.sql
|
||||
V58__drop_default_value_and_sequences_for_billing_event.sql
|
||||
V59__use_composite_primary_key_for_contact_and_host_history_table.sql
|
||||
V60__remove_pollmessage_sequence.sql
|
||||
V61__domain_hist_columns.sql
|
||||
V62__disable_key_auto_generation_for_history_tables.sql
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
alter table "ContactHistory" drop constraint "ContactHistory_pkey";
|
||||
|
||||
alter table "ContactHistory"
|
||||
add constraint "ContactHistory_pkey" primary key (contact_repo_id, history_revision_id);
|
||||
|
||||
alter table "HostHistory" drop constraint "HostHistory_pkey";
|
||||
|
||||
alter table "HostHistory"
|
||||
add constraint "HostHistory_pkey" primary key (host_repo_id, history_revision_id);
|
||||
@@ -0,0 +1,36 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
alter table "PollMessage" alter column poll_message_id drop default;
|
||||
|
||||
drop sequence "PollMessage_poll_message_id_seq";
|
||||
|
||||
alter table "PollMessage" rename column "domain_revision_id" to "domain_history_revision_id";
|
||||
alter table "PollMessage" rename column "contact_revision_id" to "contact_history_revision_id";
|
||||
alter table "PollMessage" rename column "host_revision_id" to "host_history_revision_id";
|
||||
|
||||
alter table if exists "PollMessage"
|
||||
add constraint fk_poll_message_domain_history
|
||||
foreign key (domain_repo_id, domain_history_revision_id)
|
||||
references "DomainHistory";
|
||||
|
||||
alter table if exists "PollMessage"
|
||||
add constraint fk_poll_message_contact_history
|
||||
foreign key (contact_repo_id, contact_history_revision_id)
|
||||
references "ContactHistory";
|
||||
|
||||
alter table if exists "PollMessage"
|
||||
add constraint fk_poll_message_host_history
|
||||
foreign key (host_repo_id, host_history_revision_id)
|
||||
references "HostHistory";
|
||||
@@ -0,0 +1,39 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http:--www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
-- These history ids are technically foreign keys, we don't want to constrain
|
||||
-- them because they're temporary and we don't need to because they are
|
||||
-- already indirectly constrained by the relationships with the
|
||||
-- PollMessages/BillingEvents involved.
|
||||
ALTER TABLE "Domain" ADD COLUMN billing_recurrence_history_id int8;
|
||||
ALTER TABLE "Domain" ADD COLUMN autorenew_poll_message_history_id int8;
|
||||
ALTER TABLE "Domain" ADD COLUMN deletion_poll_message_history_id int8;
|
||||
ALTER TABLE "DomainHistory" ADD COLUMN billing_recurrence_history_id int8;
|
||||
ALTER TABLE "DomainHistory" ADD COLUMN autorenew_poll_message_history_id int8;
|
||||
ALTER TABLE "DomainHistory" ADD COLUMN deletion_poll_message_history_id int8;
|
||||
|
||||
-- Drop and re-add DomainHistory's Domain FK constraint to make it deferrable,
|
||||
-- this breaks a cycle with Domain -> PollMessage|BillingEvent -> History.
|
||||
ALTER TABLE "DomainHistory" DROP CONSTRAINT fk_domain_history_domain_repo_id;
|
||||
ALTER TABLE "DomainHistory"
|
||||
ADD CONSTRAINT fk_domain_history_domain_repo_id
|
||||
FOREIGN KEY (domain_repo_id) REFERENCES "Domain"(repo_id)
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
-- Same for PollMessage -> Domain, breaking Domain -> PollMessage -> Domain.
|
||||
ALTER TABLE "PollMessage" DROP CONSTRAINT fk_poll_message_domain_repo_id;
|
||||
ALTER TABLE "PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_domain_repo_id
|
||||
FOREIGN KEY (domain_repo_id) REFERENCES "Domain"(repo_id)
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
drop sequence "history_id_sequence";
|
||||
|
||||
drop sequence "temp_history_id_sequence";
|
||||
@@ -11,7 +11,6 @@
|
||||
-- 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.
|
||||
create sequence temp_history_id_sequence start 1 increment 50;
|
||||
|
||||
create table "AllocationToken" (
|
||||
token text not null,
|
||||
@@ -151,7 +150,8 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
);
|
||||
|
||||
create table "ContactHistory" (
|
||||
history_revision_id int8 not null,
|
||||
contact_repo_id text not null,
|
||||
history_revision_id int8 not null,
|
||||
history_by_superuser boolean not null,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamptz not null,
|
||||
@@ -215,8 +215,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
last_epp_update_time timestamptz,
|
||||
statuses text[],
|
||||
update_timestamp timestamptz,
|
||||
contact_repo_id text not null,
|
||||
primary key (history_revision_id)
|
||||
primary key (contact_repo_id, history_revision_id)
|
||||
);
|
||||
|
||||
create table "Cursor" (
|
||||
@@ -249,10 +248,13 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
auth_info_repo_id text,
|
||||
auth_info_value text,
|
||||
billing_recurrence_id int8,
|
||||
billing_recurrence_history_id int8,
|
||||
autorenew_end_time timestamptz,
|
||||
autorenew_poll_message_id int8,
|
||||
autorenew_poll_message_history_id int8,
|
||||
billing_contact text,
|
||||
deletion_poll_message_id int8,
|
||||
deletion_poll_message_history_id int8,
|
||||
domain_name text,
|
||||
idn_table_name text,
|
||||
last_transfer_time timestamptz,
|
||||
@@ -301,10 +303,13 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
auth_info_repo_id text,
|
||||
auth_info_value text,
|
||||
billing_recurrence_id int8,
|
||||
billing_recurrence_history_id int8,
|
||||
autorenew_end_time timestamptz,
|
||||
autorenew_poll_message_id int8,
|
||||
autorenew_poll_message_history_id int8,
|
||||
billing_contact text,
|
||||
deletion_poll_message_id int8,
|
||||
deletion_poll_message_history_id int8,
|
||||
domain_name text,
|
||||
idn_table_name text,
|
||||
last_transfer_time timestamptz,
|
||||
@@ -400,7 +405,8 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
);
|
||||
|
||||
create table "HostHistory" (
|
||||
history_revision_id int8 not null,
|
||||
host_repo_id text not null,
|
||||
history_revision_id int8 not null,
|
||||
history_by_superuser boolean not null,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamptz not null,
|
||||
@@ -423,8 +429,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
last_epp_update_time timestamptz,
|
||||
statuses text[],
|
||||
update_timestamp timestamptz,
|
||||
host_repo_id text not null,
|
||||
primary key (history_revision_id)
|
||||
primary key (host_repo_id, history_revision_id)
|
||||
);
|
||||
|
||||
create table "Lock" (
|
||||
@@ -438,15 +443,15 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
|
||||
create table "PollMessage" (
|
||||
type text not null,
|
||||
poll_message_id bigserial not null,
|
||||
poll_message_id int8 not null,
|
||||
registrar_id text not null,
|
||||
contact_history_revision_id int8,
|
||||
contact_repo_id text,
|
||||
contact_revision_id int8,
|
||||
domain_history_revision_id int8,
|
||||
domain_repo_id text,
|
||||
domain_revision_id int8,
|
||||
event_time timestamptz not null,
|
||||
host_history_revision_id int8,
|
||||
host_repo_id text,
|
||||
host_revision_id int8,
|
||||
message text,
|
||||
transfer_response_contact_id text,
|
||||
transfer_response_domain_expiration_time timestamptz,
|
||||
|
||||
@@ -353,7 +353,10 @@ CREATE TABLE public."Domain" (
|
||||
billing_recurrence_id bigint,
|
||||
autorenew_poll_message_id bigint,
|
||||
deletion_poll_message_id bigint,
|
||||
autorenew_end_time timestamp with time zone
|
||||
autorenew_end_time timestamp with time zone,
|
||||
billing_recurrence_history_id bigint,
|
||||
autorenew_poll_message_history_id bigint,
|
||||
deletion_poll_message_history_id bigint
|
||||
);
|
||||
|
||||
|
||||
@@ -420,7 +423,10 @@ CREATE TABLE public."DomainHistory" (
|
||||
autorenew_end_time timestamp with time zone,
|
||||
history_other_registrar_id text,
|
||||
history_period_unit text,
|
||||
history_period_value integer
|
||||
history_period_value integer,
|
||||
billing_recurrence_history_id bigint,
|
||||
autorenew_poll_message_history_id bigint,
|
||||
deletion_poll_message_history_id bigint
|
||||
);
|
||||
|
||||
|
||||
@@ -589,12 +595,12 @@ CREATE TABLE public."PollMessage" (
|
||||
poll_message_id bigint NOT NULL,
|
||||
registrar_id text NOT NULL,
|
||||
contact_repo_id text,
|
||||
contact_revision_id bigint,
|
||||
contact_history_revision_id bigint,
|
||||
domain_repo_id text,
|
||||
domain_revision_id bigint,
|
||||
domain_history_revision_id bigint,
|
||||
event_time timestamp with time zone NOT NULL,
|
||||
host_repo_id text,
|
||||
host_revision_id bigint,
|
||||
host_history_revision_id bigint,
|
||||
message text,
|
||||
transfer_response_contact_id text,
|
||||
transfer_response_domain_expiration_time timestamp with time zone,
|
||||
@@ -614,25 +620,6 @@ CREATE TABLE public."PollMessage" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage_poll_message_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."PollMessage_poll_message_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage_poll_message_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."PollMessage_poll_message_id_seq" OWNED BY public."PollMessage".poll_message_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: PremiumEntry; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -944,30 +931,6 @@ CREATE SEQUENCE public."Transaction_id_seq"
|
||||
ALTER SEQUENCE public."Transaction_id_seq" OWNED BY public."Transaction".id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: history_id_sequence; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.history_id_sequence
|
||||
START WITH 1
|
||||
INCREMENT BY 50
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: temp_history_id_sequence; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.temp_history_id_sequence
|
||||
START WITH 1
|
||||
INCREMENT BY 50
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ClaimsList revision_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -989,13 +952,6 @@ ALTER TABLE ONLY public."DomainTransactionRecord" ALTER COLUMN id SET DEFAULT ne
|
||||
ALTER TABLE ONLY public."GracePeriod" ALTER COLUMN id SET DEFAULT nextval('public."GracePeriod_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage poll_message_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage" ALTER COLUMN poll_message_id SET DEFAULT nextval('public."PollMessage_poll_message_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PremiumList revision_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1084,7 +1040,7 @@ ALTER TABLE ONLY public."ClaimsList"
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."ContactHistory"
|
||||
ADD CONSTRAINT "ContactHistory_pkey" PRIMARY KEY (history_revision_id);
|
||||
ADD CONSTRAINT "ContactHistory_pkey" PRIMARY KEY (contact_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
@@ -1140,7 +1096,7 @@ ALTER TABLE ONLY public."GracePeriod"
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."HostHistory"
|
||||
ADD CONSTRAINT "HostHistory_pkey" PRIMARY KEY (history_revision_id);
|
||||
ADD CONSTRAINT "HostHistory_pkey" PRIMARY KEY (host_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
@@ -1794,7 +1750,7 @@ ALTER TABLE ONLY public."Domain"
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."DomainHistory"
|
||||
ADD CONSTRAINT fk_domain_history_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id);
|
||||
ADD CONSTRAINT fk_domain_history_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
@@ -1901,6 +1857,14 @@ ALTER TABLE ONLY public."HostHistory"
|
||||
ADD CONSTRAINT fk_hosthistory_host FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage fk_poll_message_contact_history; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_contact_history FOREIGN KEY (contact_repo_id, contact_history_revision_id) REFERENCES public."ContactHistory"(contact_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage fk_poll_message_contact_repo_id; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1909,12 +1873,28 @@ ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_contact_repo_id FOREIGN KEY (contact_repo_id) REFERENCES public."Contact"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage fk_poll_message_domain_history; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_domain_history FOREIGN KEY (domain_repo_id, domain_history_revision_id) REFERENCES public."DomainHistory"(domain_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage fk_poll_message_domain_repo_id; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id);
|
||||
ADD CONSTRAINT fk_poll_message_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id) DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage fk_poll_message_host_history; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_host_history FOREIGN KEY (host_repo_id, host_history_revision_id) REFERENCES public."HostHistory"(host_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
|
||||
@@ -204,6 +204,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -202,6 +202,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -204,6 +204,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -204,6 +204,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -208,6 +208,7 @@ org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apiguardian:apiguardian-api:1.1.0
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -207,6 +207,7 @@ org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apiguardian:apiguardian-api:1.1.0
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -208,6 +208,7 @@ org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apiguardian:apiguardian-api:1.1.0
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -208,6 +208,7 @@ org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apiguardian:apiguardian-api:1.1.0
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import dagger.Lazy;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import static google.registry.networking.handler.SslInitializerTestUtils.signKey
|
||||
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslException;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import static google.registry.networking.handler.SslServerInitializer.CLIENT_CER
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import dagger.Component;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.networking.module.CertificateSupplierModule.Mode;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.security.KeyPair;
|
||||
|
||||
@@ -23,9 +23,9 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
|
||||
@@ -27,10 +27,10 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.proxy.TestUtils;
|
||||
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
||||
import google.registry.proxy.metric.FrontendMetrics;
|
||||
import google.registry.util.SelfSignedCaCertificate;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
@@ -203,6 +203,7 @@ org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcpkix-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
org.checkerframework:checker-qual:2.11.1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user