mirror of
https://github.com/google/nomulus
synced 2026-07-09 01:27:09 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77fabe4dc4 | |||
| 71fa12f773 | |||
| fd40a6a2b9 | |||
| 71f86c9970 | |||
| 6f75dfd116 | |||
| ad5a74fee9 | |||
| 29b1ec4211 | |||
| 553d5717cb | |||
| 1056fdbb64 | |||
| 4aaf31be9f | |||
| e30c0f9a11 | |||
| 2a5d9c8ef5 | |||
| 597f5746a4 | |||
| 5bff53a711 | |||
| 933394e8c3 |
+2
-2
@@ -191,7 +191,7 @@ allprojects {
|
||||
}
|
||||
|
||||
task runPresubmits(type: Exec) {
|
||||
executable '/usr/bin/python'
|
||||
executable '/usr/bin/python3'
|
||||
args('config/presubmits.py')
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ subprojects {
|
||||
// in the 'configurations' block, the following code must run after
|
||||
// project evaluation, when all configurations have been created.
|
||||
configurations.each {
|
||||
if (it.name != 'dependencyLicenseReport') {
|
||||
if (it.name != 'dependencyLicenseReport' && it.name != 'integration') {
|
||||
it.resolutionStrategy.activateDependencyLocking()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ Pseudo-commands:
|
||||
"""
|
||||
|
||||
# Define all of our special gradle properties here.
|
||||
# TODO(b/169318491): use consistent naming style for properties and variables.
|
||||
PROPERTIES = [
|
||||
Property('mavenUrl',
|
||||
'URL to use for the main maven repository (defaults to maven '
|
||||
@@ -124,6 +125,9 @@ PROPERTIES = [
|
||||
'server/schema integration tests. Please refer to <a '
|
||||
'href="./integration/README.md">integration project</a> for more '
|
||||
'information.'),
|
||||
Property('baseSchemaTag',
|
||||
'The nomulus version tag of the schema for use in the schema'
|
||||
'deployment integration test (:db:schemaIncrementalDeployTest)'),
|
||||
Property('schema_version',
|
||||
'The nomulus version tag of the schema for use in a database'
|
||||
'integration test.'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -245,6 +245,7 @@ dependencies {
|
||||
testCompile deps['org.apache.ftpserver:ftpserver-core']
|
||||
compile deps['org.apache.httpcomponents:httpclient']
|
||||
compile deps['org.apache.httpcomponents:httpcore']
|
||||
runtime deps['org.apache.logging.log4j:log4j-core']
|
||||
testCompile deps['org.apache.sshd:sshd-core']
|
||||
testCompile deps['org.apache.sshd:sshd-scp']
|
||||
testCompile deps['org.apache.sshd:sshd-sftp']
|
||||
|
||||
@@ -201,7 +201,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -216,7 +216,8 @@ org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
|
||||
@@ -216,7 +216,8 @@ org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
org.apache.logging.log4j:log4j-api:2.13.3
|
||||
org.apache.logging.log4j:log4j-core:2.13.3
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
|
||||
@@ -464,7 +464,7 @@ public class DeleteContactsAndHostsAction implements Runnable {
|
||||
HostResource host = (HostResource) existingResource;
|
||||
if (host.isSubordinate()) {
|
||||
dnsQueue.addHostRefreshTask(host.getHostName());
|
||||
tm().saveNewOrUpdate(
|
||||
tm().put(
|
||||
tm().load(host.getSuperordinateDomain())
|
||||
.asBuilder()
|
||||
.removeSubordinateHost(host.getHostName())
|
||||
|
||||
@@ -437,7 +437,7 @@ public final class Transforms {
|
||||
.map(Optional::get)
|
||||
.map(ofy::toPojo)
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
retry(() -> jpaTm().transact(() -> jpaTm().saveNewOrUpdateAll(ofyEntities)));
|
||||
retry(() -> jpaTm().transact(() -> jpaTm().putAll(ofyEntities)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -215,7 +215,7 @@ public class Spec11Pipeline implements Serializable {
|
||||
.setRegistrarId(subdomain.registrarId())
|
||||
.build();
|
||||
JpaTransactionManager jpaTransactionManager = jpaSupplierFactory.get();
|
||||
jpaTransactionManager.transact(() -> jpaTransactionManager.saveNew(threatMatch));
|
||||
jpaTransactionManager.transact(() -> jpaTransactionManager.insert(threatMatch));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -173,7 +173,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||
existingDomain, newExpirationTime, autorenewEvent, autorenewPollMessage, now, clientId);
|
||||
updateForeignKeyIndexDeletionTime(newDomain);
|
||||
entitiesToSave.add(newDomain, historyEntry, autorenewEvent, autorenewPollMessage);
|
||||
tm().saveNewOrUpdateAll(entitiesToSave.build());
|
||||
tm().putAll(entitiesToSave.build());
|
||||
tm().delete(existingDomain.getDeletePollMessage());
|
||||
dnsQueue.addDomainRefreshTask(existingDomain.getDomainName());
|
||||
return responseBuilder
|
||||
|
||||
@@ -285,7 +285,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||
&& newHost.isSubordinate()
|
||||
&& Objects.equals(
|
||||
existingHost.getSuperordinateDomain(), newHost.getSuperordinateDomain())) {
|
||||
tm().saveNewOrUpdate(
|
||||
tm().put(
|
||||
tm().load(existingHost.getSuperordinateDomain())
|
||||
.asBuilder()
|
||||
.removeSubordinateHost(existingHost.getHostName())
|
||||
@@ -294,14 +294,14 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||
return;
|
||||
}
|
||||
if (existingHost.isSubordinate()) {
|
||||
tm().saveNewOrUpdate(
|
||||
tm().put(
|
||||
tm().load(existingHost.getSuperordinateDomain())
|
||||
.asBuilder()
|
||||
.removeSubordinateHost(existingHost.getHostName())
|
||||
.build());
|
||||
}
|
||||
if (newHost.isSubordinate()) {
|
||||
tm().saveNewOrUpdate(
|
||||
tm().put(
|
||||
tm().load(newHost.getSuperordinateDomain())
|
||||
.asBuilder()
|
||||
.addSubordinateHost(newHost.getHostName())
|
||||
|
||||
@@ -64,7 +64,7 @@ public final class PollFlowUtils {
|
||||
// and re-save it for future autorenew poll messages to be delivered. Otherwise, this
|
||||
// autorenew poll message has no more events to deliver and should be deleted.
|
||||
if (nextEventTime.isBefore(autorenewPollMessage.getAutorenewEndTime())) {
|
||||
tm().saveNewOrUpdate(autorenewPollMessage.asBuilder().setEventTime(nextEventTime).build());
|
||||
tm().put(autorenewPollMessage.asBuilder().setEventTime(nextEventTime).build());
|
||||
includeAckedMessageInCount = isBeforeOrAt(nextEventTime, tm().getTransactionTime());
|
||||
} else {
|
||||
tm().delete(autorenewPollMessage.createVKey());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Registry: Charleston Road Registry Inc.
|
||||
# Language: Chinese
|
||||
# Script: zh-Hans
|
||||
# Version: 1.0
|
||||
# Effective Date: 04-12-2012
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Registry: Charleston Road Registry Inc.
|
||||
# Language: Traditional Chinese
|
||||
# Script: zh-Hant
|
||||
# Version: 1.0
|
||||
# Effective Date: 04-12-2012
|
||||
# Contact: iana-contact@google.com
|
||||
|
||||
@@ -62,23 +62,32 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
/**
|
||||
* Unique identifier in the registry for this resource.
|
||||
*
|
||||
* <p>Not persisted so that we can store these in references to other objects. Subclasses that
|
||||
* wish to use this as the primary key should create a getter method annotated with @Id
|
||||
*
|
||||
* <p>This is in the (\w|_){1,80}-\w{1,8} format specified by RFC 5730 for roidType.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5730">RFC 5730</a>
|
||||
*/
|
||||
@Id
|
||||
// not persisted so that we can store these in references to other objects. Subclasses that wish
|
||||
// to use this as the primary key should create a getter method annotated with @Id
|
||||
@Transient
|
||||
String repoId;
|
||||
@Id @Transient String repoId;
|
||||
|
||||
/** The ID of the registrar that is currently sponsoring this resource. */
|
||||
/**
|
||||
* The ID of the registrar that is currently sponsoring this resource.
|
||||
*
|
||||
* <p>This can be null in the case of pre-Registry-3.0-migration history objects with null
|
||||
* resource fields.
|
||||
*/
|
||||
@Index
|
||||
@Column(name = "currentSponsorRegistrarId", nullable = false)
|
||||
@Column(name = "currentSponsorRegistrarId")
|
||||
String currentSponsorClientId;
|
||||
|
||||
/** The ID of the registrar that created this resource. */
|
||||
@Column(name = "creationRegistrarId", nullable = false)
|
||||
/**
|
||||
* The ID of the registrar that created this resource.
|
||||
*
|
||||
* <p>This can be null in the case of pre-Registry-3.0-migration history objects with null
|
||||
* resource fields.
|
||||
*/
|
||||
@Column(name = "creationRegistrarId")
|
||||
String creationClientId;
|
||||
|
||||
/**
|
||||
@@ -91,13 +100,17 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
@Column(name = "lastEppUpdateRegistrarId")
|
||||
String lastEppUpdateClientId;
|
||||
|
||||
/** The time when this resource was created. */
|
||||
// Map the method to XML, not the field, because if we map the field (with an adaptor class) it
|
||||
// will never be omitted from the xml even if the timestamp inside creationTime is null and we
|
||||
// return null from the adaptor. (Instead it gets written as an empty tag.)
|
||||
@Column(nullable = false)
|
||||
@Index
|
||||
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||
/**
|
||||
* The time when this resource was created.
|
||||
*
|
||||
* <p>Map the method to XML, not the field, because if we map the field (with an adaptor class) it
|
||||
* will never be omitted from the xml even if the timestamp inside creationTime is null and we
|
||||
* return null from the adaptor (instead it gets written as an empty tag).
|
||||
*
|
||||
* <p>This can be null in the case of pre-Registry-3.0-migration history objects with null
|
||||
* resource fields.
|
||||
*/
|
||||
@Index CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
|
||||
|
||||
/**
|
||||
* The time when this resource was or will be deleted.
|
||||
@@ -112,8 +125,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
* out of the index at that time, as long as we query for resources whose deletion time is before
|
||||
* now.
|
||||
*/
|
||||
@Index
|
||||
DateTime deletionTime;
|
||||
@Index DateTime deletionTime;
|
||||
|
||||
/**
|
||||
* The time that this resource was last updated.
|
||||
@@ -144,7 +156,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
return repoId;
|
||||
}
|
||||
|
||||
// Hibernate needs this to populate the repo ID, but no one else should ever use it
|
||||
/** This method exists solely to satisfy Hibernate. Use {@link Builder} instead. */
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
private void setRepoId(String repoId) {
|
||||
this.repoId = repoId;
|
||||
|
||||
@@ -33,12 +33,14 @@ import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.OnLoad;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import com.googlecode.objectify.condition.IfNull;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.common.TimeOfYear;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
@@ -57,16 +59,14 @@ import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** A billable event in a domain's lifecycle. */
|
||||
@MappedSuperclass
|
||||
@WithLongVKey
|
||||
public abstract class BillingEvent extends ImmutableObject
|
||||
implements Buildable, TransferServerApproveEntity {
|
||||
|
||||
@@ -108,10 +108,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
|
||||
/** Entity id. */
|
||||
@Id
|
||||
@javax.persistence.Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
Long id;
|
||||
@Id @javax.persistence.Id Long id;
|
||||
|
||||
@Parent @DoNotHydrate @Transient Key<HistoryEntry> parent;
|
||||
|
||||
@@ -149,6 +146,21 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
@Nullable
|
||||
Set<Flag> flags;
|
||||
|
||||
@PostLoad
|
||||
void postLoad() {
|
||||
parent =
|
||||
Key.create(
|
||||
Key.create(DomainBase.class, domainRepoId),
|
||||
HistoryEntry.class,
|
||||
domainHistoryRevisionId);
|
||||
}
|
||||
|
||||
@OnLoad
|
||||
void onLoad() {
|
||||
domainHistoryRevisionId = parent.getId();
|
||||
domainRepoId = parent.getParent().getName();
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
@@ -245,7 +257,6 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
|
||||
public B setParent(Key<HistoryEntry> parentKey) {
|
||||
// TODO(shicong): Figure out how to set domainHistoryRevisionId and domainRepoId
|
||||
getInstance().parent = parentKey;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
@@ -258,6 +269,11 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
checkNotNull(instance.eventTime, "Event time must be set");
|
||||
checkNotNull(instance.targetId, "Target ID must be set");
|
||||
checkNotNull(instance.parent, "Parent must be set");
|
||||
checkNotNull(instance.parent.getParent(), "parent.getParent() must be set");
|
||||
checkNotNull(
|
||||
instance.parent.getParent().getName(), "parent.getParent().getName() must be set");
|
||||
instance.domainHistoryRevisionId = instance.parent.getId();
|
||||
instance.domainRepoId = instance.parent.getParent().getName();
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
@@ -275,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. */
|
||||
@@ -310,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.
|
||||
@@ -392,7 +409,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
|
||||
public Builder setCancellationMatchingBillingEvent(
|
||||
VKey<? extends BillingEvent> cancellationMatchingBillingEvent) {
|
||||
VKey<Recurring> cancellationMatchingBillingEvent) {
|
||||
getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent;
|
||||
return this;
|
||||
}
|
||||
@@ -451,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 {
|
||||
|
||||
/**
|
||||
@@ -545,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. */
|
||||
@@ -665,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. */
|
||||
|
||||
@@ -17,8 +17,13 @@ package google.registry.model.contact;
|
||||
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 java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
@@ -26,6 +31,8 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.PostLoad;
|
||||
|
||||
/**
|
||||
* A persisted history entry representing an EPP modification to a contact.
|
||||
@@ -44,13 +51,13 @@ import javax.persistence.Id;
|
||||
})
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
@IdClass(ContactHistoryId.class)
|
||||
public class ContactHistory extends HistoryEntry {
|
||||
|
||||
// Store ContactBase instead of ContactResource so we don't pick up its @Id
|
||||
ContactBase contactBase;
|
||||
@Nullable ContactBase contactBase;
|
||||
|
||||
@Column(nullable = false)
|
||||
VKey<ContactResource> contactRepoId;
|
||||
@Id String contactRepoId;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
|
||||
@@ -61,14 +68,95 @@ public class ContactHistory extends HistoryEntry {
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
/** The state of the {@link ContactBase} object at this point in time. */
|
||||
public ContactBase getContactBase() {
|
||||
return contactBase;
|
||||
/**
|
||||
* The values of all the fields on the {@link ContactBase} object after the action represented by
|
||||
* this history object was executed.
|
||||
*
|
||||
* <p>Will be absent for objects created prior to the Registry 3.0 SQL migration.
|
||||
*/
|
||||
public Optional<ContactBase> getContactBase() {
|
||||
return Optional.ofNullable(contactBase);
|
||||
}
|
||||
|
||||
/** 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
|
||||
void postLoad() {
|
||||
// Normally Hibernate would see that the contact fields are all null and would fill contactBase
|
||||
// with a null object. Unfortunately, the updateTimestamp is never null in SQL.
|
||||
if (contactBase != null && contactBase.getContactId() == null) {
|
||||
contactBase = null;
|
||||
}
|
||||
// Fill in the full, symmetric, parent repo ID key
|
||||
parent = Key.create(ContactResource.class, contactRepoId);
|
||||
}
|
||||
|
||||
/** 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
|
||||
@@ -89,9 +177,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;
|
||||
}
|
||||
|
||||
@@ -99,8 +187,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));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
@@ -69,7 +70,7 @@ import javax.persistence.Table;
|
||||
public class DomainHistory extends HistoryEntry {
|
||||
|
||||
// Store DomainContent instead of DomainBase so we don't pick up its @Id
|
||||
DomainContent domainContent;
|
||||
@Nullable DomainContent domainContent;
|
||||
|
||||
@Id String domainRepoId;
|
||||
|
||||
@@ -140,9 +141,14 @@ public class DomainHistory extends HistoryEntry {
|
||||
return nsHosts;
|
||||
}
|
||||
|
||||
/** The state of the {@link DomainContent} object at this point in time. */
|
||||
public DomainContent getDomainContent() {
|
||||
return domainContent;
|
||||
/**
|
||||
* The values of all the fields on the {@link DomainContent} object after the action represented
|
||||
* by this history object was executed.
|
||||
*
|
||||
* <p>Will be absent for objects created prior to the Registry 3.0 SQL migration.
|
||||
*/
|
||||
public Optional<DomainContent> getDomainContent() {
|
||||
return Optional.ofNullable(domainContent);
|
||||
}
|
||||
|
||||
/** The key to the {@link DomainBase} this is based off of. */
|
||||
@@ -150,15 +156,23 @@ 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
|
||||
void postLoad() {
|
||||
if (domainContent != null) {
|
||||
domainContent.nsHosts = nullToEmptyImmutableCopy(nsHosts);
|
||||
// Normally Hibernate would see that the domain fields are all null and would fill
|
||||
// domainContent with a null object. Unfortunately, the updateTimestamp is never null in SQL.
|
||||
if (domainContent.getDomainName() == null) {
|
||||
domainContent = null;
|
||||
}
|
||||
}
|
||||
parent = Key.create(DomainBase.class, domainRepoId);
|
||||
}
|
||||
|
||||
/** Class to represent the composite primary key of {@link DomainHistory} entity. */
|
||||
@@ -176,19 +190,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,17 @@
|
||||
|
||||
package google.registry.model.host;
|
||||
|
||||
|
||||
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 java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
@@ -26,6 +32,8 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.PostLoad;
|
||||
|
||||
/**
|
||||
* A persisted history entry representing an EPP modification to a host.
|
||||
@@ -45,13 +53,13 @@ import javax.persistence.Id;
|
||||
})
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
@IdClass(HostHistoryId.class)
|
||||
public class HostHistory extends HistoryEntry {
|
||||
|
||||
// Store HostBase instead of HostResource so we don't pick up its @Id
|
||||
HostBase hostBase;
|
||||
@Nullable HostBase hostBase;
|
||||
|
||||
@Column(nullable = false)
|
||||
VKey<HostResource> hostRepoId;
|
||||
@Id String hostRepoId;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
|
||||
@@ -62,14 +70,93 @@ public class HostHistory extends HistoryEntry {
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
/** The state of the {@link HostBase} object at this point in time. */
|
||||
public HostBase getHostBase() {
|
||||
return hostBase;
|
||||
/**
|
||||
* The values of all the fields on the {@link HostBase} object after the action represented by
|
||||
* this history object was executed.
|
||||
*
|
||||
* <p>Will be absent for objects created prior to the Registry 3.0 SQL migration.
|
||||
*/
|
||||
public Optional<HostBase> getHostBase() {
|
||||
return Optional.ofNullable(hostBase);
|
||||
}
|
||||
|
||||
/** 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
|
||||
void postLoad() {
|
||||
// Normally Hibernate would see that the host fields are all null and would fill hostBase
|
||||
// with a null object. Unfortunately, the updateTimestamp is never null in SQL.
|
||||
if (hostBase != null && hostBase.getHostName() == null) {
|
||||
hostBase = null;
|
||||
}
|
||||
// Fill in the full, symmetric, parent repo ID key
|
||||
parent = Key.create(HostResource.class, hostRepoId);
|
||||
}
|
||||
|
||||
/** 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
|
||||
@@ -90,9 +177,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;
|
||||
}
|
||||
|
||||
@@ -100,8 +187,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import javax.persistence.AccessType;
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity
|
||||
@javax.persistence.Entity(name = "Host")
|
||||
@ExternalMessagingName("host")
|
||||
@WithStringVKey
|
||||
@Access(AccessType.FIELD) // otherwise it'll use the default if the repoId (property)
|
||||
|
||||
@@ -101,22 +101,22 @@ public class DatastoreTransactionManager implements TransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNew(Object entity) {
|
||||
public void insert(Object entity) {
|
||||
saveEntity(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAllNew(ImmutableCollection<?> entities) {
|
||||
public void insertAll(ImmutableCollection<?> entities) {
|
||||
getOfy().save().entities(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNewOrUpdate(Object entity) {
|
||||
public void put(Object entity) {
|
||||
saveEntity(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNewOrUpdateAll(ImmutableCollection<?> entities) {
|
||||
public void putAll(ImmutableCollection<?> entities) {
|
||||
getOfy().save().entities(entities);
|
||||
}
|
||||
|
||||
@@ -131,12 +131,12 @@ public class DatastoreTransactionManager implements TransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkExists(Object entity) {
|
||||
public boolean exists(Object entity) {
|
||||
return getOfy().load().key(Key.create(entity)).now() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean checkExists(VKey<T> key) {
|
||||
public <T> boolean exists(VKey<T> key) {
|
||||
return loadNullable(key) != null;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class ReservedListDualWriteDao {
|
||||
|
||||
/** Persist a new reserved list to Cloud SQL. */
|
||||
public static void save(ReservedList reservedList) {
|
||||
ofyTm().transact(() -> ofyTm().saveNewOrUpdate(reservedList));
|
||||
ofyTm().transact(() -> ofyTm().put(reservedList));
|
||||
try {
|
||||
logger.atInfo().log("Saving reserved list %s to Cloud SQL", reservedList.getName());
|
||||
ReservedListSqlDao.save(reservedList);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ReservedListSqlDao {
|
||||
/** Persist a new reserved list to Cloud SQL. */
|
||||
public static void save(ReservedList reservedList) {
|
||||
checkArgumentNotNull(reservedList, "Must specify reservedList");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(reservedList));
|
||||
jpaTm().transact(() -> jpaTm().insert(reservedList));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -178,7 +178,7 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
|
||||
boolean bySuperuser;
|
||||
|
||||
/** Reason for the change. */
|
||||
@Column(nullable = false, name = "historyReason")
|
||||
@Column(name = "historyReason")
|
||||
String reason;
|
||||
|
||||
/** Whether this change was requested by a registrar. */
|
||||
@@ -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));
|
||||
@@ -364,7 +355,10 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor
|
||||
setBySuperuser(historyEntry.bySuperuser);
|
||||
setReason(historyEntry.reason);
|
||||
setRequestedByRegistrar(historyEntry.requestedByRegistrar);
|
||||
setDomainTransactionRecords(nullToEmptyImmutableCopy(historyEntry.domainTransactionRecords));
|
||||
setDomainTransactionRecords(
|
||||
historyEntry.domainTransactionRecords == null
|
||||
? null
|
||||
: ImmutableSet.copyOf(historyEntry.domainTransactionRecords));
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+5
-1
@@ -32,7 +32,11 @@ public class CreateAutoTimestampConverter
|
||||
implements AttributeConverter<CreateAutoTimestamp, Timestamp> {
|
||||
|
||||
@Override
|
||||
public Timestamp convertToDatabaseColumn(CreateAutoTimestamp entity) {
|
||||
@Nullable
|
||||
public Timestamp convertToDatabaseColumn(@Nullable CreateAutoTimestamp entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
DateTime dateTime = firstNonNull(entity.getTimestamp(), jpaTm().getTransactionTime());
|
||||
return Timestamp.from(DateTimeUtils.toZonedDateTime(dateTime).toInstant());
|
||||
}
|
||||
|
||||
+12
-12
@@ -224,7 +224,7 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNew(Object entity) {
|
||||
public void insert(Object entity) {
|
||||
checkArgumentNotNull(entity, "entity must be specified");
|
||||
assertInTransaction();
|
||||
getEntityManager().persist(entity);
|
||||
@@ -232,14 +232,14 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAllNew(ImmutableCollection<?> entities) {
|
||||
public void insertAll(ImmutableCollection<?> entities) {
|
||||
checkArgumentNotNull(entities, "entities must be specified");
|
||||
assertInTransaction();
|
||||
entities.forEach(this::saveNew);
|
||||
entities.forEach(this::insert);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNewOrUpdate(Object entity) {
|
||||
public void put(Object entity) {
|
||||
checkArgumentNotNull(entity, "entity must be specified");
|
||||
assertInTransaction();
|
||||
getEntityManager().merge(entity);
|
||||
@@ -247,17 +247,17 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveNewOrUpdateAll(ImmutableCollection<?> entities) {
|
||||
public void putAll(ImmutableCollection<?> entities) {
|
||||
checkArgumentNotNull(entities, "entities must be specified");
|
||||
assertInTransaction();
|
||||
entities.forEach(this::saveNewOrUpdate);
|
||||
entities.forEach(this::put);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object entity) {
|
||||
checkArgumentNotNull(entity, "entity must be specified");
|
||||
assertInTransaction();
|
||||
checkArgument(checkExists(entity), "Given entity does not exist");
|
||||
checkArgument(exists(entity), "Given entity does not exist");
|
||||
getEntityManager().merge(entity);
|
||||
transactionInfo.get().addUpdate(entity);
|
||||
}
|
||||
@@ -270,22 +270,22 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean checkExists(VKey<T> key) {
|
||||
public <T> boolean exists(VKey<T> key) {
|
||||
checkArgumentNotNull(key, "key must be specified");
|
||||
EntityType<?> entityType = getEntityType(key.getKind());
|
||||
ImmutableSet<EntityId> entityIds = getEntityIdsFromSqlKey(entityType, key.getSqlKey());
|
||||
return checkExists(entityType.getName(), entityIds);
|
||||
return exists(entityType.getName(), entityIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkExists(Object entity) {
|
||||
public boolean exists(Object entity) {
|
||||
checkArgumentNotNull(entity, "entity must be specified");
|
||||
EntityType<?> entityType = getEntityType(entity.getClass());
|
||||
ImmutableSet<EntityId> entityIds = getEntityIdsFromEntity(entityType, entity);
|
||||
return checkExists(entityType.getName(), entityIds);
|
||||
return exists(entityType.getName(), entityIds);
|
||||
}
|
||||
|
||||
private boolean checkExists(String entityName, ImmutableSet<EntityId> entityIds) {
|
||||
private boolean exists(String entityName, ImmutableSet<EntityId> entityIds) {
|
||||
assertInTransaction();
|
||||
TypedQuery<Integer> query =
|
||||
getEntityManager()
|
||||
|
||||
@@ -208,7 +208,7 @@ public class Transaction extends ImmutableObject implements Buildable {
|
||||
|
||||
@Override
|
||||
public void writeToDatastore() {
|
||||
ofyTm().saveNewOrUpdate(entity);
|
||||
ofyTm().put(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,16 +86,16 @@ public interface TransactionManager {
|
||||
DateTime getTransactionTime();
|
||||
|
||||
/** Persists a new entity in the database, throws exception if the entity already exists. */
|
||||
void saveNew(Object entity);
|
||||
void insert(Object entity);
|
||||
|
||||
/** Persists all new entities in the database, throws exception if any entity already exists. */
|
||||
void saveAllNew(ImmutableCollection<?> entities);
|
||||
void insertAll(ImmutableCollection<?> entities);
|
||||
|
||||
/** Persists a new entity or update the existing entity in the database. */
|
||||
void saveNewOrUpdate(Object entity);
|
||||
void put(Object entity);
|
||||
|
||||
/** Persists all new entities or update the existing entities in the database. */
|
||||
void saveNewOrUpdateAll(ImmutableCollection<?> entities);
|
||||
void putAll(ImmutableCollection<?> entities);
|
||||
|
||||
/** Updates an entity in the database, throws exception if the entity does not exist. */
|
||||
void update(Object entity);
|
||||
@@ -104,10 +104,10 @@ public interface TransactionManager {
|
||||
void updateAll(ImmutableCollection<?> entities);
|
||||
|
||||
/** Returns whether the given entity with same ID exists. */
|
||||
boolean checkExists(Object entity);
|
||||
boolean exists(Object entity);
|
||||
|
||||
/** Returns whether the entity of given key exists. */
|
||||
<T> boolean checkExists(VKey<T> key);
|
||||
<T> boolean exists(VKey<T> key);
|
||||
|
||||
/** Loads the entity by its id, returns empty if the entity doesn't exist. */
|
||||
<T> Optional<T> maybeLoad(VKey<T> key);
|
||||
|
||||
@@ -72,7 +72,7 @@ final class CreateRegistrarCommand extends CreateOrUpdateRegistrarCommand
|
||||
|
||||
@Override
|
||||
void saveToCloudSql(Registrar registrar) {
|
||||
jpaTm().saveNew(registrar);
|
||||
jpaTm().insert(registrar);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -85,7 +85,7 @@ class WriteToSqlTest implements Serializable {
|
||||
// Required for contacts created below.
|
||||
Registrar ofyRegistrar = AppEngineExtension.makeRegistrar2();
|
||||
store.insertOrUpdate(ofyRegistrar);
|
||||
jpaTm().transact(() -> jpaTm().saveNewOrUpdate(store.loadAsOfyEntity(ofyRegistrar)));
|
||||
jpaTm().transact(() -> jpaTm().put(store.loadAsOfyEntity(ofyRegistrar)));
|
||||
|
||||
ImmutableList.Builder<Entity> builder = new ImmutableList.Builder<>();
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ class Spec11PipelineTest {
|
||||
.build();
|
||||
|
||||
verify(mockJpaTm).transact(any(Runnable.class));
|
||||
verify(mockJpaTm).saveNew(expected);
|
||||
verify(mockJpaTm).insert(expected);
|
||||
verifyNoMoreInteractions(mockJpaTm);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,25 @@ import javax.annotation.Nullable;
|
||||
/** Truth subject for asserting things about ImmutableObjects that are not built in. */
|
||||
public final class ImmutableObjectSubject extends Subject {
|
||||
|
||||
private final ImmutableObject actual;
|
||||
@Nullable private final ImmutableObject actual;
|
||||
|
||||
protected ImmutableObjectSubject(FailureMetadata failureMetadata, ImmutableObject actual) {
|
||||
protected ImmutableObjectSubject(
|
||||
FailureMetadata failureMetadata, @Nullable ImmutableObject actual) {
|
||||
super(failureMetadata, actual);
|
||||
this.actual = actual;
|
||||
}
|
||||
|
||||
public void isEqualExceptFields(ImmutableObject expected, String... ignoredFields) {
|
||||
Map<Field, Object> actualFields = filterFields(actual, ignoredFields);
|
||||
Map<Field, Object> expectedFields = filterFields(expected, ignoredFields);
|
||||
assertThat(actualFields).containsExactlyEntriesIn(expectedFields);
|
||||
public void isEqualExceptFields(@Nullable ImmutableObject expected, String... ignoredFields) {
|
||||
if (actual == null) {
|
||||
assertThat(expected).isNull();
|
||||
} else {
|
||||
assertThat(expected).isNotNull();
|
||||
}
|
||||
if (actual != null) {
|
||||
Map<Field, Object> actualFields = filterFields(actual, ignoredFields);
|
||||
Map<Field, Object> expectedFields = filterFields(expected, ignoredFields);
|
||||
assertThat(actualFields).containsExactlyEntriesIn(expectedFields);
|
||||
}
|
||||
}
|
||||
|
||||
public static Correspondence<ImmutableObject, ImmutableObject> immutableObjectCorrespondence(
|
||||
|
||||
@@ -39,7 +39,6 @@ import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.util.DateTimeUtils;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -57,7 +56,6 @@ public class BillingEventTest extends EntityTestCase {
|
||||
private HistoryEntry historyEntry;
|
||||
private HistoryEntry historyEntry2;
|
||||
private DomainBase domain;
|
||||
private BillingEvent.OneTime sqlOneTime;
|
||||
private BillingEvent.OneTime oneTime;
|
||||
private BillingEvent.OneTime oneTimeSynthetic;
|
||||
private BillingEvent.Recurring recurring;
|
||||
@@ -107,16 +105,6 @@ public class BillingEventTest extends EntityTestCase {
|
||||
.setBillingTime(now.plusDays(5))
|
||||
.setAllocationToken(allocationToken.createVKey())));
|
||||
|
||||
sqlOneTime =
|
||||
oneTime
|
||||
.asBuilder()
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.setAllocationToken(
|
||||
VKey.create(
|
||||
AllocationToken.class, allocationToken.getToken(), Key.create(allocationToken)))
|
||||
.build();
|
||||
|
||||
recurring =
|
||||
persistResource(
|
||||
commonInit(
|
||||
@@ -179,80 +167,43 @@ public class BillingEventTest extends EntityTestCase {
|
||||
}
|
||||
|
||||
private void saveNewBillingEvent(BillingEvent billingEvent) {
|
||||
billingEvent.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(billingEvent));
|
||||
jpaTm().transact(() -> jpaTm().insert(billingEvent));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_OneTime() {
|
||||
saveRegistrar("a registrar");
|
||||
saveNewBillingEvent(sqlOneTime);
|
||||
saveNewBillingEvent(oneTime);
|
||||
|
||||
BillingEvent.OneTime persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(BillingEvent.OneTime.class, sqlOneTime.id)));
|
||||
// TODO(shicong): Remove these fixes after the entities are fully compatible
|
||||
BillingEvent.OneTime persisted = jpaTm().transact(() -> jpaTm().load(oneTime.createVKey()));
|
||||
// TODO(b/168325240): Remove this fix after VKeyConverter generates symmetric key for
|
||||
// AllocationToken.
|
||||
BillingEvent.OneTime fixed =
|
||||
persisted
|
||||
.asBuilder()
|
||||
.setParent(sqlOneTime.getParentKey())
|
||||
.setAllocationToken(sqlOneTime.getAllocationToken().get())
|
||||
.build();
|
||||
assertThat(fixed).isEqualTo(sqlOneTime);
|
||||
persisted.asBuilder().setAllocationToken(oneTime.getAllocationToken().get()).build();
|
||||
assertThat(fixed).isEqualTo(oneTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_Cancellation() {
|
||||
saveRegistrar("a registrar");
|
||||
saveNewBillingEvent(sqlOneTime);
|
||||
VKey<BillingEvent.OneTime> sqlVKey = VKey.createSql(BillingEvent.OneTime.class, sqlOneTime.id);
|
||||
BillingEvent sqlCancellationOneTime =
|
||||
cancellationOneTime
|
||||
.asBuilder()
|
||||
.setOneTimeEventKey(sqlVKey)
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.build();
|
||||
saveNewBillingEvent(sqlCancellationOneTime);
|
||||
saveNewBillingEvent(oneTime);
|
||||
saveNewBillingEvent(cancellationOneTime);
|
||||
|
||||
BillingEvent.Cancellation persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
jpaTm()
|
||||
.load(
|
||||
VKey.createSql(
|
||||
BillingEvent.Cancellation.class, sqlCancellationOneTime.id)));
|
||||
// TODO(shicong): Remove these fixes after the entities are fully compatible
|
||||
jpaTm().transact(() -> jpaTm().load(cancellationOneTime.createVKey()));
|
||||
// TODO(b/168537779): Remove this fix after VKey<OneTime> can be reconstructed correctly.
|
||||
BillingEvent.Cancellation fixed =
|
||||
persisted
|
||||
.asBuilder()
|
||||
.setParent(sqlCancellationOneTime.getParentKey())
|
||||
.setOneTimeEventKey(sqlVKey)
|
||||
.build();
|
||||
assertThat(fixed).isEqualTo(sqlCancellationOneTime);
|
||||
persisted.asBuilder().setOneTimeEventKey(oneTime.createVKey()).build();
|
||||
assertThat(fixed).isEqualTo(cancellationOneTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_Recurring() {
|
||||
saveRegistrar("a registrar");
|
||||
BillingEvent.Recurring sqlRecurring =
|
||||
recurring
|
||||
.asBuilder()
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.build();
|
||||
saveNewBillingEvent(sqlRecurring);
|
||||
saveNewBillingEvent(recurring);
|
||||
|
||||
BillingEvent.Recurring persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> jpaTm().load(VKey.createSql(BillingEvent.Recurring.class, sqlRecurring.id)));
|
||||
// TODO(shicong): Remove these fixes after the entities are fully compatible
|
||||
BillingEvent.Recurring fixed =
|
||||
persisted.asBuilder().setParent(sqlRecurring.getParentKey()).build();
|
||||
assertThat(fixed).isEqualTo(sqlRecurring);
|
||||
BillingEvent.Recurring persisted = jpaTm().transact(() -> jpaTm().load(recurring.createVKey()));
|
||||
assertThat(persisted).isEqualTo(recurring);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ContactResourceTest extends EntityTestCase {
|
||||
|
||||
@Test
|
||||
void testCloudSqlPersistence_failWhenViolateForeignKeyConstraint() {
|
||||
assertThrowForeignKeyViolation(() -> jpaTm().transact(() -> jpaTm().saveNew(originalContact)));
|
||||
assertThrowForeignKeyViolation(() -> jpaTm().transact(() -> jpaTm().insert(originalContact)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,7 +134,7 @@ public class ContactResourceTest extends EntityTestCase {
|
||||
saveRegistrar("registrar3");
|
||||
saveRegistrar("gaining");
|
||||
saveRegistrar("losing");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(originalContact));
|
||||
jpaTm().transact(() -> jpaTm().insert(originalContact));
|
||||
ContactResource persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
|
||||
@@ -139,9 +139,9 @@ public class DomainBaseSqlTest {
|
||||
.transact(
|
||||
() -> {
|
||||
// Persist the domain without the associated host object.
|
||||
jpaTm().saveNew(contact);
|
||||
jpaTm().saveNew(contact2);
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(contact2);
|
||||
jpaTm().insert(domain);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -153,8 +153,8 @@ public class DomainBaseSqlTest {
|
||||
.transact(
|
||||
() -> {
|
||||
// Persist the domain without the associated contact objects.
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().insert(domain);
|
||||
jpaTm().insert(host);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public class DomainBaseSqlTest {
|
||||
.transact(
|
||||
() -> {
|
||||
DomainBase persisted = jpaTm().load(domain.createVKey());
|
||||
jpaTm().saveNewOrUpdate(persisted.asBuilder().build());
|
||||
jpaTm().put(persisted.asBuilder().build());
|
||||
});
|
||||
jpaTm()
|
||||
.transact(
|
||||
@@ -185,7 +185,7 @@ public class DomainBaseSqlTest {
|
||||
DomainBase persisted = jpaTm().load(domain.createVKey());
|
||||
DomainBase modified =
|
||||
persisted.asBuilder().setGracePeriods(ImmutableSet.of()).build();
|
||||
jpaTm().saveNewOrUpdate(modified);
|
||||
jpaTm().put(modified);
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -204,7 +204,7 @@ public class DomainBaseSqlTest {
|
||||
() -> {
|
||||
DomainBase persisted = jpaTm().load(domain.createVKey());
|
||||
DomainBase modified = persisted.asBuilder().setGracePeriods(null).build();
|
||||
jpaTm().saveNewOrUpdate(modified);
|
||||
jpaTm().put(modified);
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -229,7 +229,7 @@ public class DomainBaseSqlTest {
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.RENEW, "4-COM", END_OF_TIME, "registrar1", null))
|
||||
.build();
|
||||
jpaTm().saveNewOrUpdate(modified);
|
||||
jpaTm().put(modified);
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -281,7 +281,7 @@ public class DomainBaseSqlTest {
|
||||
builder.removeGracePeriod(gracePeriod);
|
||||
}
|
||||
}
|
||||
jpaTm().saveNewOrUpdate(builder.build());
|
||||
jpaTm().put(builder.build());
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -301,7 +301,7 @@ public class DomainBaseSqlTest {
|
||||
DomainBase persisted = jpaTm().load(domain.createVKey());
|
||||
DomainBase modified =
|
||||
persisted.asBuilder().setGracePeriods(ImmutableSet.of()).build();
|
||||
jpaTm().saveNewOrUpdate(modified);
|
||||
jpaTm().put(modified);
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -316,7 +316,7 @@ public class DomainBaseSqlTest {
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.ADD, "4-COM", END_OF_TIME, "registrar1", null))
|
||||
.build();
|
||||
jpaTm().saveNewOrUpdate(modified);
|
||||
jpaTm().put(modified);
|
||||
});
|
||||
|
||||
jpaTm()
|
||||
@@ -339,13 +339,13 @@ public class DomainBaseSqlTest {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(contact);
|
||||
jpaTm().saveNew(contact2);
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(contact2);
|
||||
jpaTm().insert(domain);
|
||||
jpaTm().insert(host);
|
||||
});
|
||||
domain = domain.asBuilder().setNameservers(ImmutableSet.of()).build();
|
||||
jpaTm().transact(() -> jpaTm().saveNewOrUpdate(domain));
|
||||
jpaTm().transact(() -> jpaTm().put(domain));
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
@@ -382,16 +382,16 @@ public class DomainBaseSqlTest {
|
||||
// Persist the contacts. Note that these need to be persisted before the domain
|
||||
// otherwise we get a foreign key constraint error. If we ever decide to defer the
|
||||
// relevant foreign key checks to commit time, then the order would not matter.
|
||||
jpaTm().saveNew(contact);
|
||||
jpaTm().saveNew(contact2);
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(contact2);
|
||||
|
||||
// Persist the domain.
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().insert(domain);
|
||||
|
||||
// Persist the host. This does _not_ need to be persisted before the domain,
|
||||
// because only the row in the join table (DomainHost) is subject to foreign key
|
||||
// constraints, and Hibernate knows to insert it after domain and host.
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().insert(host);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +95,8 @@ public class AllocationTokenTest extends EntityTestCase {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(unlimitedUseToken);
|
||||
jpaTm().saveNew(singleUseToken);
|
||||
jpaTm().insert(unlimitedUseToken);
|
||||
jpaTm().insert(singleUseToken);
|
||||
});
|
||||
jpaTm()
|
||||
.transact(
|
||||
|
||||
@@ -44,16 +44,42 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(contact));
|
||||
jpaTm().transact(() -> jpaTm().insert(contact));
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = jpaTm().transact(() -> jpaTm().load(contactVKey));
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contactVKey);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contact.getRepoId());
|
||||
contactHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(contactHistory));
|
||||
jpaTm().transact(() -> jpaTm().insert(contactHistory));
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
ContactHistory fromDatabase = jpaTm().load(VKey.createSql(ContactHistory.class, 1L));
|
||||
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
|
||||
assertContactHistoriesEqual(fromDatabase, contactHistory);
|
||||
assertThat(fromDatabase.getContactRepoId().getSqlKey())
|
||||
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLegacyPersistence_nullContactBase() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
jpaTm().transact(() -> jpaTm().insert(contact));
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = jpaTm().transact(() -> jpaTm().load(contactVKey));
|
||||
ContactHistory contactHistory =
|
||||
createContactHistory(contactFromDb, contact.getRepoId())
|
||||
.asBuilder()
|
||||
.setContactBase(null)
|
||||
.build();
|
||||
contactHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().insert(contactHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
|
||||
assertContactHistoriesEqual(fromDatabase, contactHistory);
|
||||
assertThat(fromDatabase.getContactRepoId().getSqlKey())
|
||||
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
|
||||
@@ -65,18 +91,17 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
tm().transact(() -> tm().saveNew(contact));
|
||||
tm().transact(() -> tm().insert(contact));
|
||||
VKey<ContactResource> contactVKey = contact.createVKey();
|
||||
ContactResource contactFromDb = tm().transact(() -> tm().load(contactVKey));
|
||||
fakeClock.advanceOneMilli();
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb, contactVKey);
|
||||
tm().transact(() -> tm().saveNew(contactHistory));
|
||||
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));
|
||||
@@ -85,8 +110,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))
|
||||
@@ -97,16 +121,16 @@ 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())
|
||||
.isEqualExceptFields(two.getContactBase(), "repoId");
|
||||
.that(one.getContactBase().orElse(null))
|
||||
.isEqualExceptFields(two.getContactBase().orElse(null), "repoId");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link DomainHistory}. */
|
||||
@@ -49,30 +50,35 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPersistence() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
domainHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().insert(domainHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().saveNew(contact);
|
||||
DomainHistory fromDatabase = jpaTm().load(domainHistory.createVKey());
|
||||
assertDomainHistoriesEqual(fromDatabase, domainHistory);
|
||||
assertThat(fromDatabase.getDomainRepoId().getSqlKey())
|
||||
.isEqualTo(domainHistory.getDomainRepoId().getSqlKey());
|
||||
});
|
||||
}
|
||||
|
||||
DomainBase domain =
|
||||
newDomainBase("example.tld", "domainRepoId", contact)
|
||||
.asBuilder()
|
||||
.setNameservers(host.createVKey())
|
||||
.build();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(domain));
|
||||
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
@Test
|
||||
void testLegacyPersistence_nullResource() {
|
||||
DomainBase domain = createDomainWithContactsAndHosts();
|
||||
DomainHistory domainHistory =
|
||||
createDomainHistory(domain).asBuilder().setDomainContent(null).build();
|
||||
domainHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(domainHistory));
|
||||
jpaTm().transact(() -> jpaTm().insert(domainHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
@@ -91,15 +97,13 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
|
||||
@Test
|
||||
void testOfyPersistence() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
|
||||
tm().transact(
|
||||
() -> {
|
||||
tm().saveNew(host);
|
||||
tm().saveNew(contact);
|
||||
tm().insert(host);
|
||||
tm().insert(contact);
|
||||
});
|
||||
fakeClock.advanceOneMilli();
|
||||
|
||||
@@ -108,17 +112,16 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
.asBuilder()
|
||||
.setNameservers(host.createVKey())
|
||||
.build();
|
||||
tm().transact(() -> tm().saveNew(domain));
|
||||
tm().transact(() -> tm().insert(domain));
|
||||
|
||||
fakeClock.advanceOneMilli();
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
tm().transact(() -> tm().saveNew(domainHistory));
|
||||
tm().transact(() -> tm().insert(domainHistory));
|
||||
|
||||
// retrieving a HistoryEntry or a DomainHistory with the same key should return the same object
|
||||
// note: due to the @EntitySubclass annotation. all Keys for ContactHistory objects will have
|
||||
// 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));
|
||||
@@ -127,11 +130,33 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
assertThat(domainHistoryFromDb).isEqualTo(historyEntryFromDb);
|
||||
}
|
||||
|
||||
static DomainBase createDomainWithContactsAndHosts() {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().insert(host);
|
||||
jpaTm().insert(contact);
|
||||
});
|
||||
|
||||
DomainBase domain =
|
||||
newDomainBase("example.tld", "domainRepoId", contact)
|
||||
.asBuilder()
|
||||
.setNameservers(host.createVKey())
|
||||
.build();
|
||||
jpaTm().transact(() -> jpaTm().insert(domain));
|
||||
return domain;
|
||||
}
|
||||
|
||||
static void assertDomainHistoriesEqual(DomainHistory one, DomainHistory two) {
|
||||
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
|
||||
// compare it separately
|
||||
assertThat(one.getDomainTransactionRecords())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
||||
// 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.
|
||||
@@ -44,17 +44,17 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(host));
|
||||
VKey<HostResource> hostVKey = VKey.createSql(HostResource.class, "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));
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, hostVKey);
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb, host.getRepoId());
|
||||
hostHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(hostHistory));
|
||||
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());
|
||||
@@ -62,21 +62,44 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOfySave() {
|
||||
void testLegacyPersistence_nullHostBase() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
jpaTm().transact(() -> jpaTm().insert(host));
|
||||
|
||||
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(host.createVKey()));
|
||||
HostHistory hostHistory =
|
||||
createHostHistory(hostFromDb, host.getRepoId()).asBuilder().setHostBase(null).build();
|
||||
hostHistory.id = null;
|
||||
jpaTm().transact(() -> jpaTm().insert(hostHistory));
|
||||
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
HostHistory fromDatabase = jpaTm().load(hostHistory.createVKey());
|
||||
assertHostHistoriesEqual(fromDatabase, hostHistory);
|
||||
assertThat(fromDatabase.getHostRepoId().getSqlKey())
|
||||
.isEqualTo(hostHistory.getHostRepoId().getSqlKey());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOfySave() {
|
||||
saveRegistrar("registrar1");
|
||||
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
tm().transact(() -> tm().saveNew(host));
|
||||
VKey<HostResource> hostVKey = VKey.create(HostResource.class, "host1", Key.create(host));
|
||||
tm().transact(() -> tm().insert(host));
|
||||
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().saveNew(hostHistory));
|
||||
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 ContactHistory objects will have
|
||||
// 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));
|
||||
@@ -88,11 +111,11 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
private void assertHostHistoriesEqual(HostHistory one, HostHistory two) {
|
||||
assertAboutImmutableObjects().that(one).isEqualExceptFields(two, "hostBase");
|
||||
assertAboutImmutableObjects()
|
||||
.that(one.getHostBase())
|
||||
.isEqualExceptFields(two.getHostBase(), "repoId");
|
||||
.that(one.getHostBase().orElse(null))
|
||||
.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))
|
||||
@@ -103,7 +126,7 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(true)
|
||||
.setHostBase(hostBase)
|
||||
.setHostRepoId(hostVKey)
|
||||
.setHostRepoId(hostRepoId)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
// 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.
|
||||
|
||||
package google.registry.model.history;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatastoreHelper.newContactResourceWithRoid;
|
||||
import static google.registry.testing.DatastoreHelper.newHostResourceWithRoid;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.HostHistory;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests to check {@link HistoryEntry} + its subclasses' transitions to/from Datastore/SQL. */
|
||||
public class LegacyHistoryObjectTest extends EntityTestCase {
|
||||
|
||||
public LegacyHistoryObjectTest() {
|
||||
super(JpaEntityCoverageCheck.ENABLED);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFullConversion_contact() {
|
||||
// Create+save an old contact HistoryEntry, reload it, and verify it's a proper ContactHistory
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
HistoryEntry legacyHistoryEntry = historyEntryBuilderFor(contact).build();
|
||||
tm().transact(() -> tm().insert(legacyHistoryEntry));
|
||||
|
||||
// In Datastore, we will save it as HistoryEntry but retrieve it as ContactHistory
|
||||
long historyEntryId = legacyHistoryEntry.getId();
|
||||
HistoryEntry fromObjectify =
|
||||
tm().transact(
|
||||
() ->
|
||||
tm().load(
|
||||
VKey.create(
|
||||
HistoryEntry.class,
|
||||
historyEntryId,
|
||||
Key.create(legacyHistoryEntry))));
|
||||
// The objects will be mostly the same, but the ContactHistory object has a couple extra fields
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyHistoryEntry)
|
||||
.isEqualExceptFields(fromObjectify, "contactBase", "contactRepoId");
|
||||
assertThat(fromObjectify instanceof ContactHistory).isTrue();
|
||||
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(
|
||||
() -> {
|
||||
jpaTm().insert(contact);
|
||||
jpaTm().insert(legacyContactHistory);
|
||||
});
|
||||
ContactHistory legacyHistoryFromSql =
|
||||
jpaTm().transact(() -> jpaTm().load(legacyContactHistory.createVKey()));
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyContactHistory)
|
||||
.isEqualExceptFields(legacyHistoryFromSql);
|
||||
// can't compare contactRepoId directly since it doesn't save the ofy key
|
||||
assertThat(legacyContactHistory.getContactRepoId().getSqlKey())
|
||||
.isEqualTo(legacyHistoryFromSql.getContactRepoId().getSqlKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFullConversion_domain() {
|
||||
// Create+save an old domain HistoryEntry, reload it, and verify it's a proper DomainHistory
|
||||
DomainBase domain = DomainHistoryTest.createDomainWithContactsAndHosts();
|
||||
HistoryEntry legacyHistoryEntry = historyEntryForDomain(domain);
|
||||
tm().transact(() -> tm().insert(legacyHistoryEntry));
|
||||
|
||||
// In Datastore, we will save it as HistoryEntry but retrieve it as DomainHistory
|
||||
long historyEntryId = legacyHistoryEntry.getId();
|
||||
HistoryEntry fromObjectify =
|
||||
tm().transact(
|
||||
() ->
|
||||
tm().load(
|
||||
VKey.create(
|
||||
HistoryEntry.class,
|
||||
historyEntryId,
|
||||
Key.create(legacyHistoryEntry))));
|
||||
// The objects will be mostly the same, but the DomainHistory object has a couple extra fields
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyHistoryEntry)
|
||||
.isEqualExceptFields(fromObjectify, "domainContent", "domainRepoId", "nsHosts");
|
||||
assertThat(fromObjectify instanceof DomainHistory).isTrue();
|
||||
DomainHistory legacyDomainHistory = (DomainHistory) fromObjectify;
|
||||
|
||||
// Next, save that from-Datastore object in SQL and verify we can load it back in
|
||||
jpaTm().transact(() -> jpaTm().insert(legacyDomainHistory));
|
||||
DomainHistory legacyHistoryFromSql =
|
||||
jpaTm().transact(() -> jpaTm().load(legacyDomainHistory.createVKey()));
|
||||
// Don't compare nsHosts directly because one is null and the other is empty
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyDomainHistory)
|
||||
.isEqualExceptFields(
|
||||
// NB: period, transaction records, and other client ID are added in #794
|
||||
legacyHistoryFromSql, "period", "domainTransactionRecords", "otherClientId", "nsHosts");
|
||||
assertThat(nullToEmpty(legacyDomainHistory.getNsHosts()))
|
||||
.isEqualTo(nullToEmpty(legacyHistoryFromSql.getNsHosts()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFullConversion_host() {
|
||||
// Create+save an old host HistoryEntry, reload it, and verify it's a proper HostHistory
|
||||
HostResource host = newHostResourceWithRoid("hs1.example.com", "host1");
|
||||
HistoryEntry legacyHistoryEntry = historyEntryBuilderFor(host).build();
|
||||
tm().transact(() -> tm().insert(legacyHistoryEntry));
|
||||
|
||||
// In Datastore, we will save it as HistoryEntry but retrieve it as HostHistory
|
||||
long historyEntryId = legacyHistoryEntry.getId();
|
||||
HistoryEntry fromObjectify =
|
||||
tm().transact(
|
||||
() ->
|
||||
tm().load(
|
||||
VKey.create(
|
||||
HistoryEntry.class,
|
||||
historyEntryId,
|
||||
Key.create(legacyHistoryEntry))));
|
||||
// The objects will be mostly the same, but the HostHistory object has a couple extra fields
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyHistoryEntry)
|
||||
.isEqualExceptFields(fromObjectify, "hostBase", "hostRepoId");
|
||||
assertThat(fromObjectify instanceof HostHistory).isTrue();
|
||||
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(
|
||||
() -> {
|
||||
jpaTm().insert(host);
|
||||
jpaTm().insert(legacyHostHistory);
|
||||
});
|
||||
HostHistory legacyHistoryFromSql =
|
||||
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())
|
||||
.isEqualTo(legacyHistoryFromSql.getHostRepoId().getSqlKey());
|
||||
}
|
||||
|
||||
private HistoryEntry historyEntryForDomain(DomainBase domain) {
|
||||
DomainTransactionRecord transactionRecord =
|
||||
new DomainTransactionRecord.Builder()
|
||||
.setTld("foobar")
|
||||
.setReportingTime(fakeClock.nowUtc())
|
||||
.setReportField(TransactionReportField.NET_ADDS_1_YR)
|
||||
.setReportAmount(1)
|
||||
.build();
|
||||
return historyEntryBuilderFor(domain)
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.setDomainTransactionRecords(ImmutableSet.of(transactionRecord))
|
||||
.setOtherClientId("TheRegistrar")
|
||||
.build();
|
||||
}
|
||||
|
||||
private HistoryEntry.Builder historyEntryBuilderFor(EppResource parent) {
|
||||
return new HistoryEntry.Builder()
|
||||
.setParent(parent)
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
|
||||
.setModificationTime(fakeClock.nowUtc())
|
||||
.setClientId("TheRegistrar")
|
||||
.setTrid(Trid.create("ABC-123", "server-trid"))
|
||||
.setBySuperuser(false)
|
||||
.setReason("reason")
|
||||
.setRequestedByRegistrar(false);
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class PollMessageTest extends EntityTestCase {
|
||||
@Test
|
||||
void testCloudSqlPersistenceOneTime() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(oneTime));
|
||||
jpaTm().transact(() -> jpaTm().insert(oneTime));
|
||||
PollMessage.OneTime persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(PollMessage.OneTime.class, oneTime.id)));
|
||||
persisted.parent = oneTime.parent;
|
||||
@@ -94,7 +94,7 @@ public class PollMessageTest extends EntityTestCase {
|
||||
@Test
|
||||
void testCloudSqlPersistenceAutorenew() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
jpaTm().transact(() -> jpaTm().saveNew(autoRenew));
|
||||
jpaTm().transact(() -> jpaTm().insert(autoRenew));
|
||||
PollMessage.Autorenew persisted =
|
||||
jpaTm()
|
||||
.transact(
|
||||
@@ -107,14 +107,14 @@ public class PollMessageTest extends EntityTestCase {
|
||||
void testCloudSqlSupportForPolymorphicVKey() {
|
||||
saveRegistrar("TheRegistrar");
|
||||
|
||||
jpaTm().transact(() -> jpaTm().saveNew(oneTime));
|
||||
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().saveNew(autoRenew));
|
||||
jpaTm().transact(() -> jpaTm().insert(autoRenew));
|
||||
PollMessage persistedAutoRenew =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(PollMessage.class, autoRenew.getId())));
|
||||
assertThat(persistedAutoRenew).isInstanceOf(PollMessage.Autorenew.class);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class RegistryTest extends EntityTestCase {
|
||||
PremiumList pl = persistPremiumList("tld2", "lol,USD 50", "cat,USD 700");
|
||||
Registry registry =
|
||||
Registry.get("tld").asBuilder().setReservedLists(rl15).setPremiumList(pl).build();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(registry));
|
||||
jpaTm().transact(() -> jpaTm().insert(registry));
|
||||
Registry persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(Registry.class, registry.tldStrId)));
|
||||
assertThat(persisted).isEqualTo(registry);
|
||||
|
||||
@@ -37,8 +37,8 @@ public class Spec11ThreatMatchDaoTest extends EntityTestCase {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveAllNew(getThreatMatchesToday());
|
||||
jpaTm().saveAllNew(getThreatMatchesYesterday());
|
||||
jpaTm().insertAll(getThreatMatchesToday());
|
||||
jpaTm().insertAll(getThreatMatchesYesterday());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -107,10 +107,10 @@ public class Spec11ThreatMatchTest extends EntityTestCase {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(registrantContact);
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().saveNew(threat);
|
||||
jpaTm().insert(registrantContact);
|
||||
jpaTm().insert(domain);
|
||||
jpaTm().insert(host);
|
||||
jpaTm().insert(threat);
|
||||
});
|
||||
|
||||
VKey<Spec11ThreatMatch> threatVKey = VKey.createSql(Spec11ThreatMatch.class, threat.getId());
|
||||
@@ -130,10 +130,10 @@ public class Spec11ThreatMatchTest extends EntityTestCase {
|
||||
.transact(
|
||||
() -> {
|
||||
// Persist the threat without the associated registrar.
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().saveNew(registrantContact);
|
||||
jpaTm().saveNew(domain);
|
||||
jpaTm().saveNew(threat);
|
||||
jpaTm().insert(host);
|
||||
jpaTm().insert(registrantContact);
|
||||
jpaTm().insert(domain);
|
||||
jpaTm().insert(threat);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -145,9 +145,9 @@ public class Spec11ThreatMatchTest extends EntityTestCase {
|
||||
.transact(
|
||||
() -> {
|
||||
// Persist the threat without the associated domain.
|
||||
jpaTm().saveNew(registrantContact);
|
||||
jpaTm().saveNew(host);
|
||||
jpaTm().saveNew(threat);
|
||||
jpaTm().insert(registrantContact);
|
||||
jpaTm().insert(host);
|
||||
jpaTm().insert(threat);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class EntityCallbacksListenerTest {
|
||||
@Test
|
||||
void verifyAllCallbacks_executedExpectedTimes() {
|
||||
TestEntity testPersist = new TestEntity();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testPersist));
|
||||
jpaTm().transact(() -> jpaTm().insert(testPersist));
|
||||
checkAll(testPersist, 1, 0, 0, 0);
|
||||
|
||||
TestEntity testUpdate = new TestEntity();
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class DurationConverterTest {
|
||||
|
||||
private void assertPersistedEntityHasSameDuration(Duration duration) {
|
||||
DurationTestEntity entity = new DurationTestEntity(duration);
|
||||
jpaTm().transact(() -> jpaTm().saveNew(entity));
|
||||
jpaTm().transact(() -> jpaTm().insert(entity));
|
||||
DurationTestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(DurationTestEntity.class, "id"));
|
||||
assertThat(persisted.duration.getMillis()).isEqualTo(duration.getMillis());
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class InetAddressSetConverterTest {
|
||||
|
||||
private void verifySaveAndLoad(@Nullable Set<InetAddress> inetAddresses) {
|
||||
InetAddressSetTestEntity testEntity = new InetAddressSetTestEntity(inetAddresses);
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testEntity));
|
||||
jpaTm().transact(() -> jpaTm().insert(testEntity));
|
||||
InetAddressSetTestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(InetAddressSetTestEntity.class, "id")));
|
||||
assertThat(persisted.addresses).isEqualTo(inetAddresses);
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class LocalDateConverterTest {
|
||||
|
||||
private LocalDateConverterTestEntity persistAndLoadTestEntity(LocalDate date) {
|
||||
LocalDateConverterTestEntity entity = new LocalDateConverterTestEntity(date);
|
||||
jpaTm().transact(() -> jpaTm().saveNew(entity));
|
||||
jpaTm().transact(() -> jpaTm().insert(entity));
|
||||
LocalDateConverterTestEntity retrievedEntity =
|
||||
jpaTm()
|
||||
.transact(() -> jpaTm().load(VKey.createSql(LocalDateConverterTestEntity.class, "id")));
|
||||
|
||||
+62
-62
@@ -132,10 +132,10 @@ class JpaTransactionManagerImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNew_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isTrue();
|
||||
void insert_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().load(theEntityKey))).isEqualTo(theEntity);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ class JpaTransactionManagerImplTest {
|
||||
void transact_retriesOptimisticLockExceptions() {
|
||||
JpaTransactionManager spyJpaTm = spy(jpaTm());
|
||||
doThrow(OptimisticLockException.class).when(spyJpaTm).delete(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
OptimisticLockException.class,
|
||||
() -> spyJpaTm.transact(() -> spyJpaTm.delete(theEntityKey)));
|
||||
@@ -162,7 +162,7 @@ class JpaTransactionManagerImplTest {
|
||||
void transactNoRetry_doesNotRetryOptimisticLockException() {
|
||||
JpaTransactionManager spyJpaTm = spy(jpaTm());
|
||||
doThrow(OptimisticLockException.class).when(spyJpaTm).delete(any(VKey.class));
|
||||
spyJpaTm.transactNoRetry(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transactNoRetry(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
OptimisticLockException.class,
|
||||
() -> spyJpaTm.transactNoRetry(() -> spyJpaTm.delete(theEntityKey)));
|
||||
@@ -183,7 +183,7 @@ class JpaTransactionManagerImplTest {
|
||||
doThrow(new RuntimeException().initCause(new OptimisticLockException()))
|
||||
.when(spyJpaTm)
|
||||
.delete(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
RuntimeException.class, () -> spyJpaTm.transact(() -> spyJpaTm.delete(theEntityKey)));
|
||||
verify(spyJpaTm, times(3)).delete(theEntityKey);
|
||||
@@ -201,7 +201,7 @@ class JpaTransactionManagerImplTest {
|
||||
void transactNewReadOnly_retriesJdbcConnectionExceptions() {
|
||||
JpaTransactionManager spyJpaTm = spy(jpaTm());
|
||||
doThrow(JDBCConnectionException.class).when(spyJpaTm).load(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
JDBCConnectionException.class,
|
||||
() -> spyJpaTm.transactNewReadOnly(() -> spyJpaTm.load(theEntityKey)));
|
||||
@@ -224,7 +224,7 @@ class JpaTransactionManagerImplTest {
|
||||
.initCause(new JDBCConnectionException("connection exception", new SQLException())))
|
||||
.when(spyJpaTm)
|
||||
.load(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
RuntimeException.class,
|
||||
() -> spyJpaTm.transactNewReadOnly(() -> spyJpaTm.load(theEntityKey)));
|
||||
@@ -243,7 +243,7 @@ class JpaTransactionManagerImplTest {
|
||||
void doTransactionless_retriesJdbcConnectionExceptions() {
|
||||
JpaTransactionManager spyJpaTm = spy(jpaTm());
|
||||
doThrow(JDBCConnectionException.class).when(spyJpaTm).load(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.saveNew(theEntity));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
assertThrows(
|
||||
RuntimeException.class,
|
||||
() -> spyJpaTm.doTransactionless(() -> spyJpaTm.load(theEntityKey)));
|
||||
@@ -251,19 +251,19 @@ class JpaTransactionManagerImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNew_throwsExceptionIfEntityExists() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isTrue();
|
||||
void insert_throwsExceptionIfEntityExists() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().load(theEntityKey))).isEqualTo(theEntity);
|
||||
assertThrows(RollbackException.class, () -> jpaTm().transact(() -> jpaTm().saveNew(theEntity)));
|
||||
assertThrows(RollbackException.class, () -> jpaTm().transact(() -> jpaTm().insert(theEntity)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createCompoundIdEntity_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(compoundIdEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(compoundIdEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(compoundIdEntity))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(compoundIdEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(compoundIdEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(compoundIdEntity))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().load(compoundIdEntityKey)))
|
||||
.isEqualTo(compoundIdEntity);
|
||||
}
|
||||
@@ -271,10 +271,10 @@ class JpaTransactionManagerImplTest {
|
||||
@Test
|
||||
void saveAllNew_succeeds() {
|
||||
moreEntities.forEach(
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().checkExists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().saveAllNew(moreEntities));
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().exists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().insertAll(moreEntities));
|
||||
moreEntities.forEach(
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().checkExists(entity))).isTrue());
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().exists(entity))).isTrue());
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAll(TestEntity.class)))
|
||||
.containsExactlyElementsIn(moreEntities);
|
||||
}
|
||||
@@ -282,48 +282,48 @@ class JpaTransactionManagerImplTest {
|
||||
@Test
|
||||
void saveAllNew_rollsBackWhenFailure() {
|
||||
moreEntities.forEach(
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().checkExists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().saveNew(moreEntities.get(0)));
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().exists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().insert(moreEntities.get(0)));
|
||||
assertThrows(
|
||||
RollbackException.class, () -> jpaTm().transact(() -> jpaTm().saveAllNew(moreEntities)));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(moreEntities.get(0)))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(moreEntities.get(1)))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(moreEntities.get(2)))).isFalse();
|
||||
RollbackException.class, () -> jpaTm().transact(() -> jpaTm().insertAll(moreEntities)));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(moreEntities.get(0)))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(moreEntities.get(1)))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(moreEntities.get(2)))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNewOrUpdate_persistsNewEntity() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNewOrUpdate(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isTrue();
|
||||
void put_persistsNewEntity() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().put(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().load(theEntityKey))).isEqualTo(theEntity);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNewOrUpdate_updatesExistingEntity() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
void put_updatesExistingEntity() {
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
TestEntity persisted = jpaTm().transact(() -> jpaTm().load(theEntityKey));
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
theEntity.data = "bar";
|
||||
jpaTm().transact(() -> jpaTm().saveNewOrUpdate(theEntity));
|
||||
jpaTm().transact(() -> jpaTm().put(theEntity));
|
||||
persisted = jpaTm().transact(() -> jpaTm().load(theEntityKey));
|
||||
assertThat(persisted.data).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNewOrUpdateAll_succeeds() {
|
||||
void putAll_succeeds() {
|
||||
moreEntities.forEach(
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().checkExists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().saveNewOrUpdateAll(moreEntities));
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().exists(entity))).isFalse());
|
||||
jpaTm().transact(() -> jpaTm().putAll(moreEntities));
|
||||
moreEntities.forEach(
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().checkExists(entity))).isTrue());
|
||||
entity -> assertThat(jpaTm().transact(() -> jpaTm().exists(entity))).isTrue());
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAll(TestEntity.class)))
|
||||
.containsExactlyElementsIn(moreEntities);
|
||||
}
|
||||
|
||||
@Test
|
||||
void update_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
TestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(TestEntity.class, "theEntity")));
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
@@ -335,7 +335,7 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void updateCompoundIdEntity_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(compoundIdEntity));
|
||||
jpaTm().transact(() -> jpaTm().insert(compoundIdEntity));
|
||||
TestCompoundIdEntity persisted = jpaTm().transact(() -> jpaTm().load(compoundIdEntityKey));
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
compoundIdEntity.data = "bar";
|
||||
@@ -346,15 +346,15 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void update_throwsExceptionWhenEntityDoesNotExist() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> jpaTm().transact(() -> jpaTm().update(theEntity)));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateAll_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveAllNew(moreEntities));
|
||||
jpaTm().transact(() -> jpaTm().insertAll(moreEntities));
|
||||
ImmutableList<TestEntity> updated =
|
||||
ImmutableList.of(
|
||||
new TestEntity("entity1", "foo_updated"),
|
||||
@@ -367,7 +367,7 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void updateAll_rollsBackWhenFailure() {
|
||||
jpaTm().transact(() -> jpaTm().saveAllNew(moreEntities));
|
||||
jpaTm().transact(() -> jpaTm().insertAll(moreEntities));
|
||||
ImmutableList<TestEntity> updated =
|
||||
ImmutableList.of(
|
||||
new TestEntity("entity1", "foo_updated"),
|
||||
@@ -382,8 +382,8 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void load_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
TestEntity persisted = jpaTm().transact(() -> jpaTm().load(theEntityKey));
|
||||
assertThat(persisted.name).isEqualTo("theEntity");
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
@@ -391,15 +391,15 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void load_throwsOnMissingElement() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
assertThrows(
|
||||
NoSuchElementException.class, () -> jpaTm().transact(() -> jpaTm().load(theEntityKey)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void maybeLoad_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
TestEntity persisted = jpaTm().transact(() -> jpaTm().maybeLoad(theEntityKey).get());
|
||||
assertThat(persisted.name).isEqualTo("theEntity");
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
@@ -407,14 +407,14 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void maybeLoad_nonExistentObject() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().maybeLoad(theEntityKey)).isPresent()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadCompoundIdEntity_succeeds() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(compoundIdEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(compoundIdEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(compoundIdEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(compoundIdEntity));
|
||||
TestCompoundIdEntity persisted = jpaTm().transact(() -> jpaTm().load(compoundIdEntityKey));
|
||||
assertThat(persisted.name).isEqualTo("compoundIdEntity");
|
||||
assertThat(persisted.age).isEqualTo(10);
|
||||
@@ -423,37 +423,37 @@ class JpaTransactionManagerImplTest {
|
||||
|
||||
@Test
|
||||
void loadAll_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveAllNew(moreEntities));
|
||||
jpaTm().transact(() -> jpaTm().insertAll(moreEntities));
|
||||
ImmutableList<TestEntity> persisted = jpaTm().transact(() -> jpaTm().loadAll(TestEntity.class));
|
||||
assertThat(persisted).containsExactlyElementsIn(moreEntities);
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isTrue();
|
||||
jpaTm().transact(() -> jpaTm().insert(theEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isTrue();
|
||||
jpaTm().transact(() -> jpaTm().delete(theEntityKey));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_returnsZeroWhenNoEntity() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().delete(theEntityKey));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteCompoundIdEntity_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(compoundIdEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(compoundIdEntity))).isTrue();
|
||||
jpaTm().transact(() -> jpaTm().insert(compoundIdEntity));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(compoundIdEntity))).isTrue();
|
||||
jpaTm().transact(() -> jpaTm().delete(compoundIdEntityKey));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(compoundIdEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(compoundIdEntity))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertDelete_throwsExceptionWhenEntityNotDeleted() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(theEntity))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(theEntity))).isFalse();
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> jpaTm().transact(() -> jpaTm().assertDelete(theEntityKey)));
|
||||
|
||||
+22
-22
@@ -107,7 +107,7 @@ public class TransactionManagerTest {
|
||||
() ->
|
||||
tm().transact(
|
||||
() -> {
|
||||
tm().saveNew(theEntity);
|
||||
tm().insert(theEntity);
|
||||
throw new RuntimeException();
|
||||
}));
|
||||
assertEntityNotExist(theEntity);
|
||||
@@ -116,21 +116,21 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void transact_reusesExistingTransaction() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().transact(() -> tm().saveNew(theEntity)));
|
||||
tm().transact(() -> tm().transact(() -> tm().insert(theEntity)));
|
||||
assertEntityExists(theEntity);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void transactNew_succeeds() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transactNew(() -> tm().saveNew(theEntity));
|
||||
tm().transactNew(() -> tm().insert(theEntity));
|
||||
assertEntityExists(theEntity);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void transactNewReadOnly_succeeds() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
assertEntityExists(theEntity);
|
||||
TestEntity persisted = tm().transactNewReadOnly(() -> tm().load(theEntity.key()));
|
||||
assertThat(persisted).isEqualTo(theEntity);
|
||||
@@ -140,14 +140,14 @@ public class TransactionManagerTest {
|
||||
void transactNewReadOnly_throwsWhenWritingEntity() {
|
||||
assertEntityNotExist(theEntity);
|
||||
assertThrows(
|
||||
RuntimeException.class, () -> tm().transactNewReadOnly(() -> tm().saveNew(theEntity)));
|
||||
RuntimeException.class, () -> tm().transactNewReadOnly(() -> tm().insert(theEntity)));
|
||||
assertEntityNotExist(theEntity);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void saveNew_succeeds() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
assertEntityExists(theEntity);
|
||||
assertThat(tm().transact(() -> tm().load(theEntity.key()))).isEqualTo(theEntity);
|
||||
}
|
||||
@@ -155,26 +155,26 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void saveAllNew_succeeds() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
assertAllEntitiesExist(moreEntities);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void saveNewOrUpdate_persistsNewEntity() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().saveNewOrUpdate(theEntity));
|
||||
tm().transact(() -> tm().put(theEntity));
|
||||
assertEntityExists(theEntity);
|
||||
assertThat(tm().transact(() -> tm().load(theEntity.key()))).isEqualTo(theEntity);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void saveNewOrUpdate_updatesExistingEntity() {
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
TestEntity persisted = tm().transact(() -> tm().load(theEntity.key()));
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
theEntity.data = "bar";
|
||||
fakeClock.advanceOneMilli();
|
||||
tm().transact(() -> tm().saveNewOrUpdate(theEntity));
|
||||
tm().transact(() -> tm().put(theEntity));
|
||||
persisted = tm().transact(() -> tm().load(theEntity.key()));
|
||||
assertThat(persisted.data).isEqualTo("bar");
|
||||
}
|
||||
@@ -182,13 +182,13 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void saveNewOrUpdateAll_succeeds() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveNewOrUpdateAll(moreEntities));
|
||||
tm().transact(() -> tm().putAll(moreEntities));
|
||||
assertAllEntitiesExist(moreEntities);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void update_succeeds() {
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
TestEntity persisted =
|
||||
tm().transact(
|
||||
() ->
|
||||
@@ -205,7 +205,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void load_succeeds() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
TestEntity persisted = tm().transact(() -> tm().load(theEntity.key()));
|
||||
assertThat(persisted.name).isEqualTo("theEntity");
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
@@ -221,7 +221,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void maybeLoad_succeeds() {
|
||||
assertEntityNotExist(theEntity);
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
TestEntity persisted = tm().transact(() -> tm().maybeLoad(theEntity.key()).get());
|
||||
assertThat(persisted.name).isEqualTo("theEntity");
|
||||
assertThat(persisted.data).isEqualTo("foo");
|
||||
@@ -235,7 +235,7 @@ public class TransactionManagerTest {
|
||||
|
||||
@TestTemplate
|
||||
void delete_succeeds() {
|
||||
tm().transact(() -> tm().saveNew(theEntity));
|
||||
tm().transact(() -> tm().insert(theEntity));
|
||||
assertEntityExists(theEntity);
|
||||
fakeClock.advanceOneMilli();
|
||||
tm().transact(() -> tm().delete(theEntity.key()));
|
||||
@@ -252,7 +252,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void delete_succeedsForEntitySet() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
Set<VKey<TestEntity>> keys =
|
||||
moreEntities.stream().map(TestEntity::key).collect(toImmutableSet());
|
||||
assertAllEntitiesExist(moreEntities);
|
||||
@@ -264,7 +264,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void delete_ignoreNonExistentEntity() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
List<VKey<TestEntity>> keys =
|
||||
moreEntities.stream().map(TestEntity::key).collect(toImmutableList());
|
||||
assertAllEntitiesExist(moreEntities);
|
||||
@@ -279,7 +279,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void load_multi() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
List<VKey<TestEntity>> keys =
|
||||
moreEntities.stream().map(TestEntity::key).collect(toImmutableList());
|
||||
assertThat(tm().transact(() -> tm().load(keys)))
|
||||
@@ -289,7 +289,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void load_multiWithDuplicateKeys() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
ImmutableList<VKey<TestEntity>> keys =
|
||||
moreEntities.stream().map(TestEntity::key).collect(toImmutableList());
|
||||
ImmutableList<VKey<TestEntity>> doubleKeys =
|
||||
@@ -301,7 +301,7 @@ public class TransactionManagerTest {
|
||||
@TestTemplate
|
||||
void load_multiMissingKeys() {
|
||||
assertAllEntitiesNotExist(moreEntities);
|
||||
tm().transact(() -> tm().saveAllNew(moreEntities));
|
||||
tm().transact(() -> tm().insertAll(moreEntities));
|
||||
List<VKey<TestEntity>> keys =
|
||||
Stream.concat(moreEntities.stream(), Stream.of(new TestEntity("dark", "matter")))
|
||||
.map(TestEntity::key)
|
||||
@@ -311,11 +311,11 @@ public class TransactionManagerTest {
|
||||
}
|
||||
|
||||
private static void assertEntityExists(TestEntity entity) {
|
||||
assertThat(tm().transact(() -> tm().checkExists(entity))).isTrue();
|
||||
assertThat(tm().transact(() -> tm().exists(entity))).isTrue();
|
||||
}
|
||||
|
||||
private static void assertEntityNotExist(TestEntity entity) {
|
||||
assertThat(tm().transact(() -> tm().checkExists(entity))).isFalse();
|
||||
assertThat(tm().transact(() -> tm().exists(entity))).isFalse();
|
||||
}
|
||||
|
||||
private static void assertAllEntitiesExist(ImmutableList<TestEntity> entities) {
|
||||
|
||||
@@ -66,7 +66,7 @@ class TransactionTest {
|
||||
|
||||
txn = new Transaction.Builder().addDelete(barEntity.key()).build();
|
||||
txn.writeToDatastore();
|
||||
assertThat(ofyTm().checkExists(barEntity.key())).isEqualTo(false);
|
||||
assertThat(ofyTm().exists(barEntity.key())).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,7 +83,7 @@ class TransactionTest {
|
||||
.transact(
|
||||
() -> {
|
||||
assertThat(ofyTm().load(fooEntity.key())).isEqualTo(fooEntity);
|
||||
assertThat(ofyTm().checkExists(barEntity.key())).isEqualTo(false);
|
||||
assertThat(ofyTm().exists(barEntity.key())).isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,8 +107,8 @@ class TransactionTest {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(fooEntity);
|
||||
jpaTm().saveNew(barEntity);
|
||||
jpaTm().insert(fooEntity);
|
||||
jpaTm().insert(barEntity);
|
||||
});
|
||||
TransactionEntity txnEnt =
|
||||
jpaTm().transact(() -> jpaTm().load(VKey.createSql(TransactionEntity.class, 1L)));
|
||||
@@ -123,8 +123,7 @@ class TransactionTest {
|
||||
|
||||
// Verify that no transaction was persisted for the load transaction.
|
||||
assertThat(
|
||||
jpaTm()
|
||||
.transact(() -> jpaTm().checkExists(VKey.createSql(TransactionEntity.class, 2L))))
|
||||
jpaTm().transact(() -> jpaTm().exists(VKey.createSql(TransactionEntity.class, 2L))))
|
||||
.isFalse();
|
||||
} finally {
|
||||
RegistryConfig.overrideCloudSqlReplicateTransactions(false);
|
||||
@@ -136,12 +135,10 @@ class TransactionTest {
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
jpaTm().saveNew(fooEntity);
|
||||
jpaTm().saveNew(barEntity);
|
||||
jpaTm().insert(fooEntity);
|
||||
jpaTm().insert(barEntity);
|
||||
});
|
||||
assertThat(
|
||||
jpaTm()
|
||||
.transact(() -> jpaTm().checkExists(VKey.createSql(TransactionEntity.class, 1L))))
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(VKey.createSql(TransactionEntity.class, 1L))))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class RdeStagingMapperTest {
|
||||
// Set Registrar states which are required for reporting.
|
||||
tm().transact(
|
||||
() ->
|
||||
tm().saveNewOrUpdateAll(
|
||||
tm().putAll(
|
||||
ImmutableList.of(
|
||||
externalMonitoringRegistrar.asBuilder().setState(State.ACTIVE).build(),
|
||||
testRegistrar.asBuilder().setState(State.ACTIVE).build(),
|
||||
|
||||
@@ -65,7 +65,7 @@ class RegistrarContactTest {
|
||||
|
||||
@Test
|
||||
void testPersistence_succeeds() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testRegistrarPoc));
|
||||
jpaTm().transact(() -> jpaTm().insert(testRegistrarPoc));
|
||||
RegistrarContact persisted =
|
||||
jpaTm().transact(() -> jpaTm().load(testRegistrarPoc.createVKey()));
|
||||
assertThat(persisted).isEqualTo(testRegistrarPoc);
|
||||
|
||||
@@ -70,14 +70,14 @@ public class RegistrarDaoTest {
|
||||
|
||||
@Test
|
||||
void saveNew_worksSuccessfully() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(testRegistrar))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testRegistrar));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(testRegistrar))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(testRegistrar))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(testRegistrar));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(testRegistrar))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void update_worksSuccessfully() {
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testRegistrar));
|
||||
jpaTm().transact(() -> jpaTm().insert(testRegistrar));
|
||||
Registrar persisted = jpaTm().transact(() -> jpaTm().load(registrarKey));
|
||||
assertThat(persisted.getRegistrarName()).isEqualTo("registrarName");
|
||||
jpaTm()
|
||||
@@ -92,7 +92,7 @@ public class RegistrarDaoTest {
|
||||
|
||||
@Test
|
||||
void update_throwsExceptionWhenEntityDoesNotExist() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(testRegistrar))).isFalse();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(testRegistrar))).isFalse();
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> jpaTm().transact(() -> jpaTm().update(testRegistrar)));
|
||||
@@ -100,8 +100,8 @@ public class RegistrarDaoTest {
|
||||
|
||||
@Test
|
||||
void load_worksSuccessfully() {
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(testRegistrar))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(testRegistrar));
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(testRegistrar))).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().insert(testRegistrar));
|
||||
Registrar persisted = jpaTm().transact(() -> jpaTm().load(registrarKey));
|
||||
|
||||
assertThat(persisted.getClientId()).isEqualTo("registrarId");
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SqlHelper {
|
||||
|
||||
public static Registrar saveRegistrar(String clientId) {
|
||||
Registrar registrar = makeRegistrar1().asBuilder().setClientId(clientId).build();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(registrar));
|
||||
jpaTm().transact(() -> jpaTm().insert(registrar));
|
||||
return jpaTm().transact(() -> jpaTm().load(registrar.createVKey()));
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
|
||||
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
|
||||
assertThat(registrar).isPresent();
|
||||
assertThat(registrar.get().verifyPassword("some_password")).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().checkExists(registrar.get()))).isTrue();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().exists(registrar.get()))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -47,7 +47,7 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
|
||||
@Test
|
||||
void testSuccess_alsoUpdateInCloudSql() throws Exception {
|
||||
assertThat(loadRegistrar("NewRegistrar").verifyPassword("some_password")).isFalse();
|
||||
jpaTm().transact(() -> jpaTm().saveNew(loadRegistrar("NewRegistrar")));
|
||||
jpaTm().transact(() -> jpaTm().insert(loadRegistrar("NewRegistrar")));
|
||||
runCommand("--password=some_password", "--force", "NewRegistrar");
|
||||
assertThat(loadRegistrar("NewRegistrar").verifyPassword("some_password")).isTrue();
|
||||
assertThat(
|
||||
|
||||
@@ -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
|
||||
|
||||
+57
-1
@@ -59,8 +59,11 @@ ext {
|
||||
getJdbcAccessInfo = {
|
||||
if (allDbEnv.contains(dbServer)) {
|
||||
return getSocketFactoryAccessInfo(dbServer)
|
||||
} else {
|
||||
} else if (!dbServer.isEmpty()) {
|
||||
return getAccessInfoByHostPort(dbServer)
|
||||
} else {
|
||||
// Not connecting to a database. Return a dummy object for Flyway config.
|
||||
return [ url: '', user: '', password: '' ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +113,7 @@ task compileApiJar(type: Jar) {
|
||||
configurations {
|
||||
compileApi
|
||||
schema
|
||||
integration
|
||||
}
|
||||
|
||||
artifacts {
|
||||
@@ -166,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')
|
||||
|
||||
@@ -187,3 +213,33 @@ if (ext.isRestricted()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project.baseSchemaTag != '') {
|
||||
repositories {
|
||||
maven {
|
||||
url project.publish_repo
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
integration "google.registry:schema:${project.baseSchemaTag}"
|
||||
}
|
||||
|
||||
// Checks if Flyway scripts can be deployed to an existing database with
|
||||
// an older release. Please refer to SchemaTest.java for more information.
|
||||
task schemaIncrementalDeployTest(dependsOn: processResources, type: Test) {
|
||||
useJUnitPlatform()
|
||||
include 'google/registry/sql/flyway/SchemaTest.*'
|
||||
classpath = configurations.testRuntimeClasspath
|
||||
.plus(configurations.integration)
|
||||
.plus(files(sourceSets.test.output.classesDirs))
|
||||
.plus(files(sourceSets.test.output.resourcesDir))
|
||||
.plus(files(sourceSets.main.output.classesDirs))
|
||||
|
||||
// Declare test-runtime dependency on Flyway scripts in the resources dir.
|
||||
// They are not on classpath since they conflict with the base schema.
|
||||
inputs.dir sourceSets.main.output.resourcesDir
|
||||
|
||||
// Specifies which test to run using the following property
|
||||
systemProperty 'deploy_to_existing_db', 'true'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
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
|
||||
@@ -0,0 +1,21 @@
|
||||
-- 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 "HostResource" RENAME TO "Host";
|
||||
|
||||
ALTER TABLE "HostHistory" RENAME CONSTRAINT fk_hosthistory_hostresource TO fk_hosthistory_host;
|
||||
ALTER TABLE "Host"
|
||||
RENAME CONSTRAINT fk_host_resource_superordinate_domain TO fk_host_superordinate_domain;
|
||||
ALTER TABLE "Host" RENAME CONSTRAINT "HostResource_pkey" TO "Host_pkey";
|
||||
@@ -0,0 +1,31 @@
|
||||
-- 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.
|
||||
|
||||
-- Note: we drop the not-null constraints from the history tables but we keep them in the
|
||||
-- EPP resource tables since nothing inserted there should be null
|
||||
|
||||
ALTER TABLE "ContactHistory" ALTER COLUMN creation_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "ContactHistory" ALTER COLUMN creation_time DROP NOT NULL;
|
||||
ALTER TABLE "ContactHistory" ALTER COLUMN current_sponsor_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "ContactHistory" ALTER COLUMN history_reason DROP NOT NULL;
|
||||
|
||||
ALTER TABLE "DomainHistory" ALTER COLUMN creation_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "DomainHistory" ALTER COLUMN creation_time DROP NOT NULL;
|
||||
ALTER TABLE "DomainHistory" ALTER COLUMN current_sponsor_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "DomainHistory" ALTER COLUMN history_reason DROP NOT NULL;
|
||||
|
||||
ALTER TABLE "HostHistory" ALTER COLUMN creation_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "HostHistory" ALTER COLUMN creation_time DROP NOT NULL;
|
||||
ALTER TABLE "HostHistory" ALTER COLUMN current_sponsor_registrar_id DROP NOT NULL;
|
||||
ALTER TABLE "HostHistory" ALTER COLUMN history_reason DROP NOT NULL;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
-- 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 "BillingCancellation" alter column billing_cancellation_id drop default;
|
||||
alter table "BillingEvent" alter column billing_event_id drop default;
|
||||
alter table "BillingRecurrence" alter column billing_recurrence_id drop default;
|
||||
|
||||
drop sequence "BillingCancellation_billing_cancellation_id_seq";
|
||||
drop sequence "BillingEvent_billing_event_id_seq";
|
||||
drop sequence "BillingRecurrence_billing_recurrence_id_seq";
|
||||
+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);
|
||||
@@ -30,7 +30,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
);
|
||||
|
||||
create table "BillingCancellation" (
|
||||
billing_cancellation_id bigserial not null,
|
||||
billing_cancellation_id int8 not null,
|
||||
registrar_id text not null,
|
||||
domain_history_revision_id int8 not null,
|
||||
domain_repo_id text not null,
|
||||
@@ -45,7 +45,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
);
|
||||
|
||||
create table "BillingEvent" (
|
||||
billing_event_id bigserial not null,
|
||||
billing_event_id int8 not null,
|
||||
registrar_id text not null,
|
||||
domain_history_revision_id int8 not null,
|
||||
domain_repo_id text not null,
|
||||
@@ -64,7 +64,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
);
|
||||
|
||||
create table "BillingRecurrence" (
|
||||
billing_recurrence_id bigserial not null,
|
||||
billing_recurrence_id int8 not null,
|
||||
registrar_id text not null,
|
||||
domain_history_revision_id int8 not null,
|
||||
domain_repo_id text not null,
|
||||
@@ -94,9 +94,9 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
create table "Contact" (
|
||||
repo_id text not null,
|
||||
update_timestamp timestamptz,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
@@ -151,11 +151,12 @@ 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,
|
||||
history_reason text not null,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean not null,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
@@ -207,16 +208,15 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
transfer_status text,
|
||||
voice_phone_extension text,
|
||||
voice_phone_number text,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
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" (
|
||||
@@ -238,9 +238,9 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
create table "Domain" (
|
||||
repo_id text not null,
|
||||
update_timestamp timestamptz,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
@@ -291,7 +291,7 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
history_by_superuser boolean not null,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamptz not null,
|
||||
history_reason text not null,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean not null,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
@@ -334,9 +334,9 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
transfer_pending_expiration_time timestamptz,
|
||||
transfer_request_time timestamptz,
|
||||
transfer_status text,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
@@ -381,40 +381,12 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
create table "HostHistory" (
|
||||
history_revision_id int8 not null,
|
||||
history_by_superuser boolean not null,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamptz not null,
|
||||
history_reason text not null,
|
||||
history_requested_by_registrar boolean not null,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
history_type text not null,
|
||||
history_xml_bytes bytea not null,
|
||||
host_name text,
|
||||
inet_addresses text[],
|
||||
last_superordinate_change timestamptz,
|
||||
last_transfer_time timestamptz,
|
||||
superordinate_domain text,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
statuses text[],
|
||||
update_timestamp timestamptz,
|
||||
host_repo_id text not null,
|
||||
primary key (history_revision_id)
|
||||
);
|
||||
|
||||
create table "HostResource" (
|
||||
create table "Host" (
|
||||
repo_id text not null,
|
||||
update_timestamp timestamptz,
|
||||
creation_registrar_id text not null,
|
||||
creation_time timestamptz not null,
|
||||
current_sponsor_registrar_id text not null,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
@@ -427,6 +399,34 @@ create sequence temp_history_id_sequence start 1 increment 50;
|
||||
primary key (repo_id)
|
||||
);
|
||||
|
||||
create table "HostHistory" (
|
||||
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,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean not null,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
history_type text not null,
|
||||
history_xml_bytes bytea not null,
|
||||
host_name text,
|
||||
inet_addresses text[],
|
||||
last_superordinate_change timestamptz,
|
||||
last_transfer_time timestamptz,
|
||||
superordinate_domain text,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamptz,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamptz,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamptz,
|
||||
statuses text[],
|
||||
update_timestamp timestamptz,
|
||||
primary key (host_repo_id, history_revision_id)
|
||||
);
|
||||
|
||||
create table "Lock" (
|
||||
resource_name text not null,
|
||||
tld text not null,
|
||||
|
||||
@@ -73,25 +73,6 @@ CREATE TABLE public."BillingCancellation" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingCancellation_billing_cancellation_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."BillingCancellation_billing_cancellation_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingCancellation_billing_cancellation_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."BillingCancellation_billing_cancellation_id_seq" OWNED BY public."BillingCancellation".billing_cancellation_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingEvent; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -115,25 +96,6 @@ CREATE TABLE public."BillingEvent" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingEvent_billing_event_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."BillingEvent_billing_event_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingEvent_billing_event_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."BillingEvent_billing_event_id_seq" OWNED BY public."BillingEvent".billing_event_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingRecurrence; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -152,25 +114,6 @@ CREATE TABLE public."BillingRecurrence" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingRecurrence_billing_recurrence_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."BillingRecurrence_billing_recurrence_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingRecurrence_billing_recurrence_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."BillingRecurrence_billing_recurrence_id_seq" OWNED BY public."BillingRecurrence".billing_recurrence_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ClaimsEntry; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -284,7 +227,7 @@ CREATE TABLE public."ContactHistory" (
|
||||
history_by_superuser boolean NOT NULL,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamp with time zone NOT NULL,
|
||||
history_reason text NOT NULL,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean NOT NULL,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
@@ -336,9 +279,9 @@ CREATE TABLE public."ContactHistory" (
|
||||
transfer_status text,
|
||||
voice_phone_extension text,
|
||||
voice_phone_number text,
|
||||
creation_registrar_id text NOT NULL,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
current_sponsor_registrar_id text NOT NULL,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp with time zone,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamp with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp with time zone,
|
||||
@@ -423,7 +366,7 @@ CREATE TABLE public."DomainHistory" (
|
||||
history_by_superuser boolean NOT NULL,
|
||||
history_registrar_id text,
|
||||
history_modification_time timestamp with time zone NOT NULL,
|
||||
history_reason text NOT NULL,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean NOT NULL,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
@@ -465,9 +408,9 @@ CREATE TABLE public."DomainHistory" (
|
||||
transfer_pending_expiration_time timestamp with time zone,
|
||||
transfer_request_time timestamp with time zone,
|
||||
transfer_status text,
|
||||
creation_registrar_id text NOT NULL,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
current_sponsor_registrar_id text NOT NULL,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp with time zone,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamp with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp with time zone,
|
||||
@@ -571,42 +514,10 @@ ALTER SEQUENCE public."GracePeriod_id_seq" OWNED BY public."GracePeriod".id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostHistory; Type: TABLE; Schema: public; Owner: -
|
||||
-- Name: Host; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."HostHistory" (
|
||||
history_revision_id bigint NOT NULL,
|
||||
history_by_superuser boolean NOT NULL,
|
||||
history_registrar_id text NOT NULL,
|
||||
history_modification_time timestamp with time zone NOT NULL,
|
||||
history_reason text NOT NULL,
|
||||
history_requested_by_registrar boolean NOT NULL,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
history_type text NOT NULL,
|
||||
history_xml_bytes bytea NOT NULL,
|
||||
host_name text,
|
||||
inet_addresses text[],
|
||||
last_superordinate_change timestamp with time zone,
|
||||
last_transfer_time timestamp with time zone,
|
||||
superordinate_domain text,
|
||||
creation_registrar_id text NOT NULL,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
current_sponsor_registrar_id text NOT NULL,
|
||||
deletion_time timestamp with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp with time zone,
|
||||
statuses text[],
|
||||
host_repo_id text NOT NULL,
|
||||
update_timestamp timestamp with time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostResource; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."HostResource" (
|
||||
CREATE TABLE public."Host" (
|
||||
repo_id text NOT NULL,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp with time zone,
|
||||
@@ -624,6 +535,38 @@ CREATE TABLE public."HostResource" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostHistory; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."HostHistory" (
|
||||
history_revision_id bigint NOT NULL,
|
||||
history_by_superuser boolean NOT NULL,
|
||||
history_registrar_id text NOT NULL,
|
||||
history_modification_time timestamp with time zone NOT NULL,
|
||||
history_reason text,
|
||||
history_requested_by_registrar boolean NOT NULL,
|
||||
history_client_transaction_id text,
|
||||
history_server_transaction_id text,
|
||||
history_type text NOT NULL,
|
||||
history_xml_bytes bytea NOT NULL,
|
||||
host_name text,
|
||||
inet_addresses text[],
|
||||
last_superordinate_change timestamp with time zone,
|
||||
last_transfer_time timestamp with time zone,
|
||||
superordinate_domain text,
|
||||
creation_registrar_id text,
|
||||
creation_time timestamp with time zone,
|
||||
current_sponsor_registrar_id text,
|
||||
deletion_time timestamp with time zone,
|
||||
last_epp_update_registrar_id text,
|
||||
last_epp_update_time timestamp with time zone,
|
||||
statuses text[],
|
||||
host_repo_id text NOT NULL,
|
||||
update_timestamp timestamp with time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: Lock; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1025,27 +968,6 @@ CREATE SEQUENCE public.temp_history_id_sequence
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingCancellation billing_cancellation_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BillingCancellation" ALTER COLUMN billing_cancellation_id SET DEFAULT nextval('public."BillingCancellation_billing_cancellation_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingEvent billing_event_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BillingEvent" ALTER COLUMN billing_event_id SET DEFAULT nextval('public."BillingEvent_billing_event_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BillingRecurrence billing_recurrence_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BillingRecurrence" ALTER COLUMN billing_recurrence_id SET DEFAULT nextval('public."BillingRecurrence_billing_recurrence_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ClaimsList revision_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1162,7 +1084,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);
|
||||
|
||||
|
||||
--
|
||||
@@ -1218,15 +1140,15 @@ 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);
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostResource HostResource_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: Host Host_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."HostResource"
|
||||
ADD CONSTRAINT "HostResource_pkey" PRIMARY KEY (repo_id);
|
||||
ALTER TABLE ONLY public."Host"
|
||||
ADD CONSTRAINT "Host_pkey" PRIMARY KEY (repo_id);
|
||||
|
||||
|
||||
--
|
||||
@@ -1944,7 +1866,7 @@ ALTER TABLE ONLY public."Domain"
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."DomainHost"
|
||||
ADD CONSTRAINT fk_domainhost_host_valid FOREIGN KEY (host_repo_id) REFERENCES public."HostResource"(repo_id);
|
||||
ADD CONSTRAINT fk_domainhost_host_valid FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
@@ -1964,19 +1886,19 @@ ALTER TABLE ONLY public."GracePeriod"
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostResource fk_host_resource_superordinate_domain; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: Host fk_host_superordinate_domain; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."HostResource"
|
||||
ADD CONSTRAINT fk_host_resource_superordinate_domain FOREIGN KEY (superordinate_domain) REFERENCES public."Domain"(repo_id);
|
||||
ALTER TABLE ONLY public."Host"
|
||||
ADD CONSTRAINT fk_host_superordinate_domain FOREIGN KEY (superordinate_domain) REFERENCES public."Domain"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: HostHistory fk_hosthistory_hostresource; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: HostHistory fk_hosthistory_host; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."HostHistory"
|
||||
ADD CONSTRAINT fk_hosthistory_hostresource FOREIGN KEY (host_repo_id) REFERENCES public."HostResource"(repo_id);
|
||||
ADD CONSTRAINT fk_hosthistory_host FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
@@ -2000,7 +1922,7 @@ ALTER TABLE ONLY public."PollMessage"
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PollMessage"
|
||||
ADD CONSTRAINT fk_poll_message_host_repo_id FOREIGN KEY (host_repo_id) REFERENCES public."HostResource"(repo_id);
|
||||
ADD CONSTRAINT fk_poll_message_host_repo_id FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id);
|
||||
|
||||
|
||||
--
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.truth.TextDiffSubject.assertThat;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.io.Resources;
|
||||
import google.registry.persistence.NomulusPostgreSql;
|
||||
import java.io.File;
|
||||
@@ -26,16 +27,41 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
|
||||
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
|
||||
import org.testcontainers.containers.BindMode;
|
||||
import org.testcontainers.containers.Container.ExecResult;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
/** Unit tests about Cloud SQL schema. */
|
||||
/**
|
||||
* Schema deployment tests using Flyway.
|
||||
*
|
||||
* <p>This class has two test methods:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #deploySchema_emptyDb()} is invoked only in UNIT tests (:db:test in Gradle). It
|
||||
* deploys the entire set of Flyway scripts (found on classpath) to an empty database and
|
||||
* compares the resulting schema with the golden schema.
|
||||
* <li>{@link #deploySchema_existingDb()} is invoked only in an integration test
|
||||
* (:db:schemaIncrementalDeployTest in Gradle). It first populates the test database with an
|
||||
* earlier release of the schema (found on the classpath), then deploys the latest Flyway
|
||||
* scripts (found on local filesystem under the resources directory) to that database. This
|
||||
* test detects all forbidden changes to deployed scripts including content change, file
|
||||
* renaming, and file deletion.
|
||||
* <p>This test also checks for out-of-order version numbers, i.e., new scripts with lower
|
||||
* numbers than that of the last deployed script. Out-of-order versions are confusing to
|
||||
* maintainers, however, Flyway does not provide ways to check before schema deployment. In
|
||||
* this test, out-of-order scripts are ignored in the incremental-deployment phase (default
|
||||
* Flyway behavior). The final validate call will fail on them.
|
||||
* </ul>
|
||||
*/
|
||||
@Testcontainers
|
||||
class SchemaTest {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
// Resource path that is mapped to the testcontainer instance.
|
||||
private static final String MOUNTED_RESOURCE_PATH = "testcontainer/mount";
|
||||
// The mount point in the container.
|
||||
@@ -57,7 +83,8 @@ class SchemaTest {
|
||||
MOUNTED_RESOURCE_PATH, CONTAINER_MOUNT_POINT, BindMode.READ_WRITE);
|
||||
|
||||
@Test
|
||||
void deploySchema_success() throws Exception {
|
||||
@DisabledIfSystemProperty(named = "deploy_to_existing_db", matches = ".*")
|
||||
void deploySchema_emptyDb() throws Exception {
|
||||
Flyway flyway =
|
||||
Flyway.configure()
|
||||
.locations("sql/flyway")
|
||||
@@ -86,6 +113,32 @@ class SchemaTest {
|
||||
.hasSameContentAs(Resources.getResource("sql/schema/nomulus.golden.sql"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledIfSystemProperty(named = "deploy_to_existing_db", matches = ".*")
|
||||
void deploySchema_existingDb() {
|
||||
// Initialize database with the base schema, which is on the classpath.
|
||||
Flyway flyway =
|
||||
Flyway.configure()
|
||||
.locations("sql/flyway")
|
||||
.dataSource(
|
||||
sqlContainer.getJdbcUrl(), sqlContainer.getUsername(), sqlContainer.getPassword())
|
||||
.load();
|
||||
flyway.migrate();
|
||||
logger.atInfo().log("Base schema version: %s", flyway.info().current().getVersion().toString());
|
||||
|
||||
// Deploy latest scripts from resources directory.
|
||||
flyway =
|
||||
Flyway.configure()
|
||||
.locations("filesystem:build/resources/main/sql/flyway")
|
||||
.dataSource(
|
||||
sqlContainer.getJdbcUrl(), sqlContainer.getUsername(), sqlContainer.getPassword())
|
||||
.load();
|
||||
flyway.migrate();
|
||||
flyway.validate();
|
||||
logger.atInfo().log(
|
||||
"Latest schema version: %s", flyway.info().current().getVersion().toString());
|
||||
}
|
||||
|
||||
private static String[] getSchemaDumpCommand(String username, String dbName) {
|
||||
return new String[] {
|
||||
"pg_dump",
|
||||
|
||||
@@ -124,6 +124,7 @@ ext {
|
||||
'org.apache.ftpserver:ftpserver-core:1.0.6',
|
||||
'org.apache.httpcomponents:httpclient:4.5.11',
|
||||
'org.apache.httpcomponents:httpcore:4.4.13',
|
||||
'org.apache.logging.log4j:log4j-core:2.13.3',
|
||||
'org.apache.sshd:sshd-core:2.0.0',
|
||||
'org.apache.sshd:sshd-scp:2.0.0',
|
||||
'org.apache.sshd:sshd-sftp:2.0.0',
|
||||
|
||||
@@ -201,7 +201,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -199,7 +199,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -201,7 +201,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -201,7 +201,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -204,7 +204,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
|
||||
@@ -203,7 +203,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
|
||||
@@ -204,7 +204,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
|
||||
@@ -204,7 +204,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
|
||||
@@ -24,6 +24,7 @@ dbName=postgres
|
||||
dbUser=
|
||||
dbPassword=
|
||||
publish_repo=
|
||||
baseSchemaTag=
|
||||
schema_version=
|
||||
nomulus_version=
|
||||
dot_path=/usr/bin/dot
|
||||
|
||||
@@ -79,6 +79,8 @@ function runTest() {
|
||||
echo "Running test with -Pnomulus_version=${nomulus_version}" \
|
||||
"-Pschema_version=${schema_version}"
|
||||
|
||||
# The https scheme in the Maven repo URL below is required for Kokoro. See
|
||||
# ./run_schema_check.sh for more information.
|
||||
(cd ${SCRIPT_DIR}/..; \
|
||||
./gradlew :integration:sqlIntegrationTest \
|
||||
-PdevProject=${dev_project} \
|
||||
|
||||
@@ -25,12 +25,13 @@ $(basename "$0") OPTIONS
|
||||
Checks for post-deployment change to Flyway scripts.
|
||||
|
||||
With Flyway, once an incremental change script is deployed, it must not be
|
||||
changed. Even changes to comments or whitespaces would cause validation
|
||||
failures during future deployment. This script checks for changes (including
|
||||
removal and renaming which may happen due to incorrect merge conflict
|
||||
resolution) to scripts that have already been deployed to Sandbox. The
|
||||
assumption is that the schema in Sandbox is always newer than that in
|
||||
production.
|
||||
edited, renamed, or deleted. This script checks for changes to scripts that have
|
||||
already been deployed to Sandbox. The assumption is that the schema in Sandbox
|
||||
is always at least as recent as that in production. Please refer to Gradle task
|
||||
:db:schemaIncrementalDeployTest for more information.
|
||||
|
||||
Note that this test MAY fail to catch forbidden changes during the period when
|
||||
a new schema release is created but not yet deployed to Sandbox.
|
||||
|
||||
A side-effect of this check is that old branches missing recently deployed
|
||||
scripts must update first.
|
||||
@@ -65,16 +66,14 @@ fi
|
||||
|
||||
sandbox_tag=$(fetchVersion sql sandbox ${DEV_PROJECT})
|
||||
echo "Checking Flyway scripts against schema in Sandbox (${sandbox_tag})."
|
||||
modified_sqls=$(git diff --name-status ${sandbox_tag} \
|
||||
db/src/main/resources/sql/flyway | grep "^M\|^D\|^R" | grep \.sql$ | wc -l)
|
||||
|
||||
if [[ ${modified_sqls} = 0 ]]; then
|
||||
echo "No illegal change to deployed schema scripts."
|
||||
exit 0
|
||||
else
|
||||
echo "Changes to the following files are not allowed:"
|
||||
echo $(git diff --name-status ${sandbox_tag} \
|
||||
db/src/main/resources/sql/flyway | grep "^M\|^D\|^R" | grep \.sql$)
|
||||
echo "Make sure your branch is up to date with HEAD of master."
|
||||
exit 1
|
||||
fi
|
||||
# The URL of the Maven repo on GCS for the publish_repo parameter must use the
|
||||
# https scheme (https://storage.googleapis.com/{BUCKET}/{PATH}) in order to work
|
||||
# with Kokoro. Gradle's alternative gcs scheme does not work on Kokoro: a GCP
|
||||
# credential with proper scopes for GCS access is required even for public
|
||||
# buckets, however, Kokoro VM instances are not set up with such credentials.
|
||||
# Incidentally, gcs can be used on Cloud Build.
|
||||
(cd ${SCRIPT_DIR}/..; \
|
||||
./gradlew :db:schemaIncrementalDeployTest \
|
||||
-PbaseSchemaTag=${sandbox_tag} \
|
||||
-Ppublish_repo=https://storage.googleapis.com/${DEV_PROJECT}-deployed-tags/maven)
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
@@ -200,7 +200,8 @@ org.apache.commons:commons-compress:1.20
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.11
|
||||
org.apache.httpcomponents:httpcore:4.4.13
|
||||
org.apache.logging.log4j:log4j-api:2.6.2
|
||||
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:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-compat-qual:2.5.5
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user