mirror of
https://github.com/google/nomulus
synced 2026-06-09 16:33:02 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c23d4f3ba5 | |||
| 2b794347e6 | |||
| 26fb5388a4 | |||
| bd443633f6 | |||
| d87f119b36 | |||
| 54f1357d83 | |||
| c73d154084 |
@@ -197,6 +197,10 @@ task runPresubmits(type: Exec) {
|
||||
args('config/presubmits.py')
|
||||
}
|
||||
|
||||
def javadocSource = []
|
||||
def javadocClasspath = []
|
||||
def javadocDependentTasks = []
|
||||
|
||||
subprojects {
|
||||
// Skip no-op project
|
||||
if (project.name == 'services') return
|
||||
@@ -317,6 +321,10 @@ subprojects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javadocSource << project.sourceSets.main.allJava
|
||||
javadocClasspath << project.sourceSets.main.compileClasspath
|
||||
javadocDependentTasks << project.tasks.compileJava
|
||||
}
|
||||
|
||||
// If "-P verboseTestOutput=true" is passed in, configure all subprojects to dump all of their
|
||||
@@ -445,3 +453,18 @@ task javaIncrementalFormatApply {
|
||||
}
|
||||
|
||||
tasks.build.dependsOn(tasks.javaIncrementalFormatCheck)
|
||||
|
||||
task javadoc(type: Javadoc) {
|
||||
source javadocSource
|
||||
classpath = files(javadocClasspath)
|
||||
destinationDir = file("${buildDir}/docs/javadoc")
|
||||
// In a lot of places we don't write @return so suppress warnings about that.
|
||||
options.addBooleanOption('Xdoclint:all,-missing', true)
|
||||
options.addBooleanOption("-allow-script-in-comments",true)
|
||||
options.tags = ["type:a:Generic Type",
|
||||
"error:a:Expected Error"]
|
||||
}
|
||||
|
||||
tasks.build.dependsOn(tasks.javadoc)
|
||||
|
||||
javadocDependentTasks.each { tasks.javadoc.shouldRunAfter(it) }
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.joda.time.ReadableDuration;
|
||||
* An object which accepts requests to put the current thread to sleep.
|
||||
*
|
||||
* @see SystemSleeper
|
||||
* @see google.registry.testing.FakeSleeper
|
||||
*/
|
||||
@ThreadSafe
|
||||
public interface Sleeper {
|
||||
|
||||
@@ -150,7 +150,7 @@ public final class AsyncTaskEnqueuer {
|
||||
|
||||
/** Enqueues a task to asynchronously refresh DNS for a renamed host. */
|
||||
public void enqueueAsyncDnsRefresh(HostResource host, DateTime now) {
|
||||
VKey<HostResource> hostKey = host.createKey();
|
||||
VKey<HostResource> hostKey = host.createVKey();
|
||||
logger.atInfo().log("Enqueuing async DNS refresh for renamed host %s.", hostKey);
|
||||
addTaskToQueueWithRetry(
|
||||
asyncDnsRefreshPullQueue,
|
||||
|
||||
@@ -155,89 +155,100 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||
}
|
||||
int numBillingEventsSaved = 0;
|
||||
try {
|
||||
numBillingEventsSaved = tm().transactNew(() -> {
|
||||
ImmutableSet.Builder<OneTime> syntheticOneTimesBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
final Registry tld = Registry.get(getTldFromDomainName(recurring.getTargetId()));
|
||||
numBillingEventsSaved =
|
||||
tm().transactNew(
|
||||
() -> {
|
||||
ImmutableSet.Builder<OneTime> syntheticOneTimesBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
final Registry tld =
|
||||
Registry.get(getTldFromDomainName(recurring.getTargetId()));
|
||||
|
||||
// Determine the complete set of times at which this recurring event should occur
|
||||
// (up to and including the runtime of the mapreduce).
|
||||
Iterable<DateTime> eventTimes =
|
||||
recurring.getRecurrenceTimeOfYear().getInstancesInRange(Range.closed(
|
||||
recurring.getEventTime(),
|
||||
earliestOf(recurring.getRecurrenceEndTime(), executeTime)));
|
||||
// Determine the complete set of times at which this recurring event should
|
||||
// occur (up to and including the runtime of the mapreduce).
|
||||
Iterable<DateTime> eventTimes =
|
||||
recurring
|
||||
.getRecurrenceTimeOfYear()
|
||||
.getInstancesInRange(
|
||||
Range.closed(
|
||||
recurring.getEventTime(),
|
||||
earliestOf(recurring.getRecurrenceEndTime(), executeTime)));
|
||||
|
||||
// Convert these event times to billing times
|
||||
final ImmutableSet<DateTime> billingTimes =
|
||||
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
||||
// Convert these event times to billing times
|
||||
final ImmutableSet<DateTime> billingTimes =
|
||||
getBillingTimesInScope(eventTimes, cursorTime, executeTime, tld);
|
||||
|
||||
Key<? extends EppResource> domainKey = recurring.getParentKey().getParent();
|
||||
Iterable<OneTime> oneTimesForDomain =
|
||||
ofy().load().type(OneTime.class).ancestor(domainKey);
|
||||
Key<? extends EppResource> domainKey = recurring.getParentKey().getParent();
|
||||
Iterable<OneTime> oneTimesForDomain =
|
||||
ofy().load().type(OneTime.class).ancestor(domainKey);
|
||||
|
||||
// Determine the billing times that already have OneTime events persisted.
|
||||
ImmutableSet<DateTime> existingBillingTimes =
|
||||
getExistingBillingTimes(oneTimesForDomain, recurring);
|
||||
// Determine the billing times that already have OneTime events persisted.
|
||||
ImmutableSet<DateTime> existingBillingTimes =
|
||||
getExistingBillingTimes(oneTimesForDomain, recurring);
|
||||
|
||||
ImmutableSet.Builder<HistoryEntry> historyEntriesBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
// Create synthetic OneTime events for all billing times that do not yet have an event
|
||||
// persisted.
|
||||
for (DateTime billingTime : difference(billingTimes, existingBillingTimes)) {
|
||||
// Construct a new HistoryEntry that parents over the OneTime
|
||||
HistoryEntry historyEntry = new HistoryEntry.Builder()
|
||||
.setBySuperuser(false)
|
||||
.setClientId(recurring.getClientId())
|
||||
.setModificationTime(tm().getTransactionTime())
|
||||
.setParent(domainKey)
|
||||
.setPeriod(Period.create(1, YEARS))
|
||||
.setReason("Domain autorenewal by ExpandRecurringBillingEventsAction")
|
||||
.setRequestedByRegistrar(false)
|
||||
.setType(DOMAIN_AUTORENEW)
|
||||
// Don't write a domain transaction record if the recurrence was ended prior to the
|
||||
// billing time (i.e. a domain was deleted during the autorenew grace period).
|
||||
.setDomainTransactionRecords(
|
||||
recurring.getRecurrenceEndTime().isBefore(billingTime)
|
||||
? ImmutableSet.of()
|
||||
: ImmutableSet.of(
|
||||
DomainTransactionRecord.create(
|
||||
tld.getTldStr(),
|
||||
// We report this when the autorenew grace period ends
|
||||
billingTime,
|
||||
TransactionReportField.netRenewsFieldFromYears(1),
|
||||
1)))
|
||||
.build();
|
||||
historyEntriesBuilder.add(historyEntry);
|
||||
ImmutableSet.Builder<HistoryEntry> historyEntriesBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
// Create synthetic OneTime events for all billing times that do not yet have
|
||||
// an event persisted.
|
||||
for (DateTime billingTime : difference(billingTimes, existingBillingTimes)) {
|
||||
// Construct a new HistoryEntry that parents over the OneTime
|
||||
HistoryEntry historyEntry =
|
||||
new HistoryEntry.Builder()
|
||||
.setBySuperuser(false)
|
||||
.setClientId(recurring.getClientId())
|
||||
.setModificationTime(tm().getTransactionTime())
|
||||
.setParent(domainKey)
|
||||
.setPeriod(Period.create(1, YEARS))
|
||||
.setReason(
|
||||
"Domain autorenewal by ExpandRecurringBillingEventsAction")
|
||||
.setRequestedByRegistrar(false)
|
||||
.setType(DOMAIN_AUTORENEW)
|
||||
// Don't write a domain transaction record if the recurrence was
|
||||
// ended prior to the billing time (i.e. a domain was deleted
|
||||
// during the autorenew grace period).
|
||||
.setDomainTransactionRecords(
|
||||
recurring.getRecurrenceEndTime().isBefore(billingTime)
|
||||
? ImmutableSet.of()
|
||||
: ImmutableSet.of(
|
||||
DomainTransactionRecord.create(
|
||||
tld.getTldStr(),
|
||||
// We report this when the autorenew grace period
|
||||
// ends
|
||||
billingTime,
|
||||
TransactionReportField.netRenewsFieldFromYears(1),
|
||||
1)))
|
||||
.build();
|
||||
historyEntriesBuilder.add(historyEntry);
|
||||
|
||||
DateTime eventTime = billingTime.minus(tld.getAutoRenewGracePeriodLength());
|
||||
// Determine the cost for a one-year renewal.
|
||||
Money renewCost = getDomainRenewCost(recurring.getTargetId(), eventTime, 1);
|
||||
syntheticOneTimesBuilder.add(new OneTime.Builder()
|
||||
.setBillingTime(billingTime)
|
||||
.setClientId(recurring.getClientId())
|
||||
.setCost(renewCost)
|
||||
.setEventTime(eventTime)
|
||||
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
||||
.setParent(historyEntry)
|
||||
.setPeriodYears(1)
|
||||
.setReason(recurring.getReason())
|
||||
.setSyntheticCreationTime(executeTime)
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.setTargetId(recurring.getTargetId())
|
||||
.build());
|
||||
}
|
||||
Set<HistoryEntry> historyEntries = historyEntriesBuilder.build();
|
||||
Set<OneTime> syntheticOneTimes = syntheticOneTimesBuilder.build();
|
||||
if (!isDryRun) {
|
||||
ImmutableSet<ImmutableObject> entitiesToSave =
|
||||
new ImmutableSet.Builder<ImmutableObject>()
|
||||
.addAll(historyEntries)
|
||||
.addAll(syntheticOneTimes)
|
||||
.build();
|
||||
ofy().save().entities(entitiesToSave).now();
|
||||
}
|
||||
return syntheticOneTimes.size();
|
||||
});
|
||||
DateTime eventTime = billingTime.minus(tld.getAutoRenewGracePeriodLength());
|
||||
// Determine the cost for a one-year renewal.
|
||||
Money renewCost = getDomainRenewCost(recurring.getTargetId(), eventTime, 1);
|
||||
syntheticOneTimesBuilder.add(
|
||||
new OneTime.Builder()
|
||||
.setBillingTime(billingTime)
|
||||
.setClientId(recurring.getClientId())
|
||||
.setCost(renewCost)
|
||||
.setEventTime(eventTime)
|
||||
.setFlags(union(recurring.getFlags(), Flag.SYNTHETIC))
|
||||
.setParent(historyEntry)
|
||||
.setPeriodYears(1)
|
||||
.setReason(recurring.getReason())
|
||||
.setSyntheticCreationTime(executeTime)
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setTargetId(recurring.getTargetId())
|
||||
.build());
|
||||
}
|
||||
Set<HistoryEntry> historyEntries = historyEntriesBuilder.build();
|
||||
Set<OneTime> syntheticOneTimes = syntheticOneTimesBuilder.build();
|
||||
if (!isDryRun) {
|
||||
ImmutableSet<ImmutableObject> entitiesToSave =
|
||||
new ImmutableSet.Builder<ImmutableObject>()
|
||||
.addAll(historyEntries)
|
||||
.addAll(syntheticOneTimes)
|
||||
.build();
|
||||
ofy().save().entities(entitiesToSave).now();
|
||||
}
|
||||
return syntheticOneTimes.size();
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
getContext().incrementCounter("error: " + t.getClass().getSimpleName());
|
||||
getContext().incrementCounter(ERROR_COUNTER);
|
||||
@@ -279,7 +290,8 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||
return Streams.stream(oneTimesForDomain)
|
||||
.filter(
|
||||
billingEvent ->
|
||||
Key.create(recurringEvent)
|
||||
recurringEvent
|
||||
.createVKey()
|
||||
.equals(billingEvent.getCancellationMatchingBillingEvent()))
|
||||
.map(OneTime::getBillingTime)
|
||||
.collect(toImmutableSet());
|
||||
|
||||
@@ -442,10 +442,8 @@ public class BigqueryConnection implements AutoCloseable {
|
||||
* Returns the result of calling queryToLocalTable, but synchronously to avoid spawning new
|
||||
* background threads, which App Engine doesn't support.
|
||||
*
|
||||
* @see <a href="https://cloud.google.com/appengine/docs/standard/java/runtime#Threads">
|
||||
* App Engine Runtime</a>
|
||||
*
|
||||
* <p>Returns the results of the query in an ImmutableTable on success.
|
||||
* @see <a href="https://cloud.google.com/appengine/docs/standard/java/runtime#Threads">App Engine
|
||||
* Runtime</a>
|
||||
*/
|
||||
public ImmutableTable<Integer, TableFieldSchema, Object> queryToLocalTableSync(String querySql) {
|
||||
Job job = new Job()
|
||||
@@ -576,8 +574,6 @@ public class BigqueryConnection implements AutoCloseable {
|
||||
|
||||
/**
|
||||
* Launch a job, wait for it to complete, but <i>do not</i> check for errors.
|
||||
*
|
||||
* @throws BigqueryJobFailureException
|
||||
*/
|
||||
public Job runJob(Job job, @Nullable AbstractInputStreamContent data) {
|
||||
return checkJob(waitForJob(launchJob(job, data)));
|
||||
|
||||
@@ -84,7 +84,7 @@ public class DnsMessageTransport {
|
||||
* @param query a message to send
|
||||
* @return the response received from the server
|
||||
* @throws IOException if the Socket input/output streams throws one
|
||||
* @throws IllegalArgumentException if the query is too large to be sent (> 65535 bytes)
|
||||
* @throws IllegalArgumentException if the query is too large to be sent (> 65535 bytes)
|
||||
*/
|
||||
public Message send(Message query) throws IOException {
|
||||
try (Socket socket = factory.createSocket(InetAddress.getByName(updateHost), DNS_PORT)) {
|
||||
|
||||
@@ -73,8 +73,10 @@ public class BigqueryPollJobAction implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
checkJobOutcome(); // Throws a NotModifiedException if the job hasn't completed.
|
||||
if (payload == null || payload.length == 0) {
|
||||
boolean jobOutcome =
|
||||
checkJobOutcome(); // Throws a NotModifiedException if the job hasn't completed.
|
||||
// If the job failed, do not enqueue the next step.
|
||||
if (!jobOutcome || payload == null || payload.length == 0) {
|
||||
return;
|
||||
}
|
||||
// If there is a payload, it's a chained task, so enqueue it.
|
||||
|
||||
@@ -42,8 +42,8 @@ import javax.xml.stream.events.XMLEvent;
|
||||
/**
|
||||
* Sanitizes sensitive data in incoming/outgoing EPP XML messages.
|
||||
*
|
||||
* <p>Current implementation masks user credentials (text following <pw> and <newPW> tags) as
|
||||
* follows:
|
||||
* <p>Current implementation masks user credentials (text following <pw> and <newPW>
|
||||
* tags) as follows:
|
||||
*
|
||||
* <ul>
|
||||
* <li>A control character (in ranges [0 - 1F] and [7F - 9F]) is replaced with 'C'.
|
||||
|
||||
@@ -75,7 +75,7 @@ public class DomainCheckFlowCustomLogic extends BaseFlowCustomLogic {
|
||||
|
||||
/**
|
||||
* The time to perform the domain check as of. This defaults to the current time, but can be
|
||||
* overridden in v>=0.12 of the fee extension.
|
||||
* overridden in v>=0.12 of the fee extension.
|
||||
*/
|
||||
public abstract DateTime asOfDate();
|
||||
|
||||
@@ -105,7 +105,7 @@ public class DomainCheckFlowCustomLogic extends BaseFlowCustomLogic {
|
||||
|
||||
/**
|
||||
* The time to perform the domain check as of. This defaults to the current time, but can be
|
||||
* overridden in v>=0.12 of the fee extension.
|
||||
* overridden in v>=0.12 of the fee extension.
|
||||
*/
|
||||
public abstract DateTime asOfDate();
|
||||
|
||||
|
||||
@@ -534,7 +534,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||
.setPeriodYears(years)
|
||||
.setCost(feesAndCredits.getCreateCost())
|
||||
.setEventTime(now)
|
||||
.setAllocationToken(allocationToken.map(Key::create).orElse(null))
|
||||
.setAllocationToken(allocationToken.map(AllocationToken::createVKey).orElse(null))
|
||||
.setBillingTime(
|
||||
now.plus(
|
||||
isAnchorTenant
|
||||
|
||||
@@ -44,6 +44,7 @@ import google.registry.config.RegistryConfig;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.ofy.CommitLogManifest;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.util.NonFinalForTesting;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -183,6 +184,9 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
/** Get the foreign key string for this resource. */
|
||||
public abstract String getForeignKey();
|
||||
|
||||
/** Create the VKey for the specified EPP resource. */
|
||||
public abstract VKey<? extends EppResource> createVKey();
|
||||
|
||||
/** Override of {@link Buildable#asBuilder} so that the extra methods are visible. */
|
||||
@Override
|
||||
public abstract Builder<?, ?> asBuilder();
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -139,10 +140,13 @@ public class ModelUtils {
|
||||
|
||||
// If the field's type is the same as the field's class object, then it's a non-parameterized
|
||||
// type, and thus we just add it directly. We also don't bother looking at the parameterized
|
||||
// types of Key objects, since they are just references to other objects and don't actually
|
||||
// embed themselves in the persisted object anyway.
|
||||
// types of Key and VKey objects, since they are just references to other objects and don't
|
||||
// actually embed themselves in the persisted object anyway.
|
||||
Class<?> fieldClazz = field.getType();
|
||||
Type fieldType = field.getGenericType();
|
||||
if (VKey.class.equals(fieldClazz)) {
|
||||
continue;
|
||||
}
|
||||
builder.add(fieldClazz);
|
||||
if (fieldType.equals(fieldClazz) || Key.class.equals(clazz)) {
|
||||
continue;
|
||||
|
||||
@@ -50,7 +50,8 @@ import java.util.stream.Collectors;
|
||||
public class OteStats {
|
||||
|
||||
/**
|
||||
* Returns the statistics about the OT&E actions that have been taken by a particular registrar.
|
||||
* Returns the statistics about the OT&E actions that have been taken by a particular
|
||||
* registrar.
|
||||
*/
|
||||
public static OteStats getFromRegistrar(String registrarName) {
|
||||
return new OteStats().recordRegistrarHistory(registrarName);
|
||||
|
||||
@@ -30,7 +30,7 @@ public class UpdateAutoTimestamp extends ImmutableObject {
|
||||
|
||||
DateTime timestamp;
|
||||
|
||||
/** Returns the timestamp, or {@link START_OF_TIME} if it's null. */
|
||||
/** Returns the timestamp, or {@code START_OF_TIME} if it's null. */
|
||||
public DateTime getTimestamp() {
|
||||
return Optional.ofNullable(timestamp).orElse(START_OF_TIME);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.common.collect.Sets;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
@@ -43,14 +44,28 @@ import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithLongVKey;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
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.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 {
|
||||
|
||||
@@ -93,24 +108,41 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
|
||||
/** Entity id. */
|
||||
@Id
|
||||
long id;
|
||||
@javax.persistence.Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
Long id;
|
||||
|
||||
@Parent
|
||||
@DoNotHydrate
|
||||
Key<HistoryEntry> parent;
|
||||
@Parent @DoNotHydrate @Transient Key<HistoryEntry> parent;
|
||||
|
||||
/** The registrar to bill. */
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
String clientId;
|
||||
|
||||
/** Revision id of the entry in DomainHistory table that ths bill belongs to. */
|
||||
// TODO(shicong): Add foreign key constraint when DomainHistory table is generated
|
||||
@Ignore
|
||||
@Column(nullable = false)
|
||||
Long domainHistoryRevisionId;
|
||||
|
||||
/** ID of the EPP resource that the bill is for. */
|
||||
// TODO(shicong): Add foreign key constraint when we expand DatastoreHelp for Postgresql
|
||||
@Ignore
|
||||
@Column(nullable = false)
|
||||
String domainRepoId;
|
||||
|
||||
/** When this event was created. For recurring events, this is also the recurrence start time. */
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
DateTime eventTime;
|
||||
|
||||
/** The reason for the bill. */
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
Reason reason;
|
||||
|
||||
/** The fully qualified domain name of the domain that the bill is for. */
|
||||
@Column(name = "domain_name", nullable = false)
|
||||
String targetId;
|
||||
|
||||
@Nullable
|
||||
@@ -120,6 +152,14 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public long getDomainHistoryRevisionId() {
|
||||
return domainHistoryRevisionId;
|
||||
}
|
||||
|
||||
public String getDomainRepoId() {
|
||||
return domainRepoId;
|
||||
}
|
||||
|
||||
public DateTime getEventTime() {
|
||||
return eventTime;
|
||||
}
|
||||
@@ -163,7 +203,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setId(Long id) {
|
||||
public B setId(long id) {
|
||||
getInstance().id = id;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
@@ -173,6 +213,16 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setDomainHistoryRevisionId(long domainHistoryRevisionId) {
|
||||
getInstance().domainHistoryRevisionId = domainHistoryRevisionId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setDomainRepoId(String domainRepoId) {
|
||||
getInstance().domainRepoId = domainRepoId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setEventTime(DateTime eventTime) {
|
||||
getInstance().eventTime = eventTime;
|
||||
return thisCastToDerived();
|
||||
@@ -194,6 +244,7 @@ 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();
|
||||
}
|
||||
@@ -213,9 +264,23 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
/** A one-time billable event. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingEvent")
|
||||
@javax.persistence.Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "clientId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "billingTime"),
|
||||
@javax.persistence.Index(columnList = "syntheticCreationTime"),
|
||||
@javax.persistence.Index(columnList = "allocation_token_id")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_event_id"))
|
||||
public static class OneTime extends BillingEvent {
|
||||
|
||||
/** The billable value. */
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "money.amount", column = @Column(name = "cost_amount")),
|
||||
@AttributeOverride(name = "money.currency", column = @Column(name = "cost_currency"))
|
||||
})
|
||||
Money cost;
|
||||
|
||||
/** When the cost should be billed. */
|
||||
@@ -223,8 +288,8 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
DateTime billingTime;
|
||||
|
||||
/**
|
||||
* The period in years of the action being billed for, if applicable, otherwise null.
|
||||
* Used for financial reporting.
|
||||
* The period in years of the action being billed for, if applicable, otherwise null. Used for
|
||||
* financial reporting.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
Integer periodYears = null;
|
||||
@@ -240,15 +305,21 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
|
||||
/**
|
||||
* For {@link Flag#SYNTHETIC} events, a {@link Key} to the {@link BillingEvent} from which this
|
||||
* OneTime was created. This is needed in order to properly match billing events against
|
||||
* {@link Cancellation}s.
|
||||
* OneTime was created. This is needed in order to properly match billing events against {@link
|
||||
* Cancellation}s.
|
||||
*/
|
||||
Key<? extends BillingEvent> cancellationMatchingBillingEvent;
|
||||
@Column(name = "cancellation_matching_billing_recurrence_id")
|
||||
VKey<? extends BillingEvent> cancellationMatchingBillingEvent;
|
||||
|
||||
/**
|
||||
* The {@link AllocationToken} used in the creation of this event, or null if one was not used.
|
||||
*
|
||||
* <p>TODO(shicong): Add foreign key constraint when AllocationToken schema is generated
|
||||
*/
|
||||
@Index @Nullable Key<AllocationToken> allocationToken;
|
||||
@Column(name = "allocation_token_id")
|
||||
@Index
|
||||
@Nullable
|
||||
VKey<AllocationToken> allocationToken;
|
||||
|
||||
public Money getCost() {
|
||||
return cost;
|
||||
@@ -266,14 +337,18 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return syntheticCreationTime;
|
||||
}
|
||||
|
||||
public Key<? extends BillingEvent> getCancellationMatchingBillingEvent() {
|
||||
public VKey<? extends BillingEvent> getCancellationMatchingBillingEvent() {
|
||||
return cancellationMatchingBillingEvent;
|
||||
}
|
||||
|
||||
public Optional<Key<AllocationToken>> getAllocationToken() {
|
||||
public Optional<VKey<AllocationToken>> getAllocationToken() {
|
||||
return Optional.ofNullable(allocationToken);
|
||||
}
|
||||
|
||||
public VKey<OneTime> createVKey() {
|
||||
return VKey.createOfy(getClass(), Key.create(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
@@ -311,12 +386,12 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
|
||||
public Builder setCancellationMatchingBillingEvent(
|
||||
Key<? extends BillingEvent> cancellationMatchingBillingEvent) {
|
||||
VKey<? extends BillingEvent> cancellationMatchingBillingEvent) {
|
||||
getInstance().cancellationMatchingBillingEvent = cancellationMatchingBillingEvent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllocationToken(@Nullable Key<AllocationToken> allocationToken) {
|
||||
public Builder setAllocationToken(@Nullable VKey<AllocationToken> allocationToken) {
|
||||
getInstance().allocationToken = allocationToken;
|
||||
return this;
|
||||
}
|
||||
@@ -361,6 +436,15 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingRecurrence")
|
||||
@javax.persistence.Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "clientId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "recurrenceEndTime"),
|
||||
@javax.persistence.Index(columnList = "recurrence_time_of_year")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_recurrence_id"))
|
||||
public static class Recurring extends BillingEvent {
|
||||
|
||||
/**
|
||||
@@ -384,6 +468,10 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
* model, whereas the billing time is a fixed {@link org.joda.time.Duration} later.
|
||||
*/
|
||||
@Index
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "timeString", column = @Column(name = "recurrence_time_of_year"))
|
||||
})
|
||||
TimeOfYear recurrenceTimeOfYear;
|
||||
|
||||
public DateTime getRecurrenceEndTime() {
|
||||
@@ -394,6 +482,10 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return recurrenceTimeOfYear;
|
||||
}
|
||||
|
||||
public VKey<Recurring> createVKey() {
|
||||
return VKey.createOfy(getClass(), Key.create(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
@@ -434,6 +526,14 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "BillingCancellation")
|
||||
@javax.persistence.Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "clientId"),
|
||||
@javax.persistence.Index(columnList = "eventTime"),
|
||||
@javax.persistence.Index(columnList = "billingTime")
|
||||
})
|
||||
@AttributeOverride(name = "id", column = @Column(name = "billing_cancellation_id"))
|
||||
public static class Cancellation extends BillingEvent {
|
||||
|
||||
/** The billing time of the charge that is being cancelled. */
|
||||
@@ -446,7 +546,8 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
* <p>Although the type is {@link Key} the name "ref" is preserved for historical reasons.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
Key<BillingEvent.OneTime> refOneTime = null;
|
||||
@Column(name = "billing_event_id")
|
||||
VKey<BillingEvent.OneTime> refOneTime = null;
|
||||
|
||||
/**
|
||||
* The recurring billing event to cancel, or null for non-autorenew cancellations.
|
||||
@@ -454,13 +555,14 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
* <p>Although the type is {@link Key} the name "ref" is preserved for historical reasons.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
Key<BillingEvent.Recurring> refRecurring = null;
|
||||
@Column(name = "billing_recurrence_id")
|
||||
VKey<BillingEvent.Recurring> refRecurring = null;
|
||||
|
||||
public DateTime getBillingTime() {
|
||||
return billingTime;
|
||||
}
|
||||
|
||||
public Key<? extends BillingEvent> getEventKey() {
|
||||
public VKey<? extends BillingEvent> getEventKey() {
|
||||
return firstNonNull(refOneTime, refRecurring);
|
||||
}
|
||||
|
||||
@@ -492,13 +594,19 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
.setParent(historyEntry);
|
||||
// Set the grace period's billing event using the appropriate Cancellation builder method.
|
||||
if (gracePeriod.getOneTimeBillingEvent() != null) {
|
||||
builder.setOneTimeEventKey(gracePeriod.getOneTimeBillingEvent());
|
||||
builder.setOneTimeEventKey(
|
||||
VKey.createOfy(BillingEvent.OneTime.class, gracePeriod.getOneTimeBillingEvent()));
|
||||
} else if (gracePeriod.getRecurringBillingEvent() != null) {
|
||||
builder.setRecurringEventKey(gracePeriod.getRecurringBillingEvent());
|
||||
builder.setRecurringEventKey(
|
||||
VKey.createOfy(BillingEvent.Recurring.class, gracePeriod.getRecurringBillingEvent()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public VKey<Cancellation> createVKey() {
|
||||
return VKey.createOfy(getClass(), Key.create(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
@@ -518,12 +626,12 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setOneTimeEventKey(Key<BillingEvent.OneTime> eventKey) {
|
||||
public Builder setOneTimeEventKey(VKey<BillingEvent.OneTime> eventKey) {
|
||||
getInstance().refOneTime = eventKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRecurringEventKey(Key<BillingEvent.Recurring> eventKey) {
|
||||
public Builder setRecurringEventKey(VKey<BillingEvent.Recurring> eventKey) {
|
||||
getInstance().refRecurring = eventKey;
|
||||
return this;
|
||||
}
|
||||
@@ -540,9 +648,7 @@ public abstract class BillingEvent extends ImmutableObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An event representing a modification of an existing one-time billing event.
|
||||
*/
|
||||
/** An event representing a modification of an existing one-time billing event. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
public static class Modification extends BillingEvent {
|
||||
|
||||
@@ -29,20 +29,22 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import java.util.List;
|
||||
import javax.persistence.Embeddable;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A time of year (month, day, millis of day) that can be stored in a sort-friendly format.
|
||||
*
|
||||
* <p>This is conceptually similar to {@code MonthDay} in Joda or more generally to Joda's
|
||||
* {@code Partial}, but the parts we need are too simple to justify a full implementation of
|
||||
* {@code Partial}.
|
||||
* <p>This is conceptually similar to {@code MonthDay} in Joda or more generally to Joda's {@code
|
||||
* Partial}, but the parts we need are too simple to justify a full implementation of {@code
|
||||
* Partial}.
|
||||
*
|
||||
* <p>For simplicity, the native representation of this class's data is its stored format. This
|
||||
* allows it to be embeddable with no translation needed and also delays parsing of the string on
|
||||
* load until it's actually needed.
|
||||
*/
|
||||
@Embed
|
||||
@Embeddable
|
||||
public class TimeOfYear extends ImmutableObject {
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
/** A collection of {@link ContactResource} commands. */
|
||||
public class ContactCommand {
|
||||
|
||||
/** The fields on "chgType" from {@link "http://tools.ietf.org/html/rfc5733"}. */
|
||||
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
|
||||
@XmlTransient
|
||||
public static class ContactCreateOrChange extends ImmutableObject
|
||||
implements ResourceCreateOrChange<ContactResource.Builder> {
|
||||
@@ -111,8 +111,8 @@ public class ContactCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* A create command for a {@link ContactResource}, mapping "createType" from
|
||||
* {@link "http://tools.ietf.org/html/rfc5733"}.
|
||||
* A create command for a {@link ContactResource}, mapping "createType" from <a
|
||||
* href="http://tools.ietf.org/html/rfc5733">RFC5733</a>}.
|
||||
*/
|
||||
@XmlType(propOrder = {"contactId", "postalInfo", "voice", "fax", "email", "authInfo", "disclose"})
|
||||
@XmlRootElement
|
||||
|
||||
@@ -197,7 +197,9 @@ public class ContactResource extends EppResource
|
||||
})
|
||||
Disclose disclose;
|
||||
|
||||
@Override
|
||||
public VKey<ContactResource> createVKey() {
|
||||
// TODO(mmuller): create symmetric keys if we can ever reload both sides.
|
||||
return VKey.createOfy(ContactResource.class, Key.create(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import javax.persistence.Embedded;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
/** The "discloseType" from {@link "http://tools.ietf.org/html/rfc5733"}. */
|
||||
/** The "discloseType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
|
||||
@Embed
|
||||
@Embeddable
|
||||
@XmlType(propOrder = {"name", "org", "addr", "voice", "fax", "email"})
|
||||
@@ -76,7 +76,7 @@ public class Disclose extends ImmutableObject {
|
||||
return flag;
|
||||
}
|
||||
|
||||
/** The "intLocType" from {@link "http://tools.ietf.org/html/rfc5733"}. */
|
||||
/** The "intLocType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
|
||||
@Embed
|
||||
public static class PostalInfoChoice extends ImmutableObject {
|
||||
@XmlAttribute
|
||||
|
||||
@@ -32,8 +32,8 @@ import javax.xml.bind.annotation.adapters.NormalizedStringAdapter;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
/**
|
||||
* Implementation of both "postalInfoType" and "chgPostalInfoType" from {@link
|
||||
* "http://tools.ietf.org/html/rfc5733"}.
|
||||
* Implementation of both "postalInfoType" and "chgPostalInfoType" from <a href=
|
||||
* "http://tools.ietf.org/html/rfc5733">RFC5733</a>.
|
||||
*/
|
||||
@Embed
|
||||
@Embeddable
|
||||
|
||||
@@ -613,6 +613,11 @@ public class DomainBase extends EppResource
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VKey<DomainBase> createVKey() {
|
||||
return VKey.create(DomainBase.class, getRepoId(), Key.create(this));
|
||||
}
|
||||
|
||||
/** Predicate to determine if a given {@link DesignatedContact} is the registrant. */
|
||||
private static final Predicate<DesignatedContact> IS_REGISTRANT =
|
||||
(DesignatedContact contact) -> DesignatedContact.Type.REGISTRANT.equals(contact.type);
|
||||
|
||||
@@ -72,10 +72,10 @@ public class DomainCommand {
|
||||
T cloneAndLinkReferences(DateTime now) throws InvalidReferencesException;
|
||||
}
|
||||
|
||||
/** The fields on "chgType" from {@link "http://tools.ietf.org/html/rfc5731"}. */
|
||||
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5731">RFC5731</a>. */
|
||||
@XmlTransient
|
||||
public static class DomainCreateOrChange<B extends DomainBase.Builder>
|
||||
extends ImmutableObject implements ResourceCreateOrChange<B> {
|
||||
public static class DomainCreateOrChange<B extends DomainBase.Builder> extends ImmutableObject
|
||||
implements ResourceCreateOrChange<B> {
|
||||
|
||||
/** The contactId of the registrant who registered this domain. */
|
||||
@XmlElement(name = "registrant")
|
||||
@@ -103,19 +103,20 @@ public class DomainCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* A create command for a {@link DomainBase}, mapping "createType" from
|
||||
* {@link "http://tools.ietf.org/html/rfc5731"}.
|
||||
* A create command for a {@link DomainBase}, mapping "createType" from <a
|
||||
* href="http://tools.ietf.org/html/rfc5731">RFC5731</a>.
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlType(propOrder = {
|
||||
"fullyQualifiedDomainName",
|
||||
"period",
|
||||
"nameserverFullyQualifiedHostNames",
|
||||
"registrantContactId",
|
||||
"foreignKeyedDesignatedContacts",
|
||||
"authInfo"})
|
||||
public static class Create
|
||||
extends DomainCreateOrChange<DomainBase.Builder>
|
||||
@XmlType(
|
||||
propOrder = {
|
||||
"fullyQualifiedDomainName",
|
||||
"period",
|
||||
"nameserverFullyQualifiedHostNames",
|
||||
"registrantContactId",
|
||||
"foreignKeyedDesignatedContacts",
|
||||
"authInfo"
|
||||
})
|
||||
public static class Create extends DomainCreateOrChange<DomainBase.Builder>
|
||||
implements CreateOrUpdate<Create> {
|
||||
|
||||
/** Fully qualified domain name, which serves as a unique identifier for this domain. */
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
/** The "periodType" from {@link "http://tools.ietf.org/html/rfc5731"}. */
|
||||
/** The "periodType" from <a href="http://tools.ietf.org/html/rfc5731">RFC5731</a>. */
|
||||
@Embed
|
||||
@javax.persistence.Embeddable
|
||||
public class Period extends ImmutableObject {
|
||||
|
||||
+2
@@ -29,11 +29,13 @@ import org.joda.time.DateTime;
|
||||
* An individual price check item in version 0.12 of the fee extension on domain check commands.
|
||||
* Items look like:
|
||||
*
|
||||
* <pre>{@code
|
||||
* <fee:command name="renew" phase="sunrise" subphase="hello">
|
||||
* <fee:period unit="y">1</fee:period>
|
||||
* <fee:class>premium</fee:class>
|
||||
* <fee:date>2017-05-17T13:22:21.0Z</fee:date>
|
||||
* </fee:command>
|
||||
* }</pre>
|
||||
*
|
||||
* In a change from previous versions of the extension, items do not contain domain names; instead,
|
||||
* the names from the non-extension check element are used.
|
||||
|
||||
@@ -95,9 +95,6 @@ public class LaunchNotice extends ImmutableObject {
|
||||
|
||||
/**
|
||||
* Validate the checksum of the notice against the domain label.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* @throws InvalidChecksumException
|
||||
*/
|
||||
public void validate(String domainLabel) throws InvalidChecksumException {
|
||||
// According to http://tools.ietf.org/html/draft-lozano-tmch-func-spec-08#section-6.3, a TCNID
|
||||
|
||||
@@ -49,9 +49,9 @@ public enum GracePeriodStatus implements EppEnum {
|
||||
AUTO_RENEW("autoRenewPeriod"),
|
||||
|
||||
/**
|
||||
* This status value is used to describe a domain for which a <delete> command has been received,
|
||||
* but the domain has not yet been purged because an opportunity exists to restore the domain and
|
||||
* abort the deletion process.
|
||||
* This status value is used to describe a domain for which a <delete> command has been
|
||||
* received, but the domain has not yet been purged because an opportunity exists to restore the
|
||||
* domain and abort the deletion process.
|
||||
*/
|
||||
REDEMPTION("redemptionPeriod"),
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.common.TimedTransitionProperty.TimeMapper;
|
||||
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithStringVKey;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -53,6 +55,7 @@ import org.joda.time.DateTime;
|
||||
/** An entity representing an allocation token. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@WithStringVKey
|
||||
public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||
|
||||
// Promotions should only move forward, and ENDED / CANCELLED are terminal states.
|
||||
@@ -179,6 +182,10 @@ public class AllocationToken extends BackupGroupRoot implements Buildable {
|
||||
return tokenStatusTransitions;
|
||||
}
|
||||
|
||||
public VKey<AllocationToken> createVKey() {
|
||||
return VKey.createOfy(getClass(), Key.create(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder asBuilder() {
|
||||
return new Builder(clone(this));
|
||||
|
||||
@@ -25,7 +25,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
* An allocation token extension that may be present on EPP domain commands.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/draft-ietf-regext-allocation-token-04">the IETF
|
||||
* draft</a> for full details.
|
||||
* draft</a>
|
||||
*/
|
||||
@XmlRootElement(name = "allocationToken")
|
||||
public class AllocationTokenExtension extends ImmutableObject implements CommandExtension {
|
||||
|
||||
@@ -44,8 +44,9 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
/**
|
||||
* Container for generic street address.
|
||||
*
|
||||
* <p>This is the "addrType" type from {@link "http://tools.ietf.org/html/rfc5733"}. It also matches
|
||||
* the "addrType" type from {@link "http://tools.ietf.org/html/draft-lozano-tmch-smd"}.
|
||||
* <p>This is the "addrType" type from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. It
|
||||
* also matches the "addrType" type from <a
|
||||
* href="http://tools.ietf.org/html/draft-lozano-tmch-smd">Mark and Signed Mark Objects Mapping</a>.
|
||||
*
|
||||
* @see google.registry.model.contact.ContactAddress
|
||||
* @see google.registry.model.mark.MarkAddress
|
||||
|
||||
@@ -29,8 +29,9 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
/**
|
||||
* Container for generic E164 phone number.
|
||||
*
|
||||
* <p>This is the "e164" type from {@link "http://tools.ietf.org/html/rfc5733"}. It also matches the
|
||||
* "e164Type" type from {@link "http://tools.ietf.org/html/draft-lozano-tmch-smd"}.
|
||||
* <p>This is the "e164" type from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. It also
|
||||
* matches the "e164Type" type from <a href="http://tools.ietf.org/html/draft-lozano-tmch-smd">Mark
|
||||
* and Signed Mark Objects Mapping</a>
|
||||
*
|
||||
* <blockquote>
|
||||
*
|
||||
|
||||
@@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A greeting, defined in {@link "http://tools.ietf.org/html/rfc5730"}.
|
||||
* A greeting, defined in <a href="http://tools.ietf.org/html/rfc5730">RFC5730</a>.
|
||||
*
|
||||
* <p>It would be nice to make this a singleton, but we need the {@link #svDate} field to stay
|
||||
* current.
|
||||
|
||||
@@ -32,7 +32,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
/** A collection of {@link HostResource} commands. */
|
||||
public class HostCommand {
|
||||
|
||||
/** The fields on "chgType" from {@link "http://tools.ietf.org/html/rfc5732"}. */
|
||||
/** The fields on "chgType" from <a href="http://tools.ietf.org/html/rfc5732">RFC5732</a>. */
|
||||
@XmlTransient
|
||||
abstract static class HostCreateOrChange extends AbstractSingleResourceCommand
|
||||
implements ResourceCreateOrChange<HostResource.Builder> {
|
||||
@@ -42,13 +42,13 @@ public class HostCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* A create command for a {@link HostResource}, mapping "createType" from
|
||||
* {@link "http://tools.ietf.org/html/rfc5732"}.
|
||||
* A create command for a {@link HostResource}, mapping "createType" from <a
|
||||
* href="http://tools.ietf.org/html/rfc5732">RFC5732</a>.
|
||||
*/
|
||||
@XmlType(propOrder = {"targetId", "inetAddresses" })
|
||||
@XmlType(propOrder = {"targetId", "inetAddresses"})
|
||||
@XmlRootElement
|
||||
public static class Create
|
||||
extends HostCreateOrChange implements ResourceCreateOrChange<HostResource.Builder> {
|
||||
public static class Create extends HostCreateOrChange
|
||||
implements ResourceCreateOrChange<HostResource.Builder> {
|
||||
/** IP Addresses for this host. Can be null if this is an external host. */
|
||||
@XmlElement(name = "addr")
|
||||
Set<InetAddress> inetAddresses;
|
||||
|
||||
@@ -123,7 +123,9 @@ public class HostResource extends EppResource
|
||||
return fullyQualifiedHostName;
|
||||
}
|
||||
|
||||
public VKey<HostResource> createKey() {
|
||||
@Override
|
||||
public VKey<HostResource> createVKey() {
|
||||
// TODO(mmuller): create symmetric keys if we can ever reload both sides.
|
||||
return VKey.createOfy(HostResource.class, Key.create(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.impl.translate.TranslatorFactory;
|
||||
import com.googlecode.objectify.impl.translate.opt.joda.MoneyStringTranslatorFactory;
|
||||
import google.registry.config.RegistryEnvironment;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.EntityClasses;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
|
||||
@@ -167,10 +168,16 @@ public class ObjectifyService {
|
||||
}
|
||||
com.googlecode.objectify.ObjectifyService.register(clazz);
|
||||
// Autogenerated ids make the commit log code very difficult since we won't always be able
|
||||
// to create a key for an entity immediately when requesting a save. Disallow that here.
|
||||
checkState(
|
||||
!factory().getMetadata(clazz).getKeyMetadata().isIdGeneratable(),
|
||||
"Can't register %s: Autogenerated ids (@Id on a Long) are not supported.", kind);
|
||||
// to create a key for an entity immediately when requesting a save. So, we require such
|
||||
// entities to implement google.registry.model.Buildable as its build() function allocates the
|
||||
// id to the entity.
|
||||
if (factory().getMetadata(clazz).getKeyMetadata().isIdGeneratable()) {
|
||||
checkState(
|
||||
Buildable.class.isAssignableFrom(clazz),
|
||||
"Can't register %s: Entity with autogenerated ids (@Id on a Long) must implement"
|
||||
+ " google.registry.model.Buildable.",
|
||||
kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ import org.joda.time.DateTime;
|
||||
* <p>Poll messages are identified externally by registrars using the format defined in {@link
|
||||
* PollMessageExternalKeyConverter}.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5730#section-2.9.2.3">RFC5730 - EPP - <poll>
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5730#section-2.9.2.3">RFC5730 - EPP - <poll>
|
||||
* Command</a>
|
||||
*/
|
||||
@Entity
|
||||
|
||||
@@ -158,8 +158,8 @@ public final class ReservedList
|
||||
/**
|
||||
* Gets a ReservedList by name using the caching layer.
|
||||
*
|
||||
* @return An Optional<ReservedList> that has a value if a reserved list exists by the given name,
|
||||
* or absent if not.
|
||||
* @return An Optional<ReservedList> that has a value if a reserved list exists by the given
|
||||
* name, or absent if not.
|
||||
* @throws UncheckedExecutionException if some other error occurs while trying to load the
|
||||
* ReservedList from the cache or Datastore.
|
||||
*/
|
||||
|
||||
@@ -22,8 +22,8 @@ public final class IcannReportingTypes {
|
||||
* Represents the set of possible ICANN Monthly Registry Functions Activity Report fields.
|
||||
*
|
||||
* <p>Refer to the <a
|
||||
* href="https://newgtlds.icann.org/sites/default/files/agreements/agreement-approved-09jan14-en.htm#_DV_M278>ICANN
|
||||
* registry agreement Specification 3 Section 2</a> for details.
|
||||
* href="https://newgtlds.icann.org/sites/default/files/agreements/agreement-approved-09jan14-en.htm#_DV_M278">
|
||||
* ICANN registry agreement Specification 3 Section 2</a> for details.
|
||||
*/
|
||||
public enum ActivityReportField {
|
||||
DOMAIN_CHECK("srs-dom-check"),
|
||||
|
||||
+2
-3
@@ -15,7 +15,6 @@
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import avro.shaded.com.google.common.collect.Maps;
|
||||
import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.registry.Registry.BillingCostTransition;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Converter;
|
||||
@@ -23,8 +22,8 @@ import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* JPA converter for storing/retrieving {@link TimedTransitionProperty <Money, BillingCostTransition
|
||||
* >} objects.
|
||||
* JPA converter for storing/retrieving {@code TimedTransitionProperty<Money,BillingCostTransition>}
|
||||
* objects.
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
public class BillingCostTransitionConverter
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// 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.persistence.converter;
|
||||
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set}. */
|
||||
@Converter(autoApply = true)
|
||||
public class BillingEventFlagSetConverter extends StringSetConverterBase<Flag> {
|
||||
|
||||
@Override
|
||||
String toString(Flag element) {
|
||||
return element.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
Flag fromString(String value) {
|
||||
return Flag.valueOf(value);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -15,12 +15,11 @@
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/**
|
||||
* JPA {@link AttributeConverter} for storing/retrieving {@link List<CidrAddressBlock>} objects.
|
||||
* JPA {@link AttributeConverter} for storing/retrieving {@code List<CidrAddressBlock>} objects.
|
||||
* TODO(shicong): Investigate if we can have one converter for any List type
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
import javax.persistence.Converter;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
||||
/** JPA converter for storing/retrieving {@link Map <CurrencyUnit, BillingAccountEntry>} objects. */
|
||||
/** JPA converter for storing/retrieving {@code Map<CurrencyUnit, BillingAccountEntry>} objects. */
|
||||
@Converter(autoApply = true)
|
||||
public class CurrencyToBillingConverter
|
||||
extends StringMapConverterBase<CurrencyUnit, BillingAccountEntry> {
|
||||
|
||||
+1
-2
@@ -16,11 +16,10 @@ package google.registry.persistence.converter;
|
||||
|
||||
import google.registry.model.contact.Disclose.PostalInfoChoice;
|
||||
import google.registry.model.contact.PostalInfo;
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link List < PostalInfoChoice >}. */
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@code List<PostalInfoChoice>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class PostalInfoChoiceListConverter extends StringListConverterBase<PostalInfoChoice> {
|
||||
|
||||
|
||||
+1
-2
@@ -15,11 +15,10 @@
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import google.registry.model.registrar.RegistrarContact.Type;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<Type>}. */
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@code Set<Type>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class RegistrarPocSetConverter extends StringSetConverterBase<Type> {
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -15,11 +15,10 @@
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<StatusValue>}. */
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@code Set<StatusValue>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StatusValueSetConverter extends StringSetConverterBase<StatusValue> {
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
/**
|
||||
* The {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor} for {@link StringCollection}.
|
||||
*
|
||||
* <p>A {@link StringCollection} object is a simple wrapper for a {@link Collection<String>} which
|
||||
* <p>A {@link StringCollection} object is a simple wrapper for a {@code Collection<String>} which
|
||||
* can be stored as a string array in the database. The {@link JavaTypeDescriptor} and {@link
|
||||
* SqlTypeDescriptor} is used by JPA/Hibernate to map between the collection and {@link Array} which
|
||||
* is the actual type that JDBC uses to read from and write to the database.
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link List<String>}. */
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@code List<String>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StringListConverter extends StringListConverterBase<String> {
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
/**
|
||||
* The {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor} for {@link StringMap}.
|
||||
*
|
||||
* <p>A {@link StringMap} object is a simple wrapper for a {@link Map <String, String>} which can be
|
||||
* <p>A {@link StringMap} object is a simple wrapper for a {@code Map<String, String>} which can be
|
||||
* stored in a column with data type of hstore in the database. The {@link JavaTypeDescriptor} and
|
||||
* {@link SqlTypeDescriptor} is used by JPA/Hibernate to map between the map and hstore which is the
|
||||
* actual type that JDBC uses to read from and write to the database.
|
||||
@@ -156,7 +156,7 @@ public class StringMapDescriptor extends AbstractTypeDescriptor<StringMap>
|
||||
};
|
||||
}
|
||||
|
||||
/** A simple wrapper class for {@link Map<String, String>}. */
|
||||
/** A simple wrapper class for {@code Map<String, String>}. */
|
||||
public static class StringMap {
|
||||
private Map<String, String> map;
|
||||
|
||||
@@ -169,7 +169,7 @@ public class StringMapDescriptor extends AbstractTypeDescriptor<StringMap>
|
||||
return new StringMap(ImmutableMap.copyOf(map));
|
||||
}
|
||||
|
||||
/** Returns the underlying {@link Map<String, String>} object. */
|
||||
/** Returns the underlying {@code Map<String, String>} object. */
|
||||
public Map<String, String> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<String>}. */
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@code Set<String>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StringSetConverter extends StringSetConverterBase<String> {
|
||||
|
||||
|
||||
+1
-2
@@ -15,7 +15,6 @@
|
||||
package google.registry.persistence.converter;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.registry.Registry.TldState;
|
||||
import google.registry.model.registry.Registry.TldStateTransition;
|
||||
import java.util.Map;
|
||||
@@ -23,7 +22,7 @@ import javax.persistence.Converter;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* JPA converter for storing/retrieving {@link TimedTransitionProperty<TldState,
|
||||
* JPA converter for storing/retrieving {@code TimedTransitionProperty<TldState,
|
||||
* TldStateTransition>} objects.
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.persistence.transaction;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@@ -61,10 +61,9 @@ import javax.inject.Inject;
|
||||
* (RDAP) Query Format</a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7483">RFC 7483: JSON Responses for the Registration
|
||||
* Data Access Protocol (RDAP)</a>
|
||||
*
|
||||
* TODO(guyben):This isn't required by the RDAP Technical Implementation Guide, and hence should be
|
||||
* deleted, at least until it's actually required.
|
||||
*/
|
||||
// TODO: This isn't required by the RDAP Technical Implementation Guide, and hence should be
|
||||
// deleted, at least until it's actually required.
|
||||
@Action(
|
||||
service = Action.Service.PUBAPI,
|
||||
path = "/rdap/domains",
|
||||
|
||||
@@ -72,10 +72,9 @@ import javax.inject.Inject;
|
||||
* (RDAP) Query Format</a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7483">RFC 7483: JSON Responses for the Registration
|
||||
* Data Access Protocol (RDAP)</a>
|
||||
*
|
||||
* TODO(guyben):This isn't required by the RDAP Technical Implementation Guide, and hence should be
|
||||
* deleted, at least until it's actually required.
|
||||
*/
|
||||
// TODO: This isn't required by the RDAP Technical Implementation Guide, and hence should be
|
||||
// deleted, at least until it's actually required.
|
||||
@Action(
|
||||
service = Action.Service.PUBAPI,
|
||||
path = "/rdap/entities",
|
||||
|
||||
@@ -221,10 +221,9 @@ public abstract class RdapSearchActionBase extends RdapActionBase {
|
||||
*
|
||||
* <p>This version handles a list of parameter values, all associated with the same name.
|
||||
*
|
||||
* <p>Example: If the original parameters were "a=w&a=x&b=y&c=z", and this method is called with
|
||||
* parameterName = "b" and parameterValues of "p" and "q", the result will be
|
||||
* "a=w&a=x&c=z&b=p&b=q". The new values of parameter "b" replace the old ones.
|
||||
*
|
||||
* <p>Example: If the original parameters were "a=w&a=x&b=y&c=z", and this method is
|
||||
* called with parameterName = "b" and parameterValues of "p" and "q", the result will be
|
||||
* "a=w&a=x&c=z&b=p&b=q". The new values of parameter "b" replace the old ones.
|
||||
*/
|
||||
protected String getRequestUrlWithExtraParameter(
|
||||
String parameterName, List<String> parameterValues) {
|
||||
|
||||
@@ -120,9 +120,6 @@ public final class Ghostryde {
|
||||
|
||||
/**
|
||||
* Creates a ghostryde file from an in-memory byte array.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] encode(byte[] data, PGPPublicKey key)
|
||||
throws IOException, PGPException {
|
||||
@@ -137,9 +134,6 @@ public final class Ghostryde {
|
||||
|
||||
/**
|
||||
* Deciphers a ghostryde file from an in-memory byte array.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] decode(byte[] data, PGPPrivateKey key)
|
||||
throws IOException, PGPException {
|
||||
|
||||
@@ -46,9 +46,6 @@ public final class RdeUtil {
|
||||
/**
|
||||
* Look at some bytes from {@code xmlInput} to ensure it appears to be a FULL XML deposit and
|
||||
* then use a regular expression to extract the watermark timestamp which is returned.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws XmlException
|
||||
*/
|
||||
public static DateTime peekWatermark(BufferedInputStream xmlInput)
|
||||
throws IOException, XmlException {
|
||||
|
||||
@@ -34,7 +34,7 @@ import javax.mail.internet.InternetAddress;
|
||||
import org.joda.time.YearMonth;
|
||||
|
||||
/** Utility functions for sending emails involving monthly invoices. */
|
||||
class BillingEmailUtils {
|
||||
public class BillingEmailUtils {
|
||||
|
||||
private final SendEmailService emailService;
|
||||
private final YearMonth yearMonth;
|
||||
|
||||
@@ -43,8 +43,8 @@ import org.joda.time.YearMonth;
|
||||
* PublishInvoicesAction} to publish the subsequent output.
|
||||
*
|
||||
* <p>This action runs the {@link google.registry.beam.invoicing.InvoicingPipeline} beam template,
|
||||
* staged at gs://<projectId>-beam/templates/invoicing. The pipeline then generates invoices for the
|
||||
* month and stores them on GCS.
|
||||
* staged at gs://<projectId>-beam/templates/invoicing. The pipeline then generates invoices
|
||||
* for the month and stores them on GCS.
|
||||
*/
|
||||
@Action(
|
||||
service = Action.Service.BACKEND,
|
||||
|
||||
@@ -53,7 +53,7 @@ import org.json.JSONException;
|
||||
* pipeline accordingly.
|
||||
*
|
||||
* <p>This calls {@link Spec11EmailUtils#emailSpec11Reports(LocalDate, SoyTemplateInfo, String,
|
||||
* Set)} on success or {@link Spec11EmailUtils#sendAlertEmail(String, String)} on failure.
|
||||
* ImmutableSet)} on success or {@link Spec11EmailUtils#sendAlertEmail(String, String)} on failure.
|
||||
*/
|
||||
@Action(
|
||||
service = Action.Service.BACKEND,
|
||||
|
||||
@@ -45,9 +45,9 @@ public final class RequestParameters {
|
||||
*
|
||||
* <ul>
|
||||
* <li>/foo?bar=hello → hello
|
||||
* <li>/foo?bar=hello&bar=there → hello
|
||||
* <li>/foo?bar=hello&bar=there → hello
|
||||
* <li>/foo?bar= → 400 error (empty)
|
||||
* <li>/foo?bar=&bar=there → 400 error (empty)
|
||||
* <li>/foo?bar=&bar=there → 400 error (empty)
|
||||
* <li>/foo → 400 error (absent)
|
||||
* </ul>
|
||||
*
|
||||
|
||||
@@ -59,7 +59,7 @@ public class CursorDao {
|
||||
.transact(() -> jpaTm().getEntityManager().find(Cursor.class, new CursorId(type, scope)));
|
||||
}
|
||||
|
||||
/** If no scope is given, use {@link Cursor.GLOBAL} as the scope. */
|
||||
/** If no scope is given, use {@link Cursor#GLOBAL} as the scope. */
|
||||
public static Cursor load(CursorType type) {
|
||||
checkNotNull(type, "The type of the cursor to load must be specified");
|
||||
return load(type, Cursor.GLOBAL);
|
||||
|
||||
@@ -214,13 +214,13 @@ public final class RegistryLock extends ImmutableObject implements Buildable, Sq
|
||||
return lockCompletionTimestamp != null && unlockCompletionTimestamp == null;
|
||||
}
|
||||
|
||||
/** Returns true iff the lock was requested >= 1 hour ago and has not been verified. */
|
||||
/** Returns true iff the lock was requested >= 1 hour ago and has not been verified. */
|
||||
public boolean isLockRequestExpired(DateTime now) {
|
||||
return !getLockCompletionTimestamp().isPresent()
|
||||
&& isBeforeOrAt(getLockRequestTimestamp(), now.minusHours(1));
|
||||
}
|
||||
|
||||
/** Returns true iff the unlock was requested >= 1 hour ago and has not been verified. */
|
||||
/** Returns true iff the unlock was requested >= 1 hour ago and has not been verified. */
|
||||
public boolean isUnlockRequestExpired(DateTime now) {
|
||||
Optional<DateTime> unlockRequestTimestamp = getUnlockRequestTimestamp();
|
||||
return unlockRequestTimestamp.isPresent()
|
||||
|
||||
@@ -42,7 +42,7 @@ public class DriveConnection {
|
||||
/**
|
||||
* Creates a folder with the given parent.
|
||||
*
|
||||
* @returns the folder id.
|
||||
* @return the folder id.
|
||||
*/
|
||||
public String createFolder(String title, String parentFolderId) throws IOException {
|
||||
return drive.files()
|
||||
@@ -58,7 +58,7 @@ public class DriveConnection {
|
||||
* existing file is the desired behavior, use {@link #createOrUpdateFile(String, MediaType,
|
||||
* String, byte[])} instead.
|
||||
*
|
||||
* @returns the file id.
|
||||
* @return the file id.
|
||||
*/
|
||||
public String createFile(String title, MediaType mimeType, String parentFolderId, byte[] bytes)
|
||||
throws IOException {
|
||||
@@ -76,13 +76,10 @@ public class DriveConnection {
|
||||
*
|
||||
* @throws IllegalStateException if multiple files with that name exist in the given folder.
|
||||
* @throws IOException if communication with Google Drive fails for any reason.
|
||||
* @returns the file id.
|
||||
* @return the file id.
|
||||
*/
|
||||
public String createOrUpdateFile(
|
||||
String title,
|
||||
MediaType mimeType,
|
||||
String parentFolderId,
|
||||
byte[] bytes) throws IOException {
|
||||
String title, MediaType mimeType, String parentFolderId, byte[] bytes) throws IOException {
|
||||
List<String> existingFiles = listFiles(parentFolderId, String.format("title = '%s'", title));
|
||||
if (existingFiles.size() > 1) {
|
||||
throw new IllegalStateException(String.format(
|
||||
@@ -97,10 +94,10 @@ public class DriveConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the file with the given id in place, setting the title, content, and mime type to
|
||||
* the newly specified values.
|
||||
* Updates the file with the given id in place, setting the title, content, and mime type to the
|
||||
* newly specified values.
|
||||
*
|
||||
* @returns the file id.
|
||||
* @return the file id.
|
||||
*/
|
||||
public String updateFile(String fileId, String title, MediaType mimeType, byte[] bytes)
|
||||
throws IOException {
|
||||
|
||||
@@ -77,10 +77,6 @@ public class TmchXmlSignature {
|
||||
*
|
||||
* @throws GeneralSecurityException for unsupported protocols, certs not signed by the TMCH,
|
||||
* incorrect keys, and for invalid, old, not-yet-valid or revoked certificates.
|
||||
* @throws IOException
|
||||
* @throws MarshalException
|
||||
* @throws ParserConfigurationException
|
||||
* @throws SAXException
|
||||
*/
|
||||
public void verify(byte[] smdXml)
|
||||
throws GeneralSecurityException, IOException, MarshalException, ParserConfigurationException,
|
||||
|
||||
@@ -39,16 +39,14 @@ class CompareDbBackups {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableSet<ComparableEntity> entities1 =
|
||||
RecordAccumulator.readDirectory(new File(args[0]), DATA_FILE_MATCHER)
|
||||
.getComparableEntitySet();
|
||||
ImmutableSet<ComparableEntity> entities2 =
|
||||
RecordAccumulator.readDirectory(new File(args[1]), DATA_FILE_MATCHER)
|
||||
.getComparableEntitySet();
|
||||
ImmutableSet<EntityWrapper> entities1 =
|
||||
RecordAccumulator.readDirectory(new File(args[0]), DATA_FILE_MATCHER).getEntityWrapperSet();
|
||||
ImmutableSet<EntityWrapper> entities2 =
|
||||
RecordAccumulator.readDirectory(new File(args[1]), DATA_FILE_MATCHER).getEntityWrapperSet();
|
||||
|
||||
// Calculate the entities added and removed.
|
||||
SetView<ComparableEntity> added = Sets.difference(entities2, entities1);
|
||||
SetView<ComparableEntity> removed = Sets.difference(entities1, entities2);
|
||||
SetView<EntityWrapper> added = Sets.difference(entities2, entities1);
|
||||
SetView<EntityWrapper> removed = Sets.difference(entities1, entities2);
|
||||
|
||||
printHeader(
|
||||
String.format("First backup: %d records", entities1.size()),
|
||||
@@ -56,14 +54,14 @@ class CompareDbBackups {
|
||||
|
||||
if (!removed.isEmpty()) {
|
||||
printHeader(removed.size() + " records were removed:");
|
||||
for (ComparableEntity entity : removed) {
|
||||
for (EntityWrapper entity : removed) {
|
||||
System.out.println(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (!added.isEmpty()) {
|
||||
printHeader(added.size() + " records were added:");
|
||||
for (ComparableEntity entity : added) {
|
||||
for (EntityWrapper entity : added) {
|
||||
System.out.println(entity);
|
||||
}
|
||||
}
|
||||
|
||||
+38
-6
@@ -15,20 +15,32 @@
|
||||
package google.registry.tools;
|
||||
|
||||
import com.google.appengine.api.datastore.Entity;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/** Wraps {@link Entity} to do hashCode/equals based on both the entity's key and its properties. */
|
||||
final class ComparableEntity {
|
||||
/**
|
||||
* Wraps {@link Entity} for ease of processing in collections.
|
||||
*
|
||||
* <p>Note that the {@link #hashCode}/{@link #equals} methods are based on both the entity's key and
|
||||
* its properties.
|
||||
*/
|
||||
final class EntityWrapper {
|
||||
private static final String TEST_ENTITY_KIND = "TestEntity";
|
||||
|
||||
private final Entity entity;
|
||||
|
||||
ComparableEntity(Entity entity) {
|
||||
EntityWrapper(Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that instanceof ComparableEntity) {
|
||||
ComparableEntity thatEntity = (ComparableEntity) that;
|
||||
if (that instanceof EntityWrapper) {
|
||||
EntityWrapper thatEntity = (EntityWrapper) that;
|
||||
return entity.equals(thatEntity.entity)
|
||||
&& entity.getProperties().equals(thatEntity.entity.getProperties());
|
||||
}
|
||||
@@ -43,6 +55,26 @@ final class ComparableEntity {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComparableEntity(" + entity + ")";
|
||||
return "EntityWrapper(" + entity + ")";
|
||||
}
|
||||
|
||||
public static EntityWrapper from(int id, Property... properties) {
|
||||
Entity entity = new Entity(TEST_ENTITY_KIND, id);
|
||||
for (Property prop : properties) {
|
||||
entity.setProperty(prop.name(), prop.value());
|
||||
}
|
||||
return new EntityWrapper(entity);
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
abstract static class Property {
|
||||
|
||||
static Property create(String name, Object value) {
|
||||
return new AutoValue_EntityWrapper_Property(name, value);
|
||||
}
|
||||
|
||||
abstract String name();
|
||||
|
||||
abstract Object value();
|
||||
}
|
||||
}
|
||||
@@ -36,17 +36,16 @@ import java.util.Optional;
|
||||
*
|
||||
* <p>The input source is automatically closed when all data have been read.
|
||||
*
|
||||
* <p>See <a
|
||||
* href="https://github.com/google/leveldb/blob/master/doc/log_format.md">log_format.md</a> for the
|
||||
* leveldb log format specification.</a>
|
||||
*
|
||||
* <p>There are several other implementations of this, none of which appeared suitable for our use
|
||||
* case: <a href="https://github.com/google/leveldb">The original C++ implementation</a>. <a
|
||||
* href="https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/files/RecordReadChannel">
|
||||
* com.google.appengine.api.files.RecordReadChannel</a> - Exactly what we need but deprecated. The
|
||||
* referenced replacement: <a
|
||||
* href="https://github.com/GoogleCloudPlatform/appengine-gcs-client.git">The App Engine GCS
|
||||
* Client</a> - Does not appear to have any support for working with LevelDB.
|
||||
* Client</a> - Does not appear to have any support for working with LevelDB. *
|
||||
*
|
||||
* <p>See <a
|
||||
* href="https://github.com/google/leveldb/blob/master/doc/log_format.md">log_format.md</a>
|
||||
*/
|
||||
public final class LevelDbLogReader implements Iterator<byte[]> {
|
||||
|
||||
|
||||
@@ -48,14 +48,14 @@ class RecordAccumulator {
|
||||
return new RecordAccumulator(builder.build());
|
||||
}
|
||||
|
||||
/** Creates an entity set from the current set of raw records. */
|
||||
ImmutableSet<ComparableEntity> getComparableEntitySet() {
|
||||
ImmutableSet.Builder<ComparableEntity> builder = new ImmutableSet.Builder<>();
|
||||
/** Creates an {@link EntityWrapper} set from the current set of raw records. */
|
||||
ImmutableSet<EntityWrapper> getEntityWrapperSet() {
|
||||
ImmutableSet.Builder<EntityWrapper> builder = new ImmutableSet.Builder<>();
|
||||
for (byte[] rawRecord : records) {
|
||||
// Parse the entity proto and create an Entity object from it.
|
||||
EntityProto proto = new EntityProto();
|
||||
proto.parseFrom(rawRecord);
|
||||
ComparableEntity entity = new ComparableEntity(EntityTranslator.createFromPb(proto));
|
||||
EntityWrapper entity = new EntityWrapper(EntityTranslator.createFromPb(proto));
|
||||
|
||||
builder.add(entity);
|
||||
}
|
||||
|
||||
@@ -44,43 +44,45 @@ import javax.annotation.concurrent.Immutable;
|
||||
* Declarative functional fluent form field converter / validator.
|
||||
*
|
||||
* <p>This class is responsible for converting arbitrary data, sent to us by the web browser, into
|
||||
* validated data structures that the server-side code can use. For example:<pre>
|
||||
* validated data structures that the server-side code can use. For example:
|
||||
*
|
||||
* private enum Gender { MALE, FEMALE }
|
||||
* <pre>{@code
|
||||
* private enum Gender { MALE, FEMALE }
|
||||
*
|
||||
* private static final FormField<String, String> NAME_FIELD = FormField.named("name")
|
||||
* .matches("[a-z]+")
|
||||
* .range(atMost(16))
|
||||
* .required()
|
||||
* .build();
|
||||
* private static final FormField<String, String> NAME_FIELD = FormField.named("name")
|
||||
* .matches("[a-z]+")
|
||||
* .range(atMost(16))
|
||||
* .required()
|
||||
* .build();
|
||||
*
|
||||
* private static final FormField<String, Gender> GENDER_FIELD = FormField.named("gender")
|
||||
* .asEnum(Gender.class)
|
||||
* .required()
|
||||
* .build();
|
||||
* private static final FormField<String, Gender> GENDER_FIELD = FormField.named("gender")
|
||||
* .asEnum(Gender.class)
|
||||
* .required()
|
||||
* .build();
|
||||
*
|
||||
* public Person makePerson(Map<String, String> params) {
|
||||
* Person.Builder person = new Person.Builder();
|
||||
* for (String name : NAME_FIELD.extract(params).asSet()) {
|
||||
* person.setName(name);
|
||||
* }
|
||||
* for (Gender name : GENDER_FIELD.extract(params).asSet()) {
|
||||
* person.setGender(name);
|
||||
* }
|
||||
* return person.build();
|
||||
* }</pre>
|
||||
* public Person makePerson(Map<String, String> params) {
|
||||
* Person.Builder person = new Person.Builder();
|
||||
* for (String name : NAME_FIELD.extract(params).asSet()) {
|
||||
* person.setName(name);
|
||||
* }
|
||||
* for (Gender name : GENDER_FIELD.extract(params).asSet()) {
|
||||
* person.setGender(name);
|
||||
* }
|
||||
* return person.build();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This class provides <b>full type-safety</b> <i>if and only if</i> you statically initialize
|
||||
* your FormField objects and write a unit test that causes the class to be loaded.
|
||||
*
|
||||
* <h3>Exception Handling</h3>
|
||||
*
|
||||
* <p>When values passed to {@link #convert} or {@link #extract} don't meet the contract,
|
||||
* {@link FormFieldException} will be thrown, which provides the field name and a short error
|
||||
* message that's safe to pass along to the client.
|
||||
* <p>When values passed to {@link #convert} or {@link #extract} don't meet the contract, {@link
|
||||
* FormFieldException} will be thrown, which provides the field name and a short error message
|
||||
* that's safe to pass along to the client.
|
||||
*
|
||||
* <p>You can safely throw {@code FormFieldException} from within your validator functions, and
|
||||
* the field name will automatically be propagated into the exception object for you.
|
||||
* <p>You can safely throw {@code FormFieldException} from within your validator functions, and the
|
||||
* field name will automatically be propagated into the exception object for you.
|
||||
*
|
||||
* <p>In situations when you're validating lists or maps, you'll end up with a hierarchical field
|
||||
* naming structure. For example, if you were validating a list of maps, an error generated by the
|
||||
@@ -92,23 +94,25 @@ import javax.annotation.concurrent.Immutable;
|
||||
* <p>You should never assign a partially constructed {@code FormField.Builder} to a variable or
|
||||
* constant. Instead, you should use {@link #asBuilder()} or {@link #asBuilderNamed(String)}.
|
||||
*
|
||||
* <p>Here is an example of how you might go about defining library definitions:<pre>
|
||||
* <p>Here is an example of how you might go about defining library definitions:
|
||||
*
|
||||
* final class FormFields {
|
||||
* private static final FormField<String, String> COUNTRY_CODE =
|
||||
* FormField.named("countryCode")
|
||||
* .range(Range.singleton(2))
|
||||
* .uppercased()
|
||||
* .in(ImmutableSet.copyOf(Locale.getISOCountries()))
|
||||
* .build();
|
||||
* }
|
||||
* <pre>{@code
|
||||
* final class FormFields {
|
||||
* private static final FormField<String, String> COUNTRY_CODE =
|
||||
* FormField.named("countryCode")
|
||||
* .range(Range.singleton(2))
|
||||
* .uppercased()
|
||||
* .in(ImmutableSet.copyOf(Locale.getISOCountries()))
|
||||
* .build();
|
||||
* }
|
||||
*
|
||||
* final class Form {
|
||||
* private static final FormField<String, String> COUNTRY_CODE_FIELD =
|
||||
* FormFields.COUNTRY_CODE.asBuilder()
|
||||
* .required()
|
||||
* .build();
|
||||
* }</pre>
|
||||
* final class Form {
|
||||
* private static final FormField<String, String> COUNTRY_CODE_FIELD =
|
||||
* FormFields.COUNTRY_CODE.asBuilder()
|
||||
* .required()
|
||||
* .build();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param <I> input value type
|
||||
* @param <O> output value type
|
||||
|
||||
@@ -105,9 +105,10 @@ public class SendEmailUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Sends an email from Nomulus to the registrarChangesNotificationEmailAddresses.
|
||||
/**
|
||||
* Sends an email from Nomulus to the registrarChangesNotificationEmailAddresses.
|
||||
*
|
||||
* <p>See {@link #sendEmail(String, String, ImmutableList<String>)}.
|
||||
* <p>See {@link #sendEmail(String, String, ImmutableList)}.
|
||||
*/
|
||||
public boolean sendEmail(final String subject, String body) {
|
||||
return sendEmail(subject, body, ImmutableList.of());
|
||||
|
||||
@@ -58,40 +58,38 @@ import org.joda.time.Duration;
|
||||
* <p>You can send AJAX requests to our WHOIS API from your <em>very own</em> website using the
|
||||
* following embed code:
|
||||
*
|
||||
* <pre>
|
||||
* <p>
|
||||
* <input id="query-input" placeholder="Domain, Nameserver, IP, etc." autofocus>
|
||||
* <button id="search-button">Lookup</button>
|
||||
* <p>
|
||||
* <pre id="whois-results"></pre>
|
||||
* <script>
|
||||
* (function() {
|
||||
* var WHOIS_API_URL = 'https://domain-registry-alpha.appspot.com/whois/';
|
||||
* function OnKeyPressQueryInput(ev) {
|
||||
* if (typeof ev == 'undefined' && window.event) {
|
||||
* ev = window.event;
|
||||
* }
|
||||
* if (ev.keyCode == 13) {
|
||||
* document.getElementById('search-button').click();
|
||||
* }
|
||||
* <pre>{@code
|
||||
* <input id="query-input" placeholder="Domain, Nameserver, IP, etc." autofocus>
|
||||
* <button id="search-button">Lookup</button>
|
||||
* <pre id="whois-results"></pre>
|
||||
* <script>
|
||||
* (function() {
|
||||
* var WHOIS_API_URL = 'https://domain-registry-alpha.appspot.com/whois/';
|
||||
* function OnKeyPressQueryInput(ev) {
|
||||
* if (typeof ev == 'undefined' && window.event) {
|
||||
* ev = window.event;
|
||||
* }
|
||||
* function OnClickSearchButton() {
|
||||
* var query = document.getElementById('query-input').value;
|
||||
* var req = new XMLHttpRequest();
|
||||
* req.onreadystatechange = function() {
|
||||
* if (req.readyState == 4) {
|
||||
* var results = document.getElementById('whois-results');
|
||||
* results.textContent = req.responseText;
|
||||
* }
|
||||
* };
|
||||
* req.open('GET', WHOIS_API_URL + escape(query), true);
|
||||
* req.send();
|
||||
* if (ev.keyCode == 13) {
|
||||
* document.getElementById('search-button').click();
|
||||
* }
|
||||
* document.getElementById('search-button').onclick = OnClickSearchButton;
|
||||
* document.getElementById('query-input').onkeypress = OnKeyPressQueryInput;
|
||||
* })();
|
||||
* </script>
|
||||
* </pre>
|
||||
* }
|
||||
* function OnClickSearchButton() {
|
||||
* var query = document.getElementById('query-input').value;
|
||||
* var req = new XMLHttpRequest();
|
||||
* req.onreadystatechange = function() {
|
||||
* if (req.readyState == 4) {
|
||||
* var results = document.getElementById('whois-results');
|
||||
* results.textContent = req.responseText;
|
||||
* }
|
||||
* };
|
||||
* req.open('GET', WHOIS_API_URL + escape(query), true);
|
||||
* req.send();
|
||||
* }
|
||||
* document.getElementById('search-button').onclick = OnClickSearchButton;
|
||||
* document.getElementById('query-input').onkeypress = OnKeyPressQueryInput;
|
||||
* })();
|
||||
* </script>
|
||||
* }</pre>
|
||||
*
|
||||
* @see WhoisAction
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
* Move tests to another (sub)project. This is not a big problem, but feels unnatural.
|
||||
* Use Hibernate's ServiceRegistry for bootstrapping (not JPA-compliant)
|
||||
-->
|
||||
<class>google.registry.model.billing.BillingEvent$Cancellation</class>
|
||||
<class>google.registry.model.billing.BillingEvent$OneTime</class>
|
||||
<class>google.registry.model.billing.BillingEvent$Recurring</class>
|
||||
<class>google.registry.model.contact.ContactResource</class>
|
||||
<class>google.registry.model.domain.DomainBase</class>
|
||||
<class>google.registry.model.host.HostResource</class>
|
||||
@@ -36,6 +39,7 @@
|
||||
|
||||
<!-- Customized type converters -->
|
||||
<class>google.registry.persistence.converter.BillingCostTransitionConverter</class>
|
||||
<class>google.registry.persistence.converter.BillingEventFlagSetConverter</class>
|
||||
<class>google.registry.persistence.converter.BloomFilterConverter</class>
|
||||
<class>google.registry.persistence.converter.CidrAddressBlockListConverter</class>
|
||||
<class>google.registry.persistence.converter.CreateAutoTimestampConverter</class>
|
||||
@@ -53,6 +57,8 @@
|
||||
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
|
||||
|
||||
<!-- Generated converters for VKey -->
|
||||
<class>google.registry.model.billing.VKeyConverter_BillingEvent</class>
|
||||
<class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
|
||||
<class>google.registry.model.host.VKeyConverter_HostResource</class>
|
||||
<class>google.registry.model.contact.VKeyConverter_ContactResource</class>
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
{template .resultSuccess}
|
||||
{@param baseClientId: string} /** The base clientId used for the OT&E setup. */
|
||||
{@param contactEmail: string} /** The contact's email added to the registrars. */
|
||||
{@param clientIdToTld: map<string, string>} /** The created registrars->TLD mapping. */
|
||||
{@param clientIdToTld: map<string, string>} /** The created registrars->TLD mapping. */
|
||||
{@param password: string} /** The password given for the created registrars. */
|
||||
{@param username: string} /** Arbitrary username to display. */
|
||||
{@param logoutUrl: string} /** Generated URL for logging out of Google. */
|
||||
|
||||
@@ -609,7 +609,7 @@ public class DeleteContactsAndHostsActionTest
|
||||
.hasDeletionTime(END_OF_TIME);
|
||||
DomainBase domain =
|
||||
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
|
||||
assertThat(domain.getNameservers()).contains(hostAfter.createKey());
|
||||
assertThat(domain.getNameservers()).contains(hostAfter.createVKey());
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostAfter, HOST_DELETE_FAILURE);
|
||||
assertPollMessageFor(
|
||||
historyEntry,
|
||||
@@ -679,7 +679,7 @@ public class DeleteContactsAndHostsActionTest
|
||||
persistResource(
|
||||
newDomainBase("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.setDeletionTime(clock.nowUtc().minusDays(5))
|
||||
.build());
|
||||
enqueuer.enqueueAsyncDelete(
|
||||
@@ -938,7 +938,7 @@ public class DeleteContactsAndHostsActionTest
|
||||
return persistResource(
|
||||
newDomainBase(domainName, contact)
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
+19
-15
@@ -155,7 +155,7 @@ public class ExpandRecurringBillingEventsActionTest
|
||||
.setPeriodYears(1)
|
||||
.setReason(Reason.RENEW)
|
||||
.setSyntheticCreationTime(beginningOfTest)
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setTargetId(domain.getFullyQualifiedDomainName());
|
||||
}
|
||||
|
||||
@@ -274,10 +274,12 @@ public class ExpandRecurringBillingEventsActionTest
|
||||
.setParent(persistedEntries.get(0))
|
||||
.build();
|
||||
// Persist an otherwise identical billing event that differs only in recurring event key.
|
||||
BillingEvent.OneTime persisted = expected.asBuilder()
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring2))
|
||||
.build();
|
||||
BillingEvent.OneTime persisted =
|
||||
expected
|
||||
.asBuilder()
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.build();
|
||||
assertCursorAt(beginningOfTest);
|
||||
assertBillingEventsForResource(domain, persisted, expected, recurring, recurring2);
|
||||
}
|
||||
@@ -604,19 +606,21 @@ public class ExpandRecurringBillingEventsActionTest
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntries.get(0), "TheRegistrar", DateTime.parse("2000-02-19T00:00:00Z"),
|
||||
true);
|
||||
BillingEvent.OneTime expected = defaultOneTimeBuilder()
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.build();
|
||||
BillingEvent.OneTime expected =
|
||||
defaultOneTimeBuilder()
|
||||
.setParent(persistedEntries.get(0))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.build();
|
||||
assertHistoryEntryMatches(
|
||||
domain, persistedEntries.get(1), "TheRegistrar", DateTime.parse("2000-05-20T00:00:00Z"),
|
||||
true);
|
||||
BillingEvent.OneTime expected2 = defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring2))
|
||||
.build();
|
||||
BillingEvent.OneTime expected2 =
|
||||
defaultOneTimeBuilder()
|
||||
.setBillingTime(DateTime.parse("2000-05-20T00:00:00Z"))
|
||||
.setEventTime(DateTime.parse("2000-04-05T00:00:00Z"))
|
||||
.setParent(persistedEntries.get(1))
|
||||
.setCancellationMatchingBillingEvent(recurring2.createVKey())
|
||||
.build();
|
||||
assertBillingEventsForResource(domain, expected, expected2, recurring, recurring2);
|
||||
assertCursorAt(beginningOfTest);
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ public class CloudDnsWriterTest {
|
||||
|
||||
ImmutableSet.Builder<VKey<HostResource>> hostResourceRefBuilder = new ImmutableSet.Builder<>();
|
||||
for (HostResource nameserver : nameservers) {
|
||||
hostResourceRefBuilder.add(nameserver.createKey());
|
||||
hostResourceRefBuilder.add(nameserver.createVKey());
|
||||
}
|
||||
|
||||
return newDomainBase(domainName)
|
||||
|
||||
@@ -105,7 +105,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain =
|
||||
persistActiveDomain("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host1.createKey(), host2.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host1.createVKey(), host2.createVKey()))
|
||||
.build();
|
||||
persistResource(domain);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain1 =
|
||||
persistActiveDomain("example1.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host1.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host1.createVKey()))
|
||||
.build();
|
||||
persistResource(domain1);
|
||||
|
||||
@@ -134,7 +134,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain2 =
|
||||
persistActiveDomain("example2.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host2.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host2.createVKey()))
|
||||
.build();
|
||||
persistResource(domain2);
|
||||
|
||||
@@ -150,7 +150,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain1 =
|
||||
persistActiveDomain("example1.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host1.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host1.createVKey()))
|
||||
.build();
|
||||
persistResource(domain1);
|
||||
|
||||
@@ -158,7 +158,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain2 =
|
||||
persistActiveDomain("example2.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host2.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host2.createVKey()))
|
||||
.build();
|
||||
persistResource(domain2);
|
||||
|
||||
@@ -181,7 +181,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain =
|
||||
persistActiveDomain("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createVKey()))
|
||||
.setDsData(
|
||||
ImmutableSet.of(
|
||||
DelegationSignerData.create(1, 3, 1, base16().decode("0123456789ABCDEF"))))
|
||||
@@ -206,7 +206,7 @@ public class DnsUpdateWriterTest {
|
||||
persistActiveDomain("example.tld")
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.SERVER_HOLD)
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createVKey()))
|
||||
.build();
|
||||
persistResource(domain);
|
||||
|
||||
@@ -250,7 +250,7 @@ public class DnsUpdateWriterTest {
|
||||
newDomainBase("example.tld")
|
||||
.asBuilder()
|
||||
.addSubordinateHost("ns1.example.tld")
|
||||
.addNameserver(host.createKey())
|
||||
.addNameserver(host.createVKey())
|
||||
.build());
|
||||
|
||||
writer.publishHost("ns1.example.tld");
|
||||
@@ -289,7 +289,7 @@ public class DnsUpdateWriterTest {
|
||||
persistResource(
|
||||
persistActiveDomain("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.com").createKey()))
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.com").createVKey()))
|
||||
.build());
|
||||
|
||||
writer.publishHost("ns1.example.tld");
|
||||
@@ -323,7 +323,8 @@ public class DnsUpdateWriterTest {
|
||||
.asBuilder()
|
||||
.addSubordinateHost("ns1.example.tld")
|
||||
.addNameservers(
|
||||
ImmutableSet.of(externalNameserver.createKey(), inBailiwickNameserver.createKey()))
|
||||
ImmutableSet.of(
|
||||
externalNameserver.createVKey(), inBailiwickNameserver.createVKey()))
|
||||
.build());
|
||||
|
||||
writer.publishDomain("example.tld");
|
||||
@@ -358,7 +359,7 @@ public class DnsUpdateWriterTest {
|
||||
.asBuilder()
|
||||
.addSubordinateHost("ns1.example.tld")
|
||||
.addSubordinateHost("foo.example.tld")
|
||||
.addNameserver(inBailiwickNameserver.createKey())
|
||||
.addNameserver(inBailiwickNameserver.createVKey())
|
||||
.build());
|
||||
|
||||
writer.publishDomain("example.tld");
|
||||
@@ -382,7 +383,7 @@ public class DnsUpdateWriterTest {
|
||||
DomainBase domain =
|
||||
persistActiveDomain("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createVKey()))
|
||||
.build();
|
||||
persistResource(domain);
|
||||
when(mockResolver.send(any(Message.class))).thenReturn(messageWithResponseCode(Rcode.SERVFAIL));
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.export;
|
||||
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
|
||||
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
||||
import static google.registry.testing.TestLogHandlerUtils.assertLogMessage;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
@@ -174,6 +175,7 @@ public class BigqueryPollJobActionTest {
|
||||
action.run();
|
||||
assertLogMessage(
|
||||
logHandler, SEVERE, String.format("Bigquery job failed - %s:%s", PROJECT_ID, JOB_ID));
|
||||
assertNoTasksEnqueued(CHAINED_QUEUE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -41,6 +41,7 @@ import google.registry.model.registry.Registry;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.reporting.HistoryEntry.Type;
|
||||
import google.registry.monitoring.whitebox.EppMetric;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeHttpSession;
|
||||
import google.registry.testing.FakeResponse;
|
||||
@@ -339,7 +340,8 @@ public class EppTestCase extends ShardableTestCase {
|
||||
.setTargetId(domain.getFullyQualifiedDomainName())
|
||||
.setClientId(domain.getCurrentSponsorClientId())
|
||||
.setEventTime(deleteTime)
|
||||
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||
.setOneTimeEventKey(
|
||||
VKey.createOfy(OneTime.class, findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
||||
.setBillingTime(createTime.plus(Registry.get(domain.getTld()).getAddGracePeriodLength()))
|
||||
.setReason(Reason.CREATE)
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE))
|
||||
@@ -353,7 +355,8 @@ public class EppTestCase extends ShardableTestCase {
|
||||
.setTargetId(domain.getFullyQualifiedDomainName())
|
||||
.setClientId(domain.getCurrentSponsorClientId())
|
||||
.setEventTime(deleteTime)
|
||||
.setOneTimeEventKey(findKeyToActualOneTimeBillingEvent(billingEventToCancel))
|
||||
.setOneTimeEventKey(
|
||||
VKey.createOfy(OneTime.class, findKeyToActualOneTimeBillingEvent(billingEventToCancel)))
|
||||
.setBillingTime(renewTime.plus(Registry.get(domain.getTld()).getRenewGracePeriodLength()))
|
||||
.setReason(Reason.RENEW)
|
||||
.setParent(getOnlyHistoryEntryOfType(domain, Type.DOMAIN_DELETE))
|
||||
|
||||
@@ -276,7 +276,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||
.setBillingTime(billingTime)
|
||||
.setFlags(expectedBillingFlags)
|
||||
.setParent(historyEntry)
|
||||
.setAllocationToken(allocationToken == null ? null : Key.create(allocationToken))
|
||||
.setAllocationToken(allocationToken == null ? null : allocationToken.createVKey())
|
||||
.build();
|
||||
|
||||
BillingEvent.Recurring renewBillingEvent =
|
||||
|
||||
@@ -214,7 +214,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
||||
.setClientId("TheRegistrar")
|
||||
.setEventTime(eventTime)
|
||||
.setBillingTime(TIME_BEFORE_FLOW.plusDays(1))
|
||||
.setOneTimeEventKey(Key.create(graceBillingEvent))
|
||||
.setOneTimeEventKey(graceBillingEvent.createVKey())
|
||||
.setParent(historyEntryDomainDelete)
|
||||
.build());
|
||||
}
|
||||
@@ -693,7 +693,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
||||
loadByForeignKey(DomainBase.class, getUniqueIdFromCommand(), clock.nowUtc())
|
||||
.get()
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
// Persist another domain that's already been deleted and references this contact and host.
|
||||
persistResource(
|
||||
@@ -703,7 +703,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
||||
loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc())
|
||||
.get()
|
||||
.createVKey())
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.setDeletionTime(START_OF_TIME)
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
|
||||
@@ -118,7 +118,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
|
||||
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
|
||||
DesignatedContact.create(Type.TECH, contact.createVKey())))
|
||||
.setNameservers(
|
||||
inactive ? null : ImmutableSet.of(host1.createKey(), host2.createKey()))
|
||||
inactive ? null : ImmutableSet.of(host1.createVKey(), host2.createVKey()))
|
||||
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR")))
|
||||
.build());
|
||||
// Set the superordinate domain of ns1.example.com to example.com. In reality, this would have
|
||||
@@ -294,7 +294,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
|
||||
ImmutableSet.of(
|
||||
DelegationSignerData.create(
|
||||
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC"))))
|
||||
.setNameservers(ImmutableSet.of(host1.createKey(), host3.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host1.createVKey(), host3.createVKey()))
|
||||
.build());
|
||||
doSuccessfulTest("domain_info_response_dsdata.xml", false);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
import org.joda.money.Money;
|
||||
@@ -402,7 +403,8 @@ public class DomainTransferApproveFlowTest
|
||||
.setEventTime(clock.nowUtc()) // The cancellation happens at the moment of transfer.
|
||||
.setBillingTime(
|
||||
oldExpirationTime.plus(Registry.get("tld").getAutoRenewGracePeriodLength()))
|
||||
.setRecurringEventKey(domain.getAutorenewBillingEvent()));
|
||||
.setRecurringEventKey(
|
||||
VKey.createOfy(BillingEvent.Recurring.class, domain.getAutorenewBillingEvent())));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -100,6 +100,7 @@ import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.transfer.TransferData;
|
||||
import google.registry.model.transfer.TransferResponse;
|
||||
import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -1136,7 +1137,8 @@ public class DomainTransferRequestFlowTest
|
||||
.setEventTime(clock.nowUtc().plus(Registry.get("tld").getAutomaticTransferLength()))
|
||||
.setBillingTime(autorenewTime.plus(Registry.get("tld").getAutoRenewGracePeriodLength()))
|
||||
// The cancellation should refer to the old autorenew billing event.
|
||||
.setRecurringEventKey(existingAutorenewEvent));
|
||||
.setRecurringEventKey(
|
||||
VKey.createOfy(BillingEvent.Recurring.class, existingAutorenewEvent)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1164,7 +1166,8 @@ public class DomainTransferRequestFlowTest
|
||||
.setBillingTime(
|
||||
expirationTime.plus(Registry.get("tld").getAutoRenewGracePeriodLength()))
|
||||
// The cancellation should refer to the old autorenew billing event.
|
||||
.setRecurringEventKey(existingAutorenewEvent));
|
||||
.setRecurringEventKey(
|
||||
VKey.createOfy(BillingEvent.Recurring.class, existingAutorenewEvent)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -139,7 +139,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
DesignatedContact.create(Type.ADMIN, mak21Contact.createVKey()),
|
||||
DesignatedContact.create(Type.BILLING, mak21Contact.createVKey())))
|
||||
.setRegistrant(mak21Contact.createVKey())
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
historyEntryDomainCreate =
|
||||
persistResource(
|
||||
@@ -162,7 +162,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
ImmutableSet.of(
|
||||
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey()),
|
||||
DesignatedContact.create(Type.ADMIN, unusedContact.createVKey())))
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
historyEntryDomainCreate =
|
||||
persistResource(
|
||||
@@ -263,7 +263,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
loadByForeignKey(
|
||||
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
|
||||
.get()
|
||||
.createKey());
|
||||
.createVKey());
|
||||
}
|
||||
}
|
||||
persistResource(
|
||||
@@ -290,7 +290,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
for (int i = 0; i < 26; i++) {
|
||||
HostResource host = persistActiveHost(String.format("max_test_%d.example.tld", i));
|
||||
if (i < 13) {
|
||||
nameservers.add(host.createKey());
|
||||
nameservers.add(host.createVKey());
|
||||
}
|
||||
}
|
||||
ImmutableList.Builder<DesignatedContact> contactsBuilder = new ImmutableList.Builder<>();
|
||||
@@ -378,13 +378,13 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
ImmutableSet.of(
|
||||
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
|
||||
.get()
|
||||
.createKey()))
|
||||
.createVKey()))
|
||||
.build());
|
||||
clock.advanceOneMilli();
|
||||
assertTransactionalFlow(true);
|
||||
runFlowAssertResponse(loadFile("generic_success_response.xml"));
|
||||
domain = reloadResourceByForeignKey();
|
||||
assertThat(domain.getNameservers()).containsExactly(addedHost.createKey());
|
||||
assertThat(domain.getNameservers()).containsExactly(addedHost.createVKey());
|
||||
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.tld", "ns2.example.tld");
|
||||
HostResource existingHost =
|
||||
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
|
||||
@@ -1061,7 +1061,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
ImmutableSet.of(
|
||||
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
|
||||
.get()
|
||||
.createKey()))
|
||||
.createVKey()))
|
||||
.build());
|
||||
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1202,13 +1202,13 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
.doesNotContain(
|
||||
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
|
||||
.get()
|
||||
.createKey());
|
||||
.createVKey());
|
||||
runFlow();
|
||||
assertThat(reloadResourceByForeignKey().getNameservers())
|
||||
.contains(
|
||||
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
|
||||
.get()
|
||||
.createKey());
|
||||
.createVKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1279,7 +1279,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
.addNameserver(
|
||||
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
|
||||
.get()
|
||||
.createKey())
|
||||
.createVKey())
|
||||
.build());
|
||||
persistResource(
|
||||
Registry.get("tld")
|
||||
@@ -1291,7 +1291,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
|
||||
.contains(
|
||||
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
|
||||
.get()
|
||||
.createKey());
|
||||
.createVKey());
|
||||
clock.advanceOneMilli();
|
||||
runFlow();
|
||||
assertThat(reloadResourceByForeignKey().getNameservers())
|
||||
|
||||
@@ -284,7 +284,7 @@ public class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Hos
|
||||
persistResource(
|
||||
newDomainBase("example.tld")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
|
||||
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createVKey()))
|
||||
.build());
|
||||
EppException thrown = assertThrows(ResourceToDeleteIsReferencedException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
|
||||
@@ -92,7 +92,7 @@ public class HostInfoFlowTest extends ResourceFlowTestCase<HostInfoFlow, HostRes
|
||||
persistResource(
|
||||
newDomainBase("example.foobar")
|
||||
.asBuilder()
|
||||
.addNameserver(persistHostResource().createKey())
|
||||
.addNameserver(persistHostResource().createVKey())
|
||||
.build());
|
||||
assertTransactionalFlow(false);
|
||||
// Check that the persisted host info was returned.
|
||||
|
||||
@@ -195,7 +195,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
|
||||
newDomainBase("test.xn--q9jyb4c")
|
||||
.asBuilder()
|
||||
.setDeletionTime(END_OF_TIME)
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
HostResource renamedHost = doSuccessfulTest();
|
||||
assertThat(renamedHost.isSubordinate()).isTrue();
|
||||
|
||||
@@ -17,9 +17,11 @@ package google.registry.model.billing;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
@@ -37,19 +39,25 @@ 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;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link BillingEvent}. */
|
||||
public class BillingEventTest extends EntityTestCase {
|
||||
private final DateTime now = DateTime.now(UTC);
|
||||
|
||||
public BillingEventTest() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
HistoryEntry historyEntry;
|
||||
HistoryEntry historyEntry2;
|
||||
DomainBase domain;
|
||||
BillingEvent.OneTime sqlOneTime;
|
||||
BillingEvent.OneTime oneTime;
|
||||
BillingEvent.OneTime oneTimeSynthetic;
|
||||
BillingEvent.Recurring recurring;
|
||||
@@ -57,7 +65,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||
BillingEvent.Cancellation cancellationRecurring;
|
||||
BillingEvent.Modification modification;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
createTld("tld");
|
||||
domain = persistActiveDomain("foo.tld");
|
||||
@@ -97,7 +105,18 @@ public class BillingEventTest extends EntityTestCase {
|
||||
.setCost(Money.of(USD, 1))
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now.plusDays(5))
|
||||
.setAllocationToken(Key.create(allocationToken))));
|
||||
.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(
|
||||
@@ -107,31 +126,41 @@ public class BillingEventTest extends EntityTestCase {
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)));
|
||||
oneTimeSynthetic = persistResource(commonInit(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setReason(Reason.CREATE)
|
||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
|
||||
.setSyntheticCreationTime(now.plusDays(10))
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.setPeriodYears(2)
|
||||
.setCost(Money.of(USD, 1))
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now.plusDays(5))));
|
||||
cancellationOneTime = persistResource(commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(historyEntry2)
|
||||
.setReason(Reason.CREATE)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusDays(5))
|
||||
.setOneTimeEventKey(Key.create(oneTime))));
|
||||
cancellationRecurring = persistResource(commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(historyEntry2)
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusYears(1).plusDays(45))
|
||||
.setRecurringEventKey(Key.create(recurring))));
|
||||
oneTimeSynthetic =
|
||||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setParent(historyEntry)
|
||||
.setReason(Reason.CREATE)
|
||||
.setFlags(
|
||||
ImmutableSet.of(
|
||||
BillingEvent.Flag.ANCHOR_TENANT, BillingEvent.Flag.SYNTHETIC))
|
||||
.setSyntheticCreationTime(now.plusDays(10))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.setPeriodYears(2)
|
||||
.setCost(Money.of(USD, 1))
|
||||
.setEventTime(now)
|
||||
.setBillingTime(now.plusDays(5))));
|
||||
|
||||
cancellationOneTime =
|
||||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(historyEntry2)
|
||||
.setReason(Reason.CREATE)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusDays(5))
|
||||
.setOneTimeEventKey(oneTime.createVKey())));
|
||||
|
||||
cancellationRecurring =
|
||||
persistResource(
|
||||
commonInit(
|
||||
new BillingEvent.Cancellation.Builder()
|
||||
.setParent(historyEntry2)
|
||||
.setReason(Reason.RENEW)
|
||||
.setEventTime(now.plusDays(1))
|
||||
.setBillingTime(now.plusYears(1).plusDays(45))
|
||||
.setRecurringEventKey(recurring.createVKey())));
|
||||
modification = persistResource(commonInit(
|
||||
new BillingEvent.Modification.Builder()
|
||||
.setParent(historyEntry2)
|
||||
@@ -149,6 +178,83 @@ public class BillingEventTest extends EntityTestCase {
|
||||
.build();
|
||||
}
|
||||
|
||||
private void saveNewBillingEvent(BillingEvent billingEvent) {
|
||||
billingEvent.id = null;
|
||||
jpaTm().transact(() -> jpaTm().saveNew(billingEvent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloudSqlPersistence_OneTime() {
|
||||
saveRegistrar("a registrar");
|
||||
saveNewBillingEvent(sqlOneTime);
|
||||
|
||||
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 fixed =
|
||||
persisted
|
||||
.asBuilder()
|
||||
.setParent(sqlOneTime.getParentKey())
|
||||
.setAllocationToken(sqlOneTime.getAllocationToken().get())
|
||||
.build();
|
||||
assertThat(fixed).isEqualTo(sqlOneTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public 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);
|
||||
|
||||
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
|
||||
BillingEvent.Cancellation fixed =
|
||||
persisted
|
||||
.asBuilder()
|
||||
.setParent(sqlCancellationOneTime.getParentKey())
|
||||
.setOneTimeEventKey(sqlVKey)
|
||||
.build();
|
||||
assertThat(fixed).isEqualTo(sqlCancellationOneTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloudSqlPersistence_Recurring() {
|
||||
saveRegistrar("a registrar");
|
||||
BillingEvent.Recurring sqlRecurring =
|
||||
recurring
|
||||
.asBuilder()
|
||||
.setDomainRepoId(domain.getRepoId())
|
||||
.setDomainHistoryRevisionId(1L)
|
||||
.build();
|
||||
saveNewBillingEvent(sqlRecurring);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistence() {
|
||||
assertThat(ofy().load().entity(oneTime).now()).isEqualTo(oneTime);
|
||||
@@ -183,8 +289,13 @@ public class BillingEventTest extends EntityTestCase {
|
||||
|
||||
@Test
|
||||
public void testCancellationMatching() {
|
||||
Key<?> recurringKey = ofy().load().entity(oneTimeSynthetic).now()
|
||||
.getCancellationMatchingBillingEvent();
|
||||
Key<?> recurringKey =
|
||||
ofy()
|
||||
.load()
|
||||
.entity(oneTimeSynthetic)
|
||||
.now()
|
||||
.getCancellationMatchingBillingEvent()
|
||||
.getOfyKey();
|
||||
assertThat(ofy().load().key(recurringKey).now()).isEqualTo(recurring);
|
||||
}
|
||||
|
||||
@@ -219,7 +330,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||
oneTime
|
||||
.asBuilder()
|
||||
.setFlags(ImmutableSet.of(BillingEvent.Flag.SYNTHETIC))
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
@@ -263,7 +374,7 @@ public class BillingEventTest extends EntityTestCase {
|
||||
() ->
|
||||
oneTime
|
||||
.asBuilder()
|
||||
.setCancellationMatchingBillingEvent(Key.create(recurring))
|
||||
.setCancellationMatchingBillingEvent(recurring.createVKey())
|
||||
.build());
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
@@ -334,8 +445,8 @@ public class BillingEventTest extends EntityTestCase {
|
||||
() ->
|
||||
cancellationOneTime
|
||||
.asBuilder()
|
||||
.setOneTimeEventKey(Key.create(oneTime))
|
||||
.setRecurringEventKey(Key.create(recurring))
|
||||
.setOneTimeEventKey(oneTime.createVKey())
|
||||
.setRecurringEventKey(recurring.createVKey())
|
||||
.build());
|
||||
assertThat(thrown).hasMessageThat().contains("exactly one billing event");
|
||||
}
|
||||
|
||||
@@ -119,7 +119,8 @@ public class DomainBaseSqlTest {
|
||||
.transact(
|
||||
() -> {
|
||||
// Persist the contacts. Note that these need to be persisted before the domain
|
||||
// otherwise we get a foreign key constraint error.
|
||||
// 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);
|
||||
|
||||
@@ -127,7 +128,8 @@ public class DomainBaseSqlTest {
|
||||
jpaTm().saveNew(domain);
|
||||
|
||||
// Persist the host. This does _not_ need to be persisted before the domain,
|
||||
// presumably because its relationship is stored in a join table.
|
||||
// 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);
|
||||
});
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class DomainBaseTest extends EntityTestCase {
|
||||
.setSuperordinateDomain(domainKey)
|
||||
.setRepoId("1-COM")
|
||||
.build())
|
||||
.createKey();
|
||||
.createVKey();
|
||||
VKey<ContactResource> contact1Key =
|
||||
persistResource(
|
||||
new ContactResource.Builder()
|
||||
@@ -221,7 +221,7 @@ public class DomainBaseTest extends EntityTestCase {
|
||||
assertThat(
|
||||
newDomainBase("example.com")
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(newHostResource("foo.example.tld").createKey()))
|
||||
.setNameservers(ImmutableSet.of(newHostResource("foo.example.tld").createVKey()))
|
||||
.build()
|
||||
.nsHosts)
|
||||
.isNotNull();
|
||||
@@ -269,7 +269,7 @@ public class DomainBaseTest extends EntityTestCase {
|
||||
@Test
|
||||
public void testImplicitStatusValues() {
|
||||
ImmutableSet<VKey<HostResource>> nameservers =
|
||||
ImmutableSet.of(newHostResource("foo.example.tld").createKey());
|
||||
ImmutableSet.of(newHostResource("foo.example.tld").createVKey());
|
||||
StatusValue[] statuses = {StatusValue.OK};
|
||||
// OK is implicit if there's no other statuses but there are nameservers.
|
||||
assertAboutDomains()
|
||||
|
||||
@@ -45,7 +45,7 @@ public class JpaEntityCoverage extends ExternalResource {
|
||||
private static final ImmutableSet<Class> ALL_JPA_ENTITIES =
|
||||
PersistenceXmlUtility.getManagedClasses().stream()
|
||||
.filter(e -> !IGNORE_ENTITIES.contains(e.getSimpleName()))
|
||||
.filter(e -> e.getAnnotation(Entity.class) != null)
|
||||
.filter(e -> e.isAnnotationPresent(Entity.class))
|
||||
.collect(ImmutableSet.toImmutableSet());
|
||||
private static final Set<Class> allCoveredJpaEntities = Sets.newHashSet();
|
||||
// Map of test class name to boolean flag indicating if it tests any JPA entities.
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
@@ -180,6 +181,17 @@ public class JpaTestRules {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables logging of SQL statements.
|
||||
*
|
||||
* <p>SQL logging is very noisy and disabled by default. This method maybe useful when
|
||||
* troubleshooting a specific test.
|
||||
*/
|
||||
public Builder withSqlLogging() {
|
||||
withProperty(Environment.SHOW_SQL, "true");
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds a {@link JpaIntegrationTestRule} instance. */
|
||||
public JpaIntegrationTestRule buildIntegrationTestRule() {
|
||||
return new JpaIntegrationTestRule(
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 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.persistence.transaction;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/** Unit test for {@link JpaTestRules.Builder#withSqlLogging()}. */
|
||||
public class JpaTestRulesSqlLoggingTest {
|
||||
|
||||
// Entity under test: configured to log SQL statements to Stdout.
|
||||
@RegisterExtension
|
||||
JpaUnitTestRule jpaRule = new JpaTestRules.Builder().withSqlLogging().buildUnitTestRule();
|
||||
|
||||
private PrintStream orgStdout;
|
||||
private ByteArrayOutputStream stdoutBuffer;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
orgStdout = System.out;
|
||||
System.setOut(new PrintStream(stdoutBuffer = new ByteArrayOutputStream()));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
System.setOut(orgStdout);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sqlLog_displayed() throws UnsupportedEncodingException {
|
||||
jpaTm()
|
||||
.transact(() -> jpaTm().getEntityManager().createNativeQuery("select 1").getSingleResult());
|
||||
assertThat(stdoutBuffer.toString(UTF_8.name())).contains("select 1");
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -41,6 +41,8 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -146,13 +148,15 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
|
||||
ImmutableMap properties = PersistenceModule.providesDefaultDatabaseConfigs();
|
||||
if (!userProperties.isEmpty()) {
|
||||
// If there are user properties, create a new properties object with these added.
|
||||
ImmutableMap.Builder builder = properties.builder();
|
||||
builder.putAll(userProperties);
|
||||
// Forbid Hibernate push to stay consistent with flyway-based schema management.
|
||||
builder.put(Environment.HBM2DDL_AUTO, "none");
|
||||
builder.put(Environment.SHOW_SQL, "true");
|
||||
properties = builder.build();
|
||||
Map<String, String> mergedProperties = Maps.newHashMap();
|
||||
mergedProperties.putAll(properties);
|
||||
mergedProperties.putAll(userProperties);
|
||||
properties = ImmutableMap.copyOf(mergedProperties);
|
||||
}
|
||||
// Forbid Hibernate push to stay consistent with flyway-based schema management.
|
||||
checkState(
|
||||
Objects.equals(properties.get(Environment.HBM2DDL_AUTO), "none"),
|
||||
"The HBM2DDL_AUTO property must be 'none'.");
|
||||
assertReasonableNumDbConnections();
|
||||
emf =
|
||||
createEntityManagerFactory(
|
||||
|
||||
@@ -418,7 +418,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
|
||||
subordinateHostnamesBuilder.add(hostName);
|
||||
HostResource host = makeAndPersistHostResource(
|
||||
hostName, String.format("5.5.%d.%d", 5 + i / 250, i % 250), clock.nowUtc().minusYears(1));
|
||||
hostKeysBuilder.add(host.createKey());
|
||||
hostKeysBuilder.add(host.createVKey());
|
||||
}
|
||||
ImmutableSet<VKey<HostResource>> hostKeys = hostKeysBuilder.build();
|
||||
// Create all the domains at once, then persist them in parallel, for increased efficiency.
|
||||
|
||||
@@ -269,9 +269,9 @@ public class DomainBaseToXjcConverterTest {
|
||||
.setNameservers(
|
||||
ImmutableSet.of(
|
||||
makeHostResource(clock, "3-Q9JYB4C", "bird.or.devil.みんな", "1.2.3.4")
|
||||
.createKey(),
|
||||
.createVKey(),
|
||||
makeHostResource(clock, "4-Q9JYB4C", "ns2.cat.みんな", "bad:f00d:cafe::15:beef")
|
||||
.createKey()))
|
||||
.createVKey()))
|
||||
.setRegistrant(
|
||||
makeContactResource(
|
||||
clock, "12-Q9JYB4C", "5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")
|
||||
|
||||
@@ -116,8 +116,8 @@ final class RdeFixtures {
|
||||
.setIdnTableName("extended_latin")
|
||||
.setNameservers(
|
||||
ImmutableSet.of(
|
||||
makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4").createKey(),
|
||||
makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef").createKey()))
|
||||
makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4").createVKey(),
|
||||
makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef").createVKey()))
|
||||
.setRegistrationExpirationTime(DateTime.parse("1994-01-01T00:00:00Z"))
|
||||
.setGracePeriods(
|
||||
ImmutableSet.of(
|
||||
|
||||
@@ -376,7 +376,7 @@ public class Spec11EmailUtilsTest {
|
||||
return persistResource(
|
||||
newDomainBase(domainName)
|
||||
.asBuilder()
|
||||
.setNameservers(ImmutableSet.of(host.createKey()))
|
||||
.setNameservers(ImmutableSet.of(host.createVKey()))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.schema.integration;
|
||||
|
||||
import static com.google.common.truth.Truth.assert_;
|
||||
|
||||
import google.registry.model.billing.BillingEventTest;
|
||||
import google.registry.model.contact.ContactResourceTest;
|
||||
import google.registry.model.domain.DomainBaseSqlTest;
|
||||
import google.registry.model.registry.RegistryLockDaoTest;
|
||||
@@ -68,6 +69,7 @@ import org.junit.runner.RunWith;
|
||||
@SelectClasses({
|
||||
// BeforeSuiteTest must be the first entry. See class javadoc for details.
|
||||
BeforeSuiteTest.class,
|
||||
BillingEventTest.class,
|
||||
ClaimsListDaoTest.class,
|
||||
ContactResourceTest.class,
|
||||
CursorDaoTest.class,
|
||||
|
||||
@@ -131,8 +131,8 @@ public enum Fixture {
|
||||
DesignatedContact.create(TECH, justine.createVKey())))
|
||||
.setNameservers(
|
||||
ImmutableSet.of(
|
||||
persistActiveHost("ns1.love.xn--q9jyb4c").createKey(),
|
||||
persistActiveHost("ns2.love.xn--q9jyb4c").createKey()))
|
||||
persistActiveHost("ns1.love.xn--q9jyb4c").createVKey(),
|
||||
persistActiveHost("ns2.love.xn--q9jyb4c").createVKey()))
|
||||
.build());
|
||||
|
||||
persistResource(
|
||||
@@ -145,11 +145,11 @@ public enum Fixture {
|
||||
DesignatedContact.create(TECH, justine.createVKey())))
|
||||
.setNameservers(
|
||||
ImmutableSet.of(
|
||||
persistActiveHost("ns1.linode.com").createKey(),
|
||||
persistActiveHost("ns2.linode.com").createKey(),
|
||||
persistActiveHost("ns3.linode.com").createKey(),
|
||||
persistActiveHost("ns4.linode.com").createKey(),
|
||||
persistActiveHost("ns5.linode.com").createKey()))
|
||||
persistActiveHost("ns1.linode.com").createVKey(),
|
||||
persistActiveHost("ns2.linode.com").createVKey(),
|
||||
persistActiveHost("ns3.linode.com").createVKey(),
|
||||
persistActiveHost("ns4.linode.com").createVKey(),
|
||||
persistActiveHost("ns5.linode.com").createVKey()))
|
||||
.build());
|
||||
|
||||
persistResource(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user