mirror of
https://github.com/google/nomulus
synced 2026-08-02 05:16:08 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cecc1a6cc7 | ||
|
|
77bc072aac | ||
|
|
93a479837f | ||
|
|
1e7aae26a3 |
+2
-1
@@ -501,7 +501,8 @@ task javadoc(type: Javadoc) {
|
||||
options.addBooleanOption('Xdoclint:all,-missing', true)
|
||||
options.addBooleanOption("-allow-script-in-comments",true)
|
||||
options.tags = ["type:a:Generic Type",
|
||||
"error:a:Expected Error"]
|
||||
"error:a:Expected Error",
|
||||
"invariant:a:Guaranteed Property"]
|
||||
}
|
||||
|
||||
tasks.build.dependsOn(tasks.javadoc)
|
||||
|
||||
@@ -112,7 +112,7 @@ public class ReplayCommitLogsToSqlAction implements Runnable {
|
||||
return;
|
||||
}
|
||||
Optional<Lock> lock =
|
||||
Lock.acquire(
|
||||
Lock.acquireSql(
|
||||
this.getClass().getSimpleName(), null, LEASE_LENGTH, requestStatusChecker, false);
|
||||
if (!lock.isPresent()) {
|
||||
String message = "Can't acquire SQL commit log replay lock, aborting.";
|
||||
|
||||
@@ -371,6 +371,10 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
||||
String.format(
|
||||
"Domain %s was deleted by registry administrator with final deletion effective: %s",
|
||||
existingDomain.getDomainName(), deletionTime))
|
||||
.setResponseData(
|
||||
ImmutableList.of(
|
||||
DomainPendingActionNotificationResponse.create(
|
||||
existingDomain.getDomainName(), true, trid, now)))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import javax.xml.bind.annotation.XmlTransient;
|
||||
* that we can enforce strictly increasing timestamps.
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public abstract class BackupGroupRoot extends ImmutableObject {
|
||||
public abstract class BackupGroupRoot extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* An automatically managed timestamp of when this object was last written to Datastore.
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.joda.time.DateTime;
|
||||
*
|
||||
* @see CreateAutoTimestampTranslatorFactory
|
||||
*/
|
||||
public class CreateAutoTimestamp extends ImmutableObject {
|
||||
public class CreateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
DateTime timestamp;
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@ public abstract class ImmutableObject implements Cloneable {
|
||||
@Target(FIELD)
|
||||
public @interface Insignificant {}
|
||||
|
||||
// Note: if this class is made to implement Serializable, this field must become 'transient' since
|
||||
// hashing is not stable across executions. Also note that @XmlTransient is forbidden on transient
|
||||
// fields and need to be removed if transient is added.
|
||||
@Ignore @XmlTransient protected Integer hashCode;
|
||||
|
||||
private boolean equalsImmutableObject(ImmutableObject other) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2021 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Marker interface for Nomulus entities whose serialization are implemented in a fragile way. These
|
||||
* entities are made {@link Serializable} so that they can be passed between JVMs. The intended use
|
||||
* case is BEAM pipeline-based cross-database data validation between Datastore and Cloud SQL during
|
||||
* the migration. Note that only objects loaded from the SQL database need serialization support.
|
||||
* Objects exported from Datastore can already be serialized as protocol buffers.
|
||||
*
|
||||
* <p>All entities implementing this interface take advantage of the fact that all Java collection
|
||||
* classes we use, either directly or indirectly, including those in Java libraries, Guava,
|
||||
* Objectify, and Hibernate are {@code Serializable}.
|
||||
*
|
||||
* <p>The {@code serialVersionUID} field has also been omitted in the implementing classes, since
|
||||
* they are not used for persistence.
|
||||
*/
|
||||
// TODO(b/203609782): either remove this interface or fix implementors post migration.
|
||||
public interface UnsafeSerializable extends Serializable {}
|
||||
@@ -38,7 +38,7 @@ import org.joda.time.DateTime;
|
||||
* @see UpdateAutoTimestampTranslatorFactory
|
||||
*/
|
||||
@Embeddable
|
||||
public class UpdateAutoTimestamp extends ImmutableObject {
|
||||
public class UpdateAutoTimestamp extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
// When set to true, database converters/translators should do the auto update. When set to
|
||||
// false, auto update should be suspended (this exists to allow us to preserve the original value
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.googlecode.objectify.annotation.Parent;
|
||||
import com.googlecode.objectify.condition.IfNull;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.common.TimeOfYear;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
@@ -72,7 +73,7 @@ import org.joda.time.DateTime;
|
||||
/** A billable event in a domain's lifecycle. */
|
||||
@MappedSuperclass
|
||||
public abstract class BillingEvent extends ImmutableObject
|
||||
implements Buildable, TransferServerApproveEntity {
|
||||
implements Buildable, TransferServerApproveEntity, UnsafeSerializable {
|
||||
|
||||
/** The reason for the bill, which maps 1:1 to skus in go/registry-billing-skus. */
|
||||
public enum Reason {
|
||||
|
||||
@@ -27,13 +27,13 @@ import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.OnLoad;
|
||||
import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.UpdateAutoTimestamp;
|
||||
import google.registry.model.annotations.InCrossTld;
|
||||
import google.registry.model.common.Cursor.CursorId;
|
||||
import google.registry.model.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.persistence.Column;
|
||||
@@ -53,7 +53,7 @@ import org.joda.time.DateTime;
|
||||
@javax.persistence.Entity
|
||||
@IdClass(CursorId.class)
|
||||
@InCrossTld
|
||||
public class Cursor extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
public class Cursor extends ImmutableObject implements DatastoreAndSqlEntity, UnsafeSerializable {
|
||||
|
||||
/** The scope of a global cursor. A global cursor is a cursor that is not specific to one tld. */
|
||||
public static final String GLOBAL = "GLOBAL";
|
||||
@@ -283,7 +283,7 @@ public class Cursor extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
return cursorTime;
|
||||
}
|
||||
|
||||
static class CursorId extends ImmutableObject implements Serializable {
|
||||
public static class CursorId extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
public CursorType type;
|
||||
public String scope;
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.google.common.collect.Range;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import java.util.List;
|
||||
import javax.persistence.Embeddable;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -45,7 +46,7 @@ import org.joda.time.DateTime;
|
||||
*/
|
||||
@Embed
|
||||
@Embeddable
|
||||
public class TimeOfYear extends ImmutableObject {
|
||||
public class TimeOfYear extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* The time as "month day millis" with all fields left-padded with zeroes so that lexographic
|
||||
|
||||
@@ -27,7 +27,9 @@ import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.googlecode.objectify.mapper.Mapper;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.util.TypeUtils;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -53,11 +55,12 @@ import org.joda.time.DateTime;
|
||||
* to use for storing the list of transitions. The user is given this choice of subclass so that the
|
||||
* field of the value type stored in the transition can be given a customized name.
|
||||
*/
|
||||
public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
extends ForwardingMap<DateTime, T> {
|
||||
public class TimedTransitionProperty<
|
||||
V extends Serializable, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
extends ForwardingMap<DateTime, T> implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* A transition to a value of type {@code V} at a certain time. This superclass only has a field
|
||||
* A transition to a value of type {@code V} at a certain time. This superclass only has a field
|
||||
* for the {@code DateTime}, which means that subclasses should supply the field of type {@code V}
|
||||
* and implementations of the abstract getter and setter methods to access that field. This design
|
||||
* is so that subclasses tagged with @Embed can define a custom field name for their value, for
|
||||
@@ -65,11 +68,12 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
*
|
||||
* <p>The public visibility of this class exists only so that it can be subclassed; clients should
|
||||
* never call any methods on this class or attempt to access its members, but should instead treat
|
||||
* it as a customizable implementation detail of {@code TimedTransitionProperty}. However, note
|
||||
* it as a customizable implementation detail of {@code TimedTransitionProperty}. However, note
|
||||
* that subclasses must also have public visibility so that they can be instantiated via
|
||||
* reflection in a call to {@code fromValueMap}.
|
||||
*/
|
||||
public abstract static class TimedTransition<V> extends ImmutableObject {
|
||||
public abstract static class TimedTransition<V extends Serializable> extends ImmutableObject
|
||||
implements UnsafeSerializable {
|
||||
/** The time at which this value becomes the active value. */
|
||||
private DateTime transitionTime;
|
||||
|
||||
@@ -89,16 +93,16 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the provided value map into the equivalent transition map, using transition objects
|
||||
* of the given TimedTransition subclass. The value map must be sorted according to the natural
|
||||
* Converts the provided value map into the equivalent transition map, using transition objects of
|
||||
* the given TimedTransition subclass. The value map must be sorted according to the natural
|
||||
* ordering of its DateTime keys, and keys cannot be earlier than START_OF_TIME.
|
||||
*/
|
||||
// NB: The Class<T> parameter could be eliminated by getting the class via reflection, but then
|
||||
// the callsite cannot infer T, so unless you explicitly call this as .<V, T>fromValueMap() it
|
||||
// will default to using just TimedTransition<V>, which fails at runtime.
|
||||
private static <V, T extends TimedTransition<V>> NavigableMap<DateTime, T> makeTransitionMap(
|
||||
ImmutableSortedMap<DateTime, V> valueMap,
|
||||
final Class<T> timedTransitionSubclass) {
|
||||
private static <V extends Serializable, T extends TimedTransition<V>>
|
||||
NavigableMap<DateTime, T> makeTransitionMap(
|
||||
ImmutableSortedMap<DateTime, V> valueMap, final Class<T> timedTransitionSubclass) {
|
||||
checkArgument(
|
||||
Ordering.natural().equals(valueMap.comparator()),
|
||||
"Timed transition value map must have transition time keys in chronological order");
|
||||
@@ -121,9 +125,9 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
*
|
||||
* <p>This method should be the normal method for constructing a {@link TimedTransitionProperty}.
|
||||
*/
|
||||
public static <V, T extends TimedTransition<V>> TimedTransitionProperty<V, T> fromValueMap(
|
||||
ImmutableSortedMap<DateTime, V> valueMap,
|
||||
final Class<T> timedTransitionSubclass) {
|
||||
public static <V extends Serializable, T extends TimedTransition<V>>
|
||||
TimedTransitionProperty<V, T> fromValueMap(
|
||||
ImmutableSortedMap<DateTime, V> valueMap, final Class<T> timedTransitionSubclass) {
|
||||
return new TimedTransitionProperty<>(ImmutableSortedMap.copyOf(
|
||||
makeTransitionMap(valueMap, timedTransitionSubclass)));
|
||||
}
|
||||
@@ -175,10 +179,10 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
* @param allowedTransitions optional map of all possible state-to-state transitions
|
||||
* @param allowedTransitionMapName optional transition map description string for error messages
|
||||
* @param initialValue optional initial value; if present, the first transition must have this
|
||||
* value
|
||||
* value
|
||||
* @param badInitialValueErrorMessage option error message string if the initial value is wrong
|
||||
*/
|
||||
public static <V, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
public static <V extends Serializable, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
TimedTransitionProperty<V, T> make(
|
||||
ImmutableSortedMap<DateTime, V> newTransitions,
|
||||
Class<T> transitionClass,
|
||||
@@ -200,7 +204,7 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
* Validates that a transition map is not null or empty, starts at START_OF_TIME, and has
|
||||
* transitions which move from one value to another in allowed ways.
|
||||
*/
|
||||
public static <V, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
public static <V extends Serializable, T extends TimedTransitionProperty.TimedTransition<V>>
|
||||
void validateTimedTransitionMap(
|
||||
@Nullable NavigableMap<DateTime, V> transitionMap,
|
||||
ImmutableMultimap<V, V> allowedTransitions,
|
||||
@@ -240,8 +244,9 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
* annotation. The map for those fields must be mutable so that Objectify can load values from
|
||||
* Datastore into the map, but clients should still never mutate the field's map directly.
|
||||
*/
|
||||
public static <V, T extends TimedTransition<V>> TimedTransitionProperty<V, T> forMapify(
|
||||
ImmutableSortedMap<DateTime, V> valueMap, Class<T> timedTransitionSubclass) {
|
||||
public static <V extends Serializable, T extends TimedTransition<V>>
|
||||
TimedTransitionProperty<V, T> forMapify(
|
||||
ImmutableSortedMap<DateTime, V> valueMap, Class<T> timedTransitionSubclass) {
|
||||
return new TimedTransitionProperty<>(
|
||||
new TreeMap<>(makeTransitionMap(valueMap, timedTransitionSubclass)));
|
||||
}
|
||||
@@ -254,8 +259,9 @@ public class TimedTransitionProperty<V, T extends TimedTransitionProperty.TimedT
|
||||
* annotation. The map for those fields must be mutable so that Objectify can load values from
|
||||
* Datastore into the map, but clients should still never mutate the field's map directly.
|
||||
*/
|
||||
public static <V, T extends TimedTransition<V>> TimedTransitionProperty<V, T> forMapify(
|
||||
V valueAtStartOfTime, Class<T> timedTransitionSubclass) {
|
||||
public static <V extends Serializable, T extends TimedTransition<V>>
|
||||
TimedTransitionProperty<V, T> forMapify(
|
||||
V valueAtStartOfTime, Class<T> timedTransitionSubclass) {
|
||||
return forMapify(
|
||||
ImmutableSortedMap.of(START_OF_TIME, valueAtStartOfTime), timedTransitionSubclass);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.contact.ContactHistory.ContactHistoryId;
|
||||
import google.registry.model.replay.DatastoreEntity;
|
||||
import google.registry.model.replay.SqlEntity;
|
||||
@@ -59,7 +60,7 @@ import javax.persistence.PostLoad;
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
@IdClass(ContactHistoryId.class)
|
||||
public class ContactHistory extends HistoryEntry implements SqlEntity {
|
||||
public class ContactHistory extends HistoryEntry implements SqlEntity, UnsafeSerializable {
|
||||
|
||||
// Store ContactBase instead of ContactResource so we don't pick up its @Id
|
||||
// Nullable for the sake of pre-Registry-3.0 history objects
|
||||
|
||||
@@ -20,7 +20,9 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.eppcommon.PresenceMarker;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
@@ -31,7 +33,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
@Embed
|
||||
@Embeddable
|
||||
@XmlType(propOrder = {"name", "org", "addr", "voice", "fax", "email"})
|
||||
public class Disclose extends ImmutableObject {
|
||||
public class Disclose extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
List<PostalInfoChoice> name;
|
||||
|
||||
@@ -78,7 +80,7 @@ public class Disclose extends ImmutableObject {
|
||||
|
||||
/** The "intLocType" from <a href="http://tools.ietf.org/html/rfc5733">RFC5733</a>. */
|
||||
@Embed
|
||||
public static class PostalInfoChoice extends ImmutableObject {
|
||||
public static class PostalInfoChoice extends ImmutableObject implements Serializable {
|
||||
@XmlAttribute
|
||||
PostalInfo.Type type;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.Buildable.Overlayable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import java.util.Optional;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.EnumType;
|
||||
@@ -38,7 +39,8 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@Embed
|
||||
@Embeddable
|
||||
@XmlType(propOrder = {"name", "org", "address", "type"})
|
||||
public class PostalInfo extends ImmutableObject implements Overlayable<PostalInfo> {
|
||||
public class PostalInfo extends ImmutableObject
|
||||
implements Overlayable<PostalInfo>, UnsafeSerializable {
|
||||
|
||||
/** The type of the address, either localized or international. */
|
||||
public enum Type {
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.persistence.VKey;
|
||||
import javax.persistence.Embeddable;
|
||||
@@ -46,7 +47,7 @@ import javax.xml.bind.annotation.XmlEnumValue;
|
||||
*/
|
||||
@Embed
|
||||
@Embeddable
|
||||
public class DesignatedContact extends ImmutableObject {
|
||||
public class DesignatedContact extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* XML type for contact types. This can be either: {@code "admin"}, {@code "billing"}, or
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.model.domain;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.persistence.BillingVKey.BillingEventVKey;
|
||||
@@ -35,7 +36,7 @@ import org.joda.time.DateTime;
|
||||
@Embed
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
public class GracePeriodBase extends ImmutableObject {
|
||||
public class GracePeriodBase extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/** Unique id required for hibernate representation. */
|
||||
@Transient long gracePeriodId;
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.domain;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
@@ -25,7 +26,7 @@ import javax.xml.bind.annotation.XmlValue;
|
||||
/** The "periodType" from <a href="http://tools.ietf.org/html/rfc5731">RFC5731</a>. */
|
||||
@Embed
|
||||
@javax.persistence.Embeddable
|
||||
public class Period extends ImmutableObject {
|
||||
public class Period extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@XmlAttribute
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.IgnoreSave;
|
||||
import com.googlecode.objectify.condition.IfNull;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import java.util.Optional;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
@@ -39,7 +40,7 @@ import org.joda.time.DateTime;
|
||||
@Embed
|
||||
@XmlType(propOrder = {"noticeId", "expirationTime", "acceptedTime"})
|
||||
@javax.persistence.Embeddable
|
||||
public class LaunchNotice extends ImmutableObject {
|
||||
public class LaunchNotice extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/** An empty instance to use in place of null. */
|
||||
private static final NoticeIdType EMPTY_NOTICE_ID = new NoticeIdType();
|
||||
@@ -47,14 +48,13 @@ public class LaunchNotice extends ImmutableObject {
|
||||
/** An id with a validator-id attribute. */
|
||||
@Embed
|
||||
@javax.persistence.Embeddable
|
||||
public static class NoticeIdType extends ImmutableObject {
|
||||
public static class NoticeIdType extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/**
|
||||
* The Trademark Claims Notice ID from
|
||||
* {@link "http://tools.ietf.org/html/draft-lozano-tmch-func-spec-08#section-6.3"}.
|
||||
* The Trademark Claims Notice ID from <a
|
||||
* href="http://tools.ietf.org/html/draft-lozano-tmch-func-spec-08#section-6.3">the RFC</a>.
|
||||
*/
|
||||
@XmlValue
|
||||
String tcnId;
|
||||
@XmlValue String tcnId;
|
||||
|
||||
/** The identifier of the TMDB provider to use, defaulting to the TMCH. */
|
||||
@IgnoreSave(IfNull.class)
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.model.domain.secdns;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
@@ -31,7 +32,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@Embed
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
public abstract class DomainDsDataBase extends ImmutableObject {
|
||||
public abstract class DomainDsDataBase extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@Ignore @XmlTransient @Transient String domainRepoId;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.domain.secdns;
|
||||
|
||||
import static google.registry.model.IdService.allocateId;
|
||||
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.replay.SqlOnlyEntity;
|
||||
@@ -27,7 +28,8 @@ import javax.persistence.Id;
|
||||
|
||||
/** Entity class to represent a historic {@link DelegationSignerData}. */
|
||||
@Entity
|
||||
public class DomainDsDataHistory extends DomainDsDataBase implements SqlOnlyEntity {
|
||||
public class DomainDsDataHistory extends DomainDsDataBase
|
||||
implements SqlOnlyEntity, UnsafeSerializable {
|
||||
|
||||
@Id Long dsDataHistoryRevisionId;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.JsonMapBuilder;
|
||||
import google.registry.model.Jsonifiable;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -56,7 +57,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@XmlTransient
|
||||
@Embeddable
|
||||
@MappedSuperclass
|
||||
public class Address extends ImmutableObject implements Jsonifiable {
|
||||
public class Address extends ImmutableObject implements Jsonifiable, UnsafeSerializable {
|
||||
|
||||
/** The schema validation will enforce that this has 3 lines at most. */
|
||||
// TODO(b/177569726): Remove this field after migration. We need to figure out how to generate
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.eppcommon;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
@@ -35,7 +36,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@XmlTransient
|
||||
@Embeddable
|
||||
@MappedSuperclass
|
||||
public abstract class AuthInfo extends ImmutableObject {
|
||||
public abstract class AuthInfo extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@Embedded protected PasswordAuth pw;
|
||||
|
||||
@@ -47,7 +48,7 @@ public abstract class AuthInfo extends ImmutableObject {
|
||||
@Embed
|
||||
@XmlType(namespace = "urn:ietf:params:xml:ns:eppcom-1.0")
|
||||
@Embeddable
|
||||
public static class PasswordAuth extends ImmutableObject {
|
||||
public static class PasswordAuth extends ImmutableObject implements UnsafeSerializable {
|
||||
@XmlValue
|
||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||
String value;
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
@@ -49,7 +50,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
@XmlTransient
|
||||
@Embeddable
|
||||
@MappedSuperclass
|
||||
public class PhoneNumber extends ImmutableObject {
|
||||
public class PhoneNumber extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
@XmlValue
|
||||
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
||||
|
||||
@@ -18,6 +18,7 @@ import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
@@ -32,7 +33,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||
@Embed
|
||||
@XmlType(propOrder = {"clientTransactionId", "serverTransactionId"})
|
||||
@javax.persistence.Embeddable
|
||||
public class Trid extends ImmutableObject {
|
||||
public class Trid extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
/** The server transaction id. */
|
||||
@XmlElement(name = "svTRID", namespace = "urn:ietf:params:xml:ns:epp-1.0")
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.host.HostHistory.HostHistoryId;
|
||||
import google.registry.model.replay.DatastoreEntity;
|
||||
import google.registry.model.replay.SqlEntity;
|
||||
@@ -60,7 +61,7 @@ import javax.persistence.PostLoad;
|
||||
@EntitySubclass
|
||||
@Access(AccessType.FIELD)
|
||||
@IdClass(HostHistoryId.class)
|
||||
public class HostHistory extends HistoryEntry implements SqlEntity {
|
||||
public class HostHistory extends HistoryEntry implements SqlEntity, UnsafeSerializable {
|
||||
|
||||
// Store HostBase instead of HostResource so we don't pick up its @Id
|
||||
// Nullable for the sake of pre-Registry-3.0 history objects
|
||||
|
||||
+4
-2
@@ -17,6 +17,7 @@ package google.registry.model.poll;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.eppoutput.EppResponse.ResponseData;
|
||||
import javax.persistence.Embeddable;
|
||||
@@ -31,12 +32,13 @@ import org.joda.time.DateTime;
|
||||
/** The {@link ResponseData} returned when completing a pending action on a domain. */
|
||||
@XmlTransient
|
||||
@Embeddable
|
||||
public class PendingActionNotificationResponse extends ImmutableObject implements ResponseData {
|
||||
public class PendingActionNotificationResponse extends ImmutableObject
|
||||
implements ResponseData, UnsafeSerializable {
|
||||
|
||||
/** The inner name type that contains a name and the result boolean. */
|
||||
@Embed
|
||||
@Embeddable
|
||||
static class NameOrId extends ImmutableObject {
|
||||
static class NameOrId extends ImmutableObject implements UnsafeSerializable {
|
||||
@XmlValue
|
||||
String value;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.ExternalMessagingName;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
@@ -98,7 +99,7 @@ import org.joda.time.DateTime;
|
||||
@javax.persistence.Index(columnList = "eventTime")
|
||||
})
|
||||
public abstract class PollMessage extends ImmutableObject
|
||||
implements Buildable, DatastoreAndSqlEntity, TransferServerApproveEntity {
|
||||
implements Buildable, DatastoreAndSqlEntity, TransferServerApproveEntity, UnsafeSerializable {
|
||||
|
||||
/** Entity id. */
|
||||
@Id
|
||||
|
||||
@@ -72,6 +72,7 @@ import google.registry.model.CreateAutoTimestamp;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.JsonMapBuilder;
|
||||
import google.registry.model.Jsonifiable;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.UpdateAutoTimestamp;
|
||||
import google.registry.model.annotations.InCrossTld;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
@@ -116,7 +117,7 @@ import org.joda.time.DateTime;
|
||||
})
|
||||
@InCrossTld
|
||||
public class Registrar extends ImmutableObject
|
||||
implements Buildable, DatastoreAndSqlEntity, Jsonifiable {
|
||||
implements Buildable, DatastoreAndSqlEntity, Jsonifiable, UnsafeSerializable {
|
||||
|
||||
/** Represents the type of a registrar entity. */
|
||||
public enum Type {
|
||||
@@ -404,7 +405,7 @@ public class Registrar extends ImmutableObject
|
||||
|
||||
/** A billing account entry for this registrar, consisting of a currency and an account Id. */
|
||||
@Embed
|
||||
public static class BillingAccountEntry extends ImmutableObject {
|
||||
public static class BillingAccountEntry extends ImmutableObject implements UnsafeSerializable {
|
||||
|
||||
CurrencyUnit currency;
|
||||
String accountId;
|
||||
|
||||
@@ -46,6 +46,7 @@ import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.JsonMapBuilder;
|
||||
import google.registry.model.Jsonifiable;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.InCrossTld;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.registrar.RegistrarContact.RegistrarPocId;
|
||||
@@ -82,7 +83,7 @@ import javax.persistence.Transient;
|
||||
@IdClass(RegistrarPocId.class)
|
||||
@InCrossTld
|
||||
public class RegistrarContact extends ImmutableObject
|
||||
implements DatastoreAndSqlEntity, Jsonifiable {
|
||||
implements DatastoreAndSqlEntity, Jsonifiable, UnsafeSerializable {
|
||||
|
||||
@Parent @Transient Key<Registrar> parent;
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ public class ReplicateToDatastoreAction implements Runnable {
|
||||
return;
|
||||
}
|
||||
Optional<Lock> lock =
|
||||
Lock.acquire(
|
||||
Lock.acquireSql(
|
||||
this.getClass().getSimpleName(), null, LEASE_LENGTH, requestStatusChecker, false);
|
||||
if (!lock.isPresent()) {
|
||||
String message = "Can't acquire ReplicateToDatastoreAction lock, aborting.";
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.replay.DatastoreAndSqlEntity;
|
||||
import javax.persistence.Column;
|
||||
@@ -46,7 +47,7 @@ import org.joda.time.DateTime;
|
||||
@Embed
|
||||
@Entity
|
||||
public class DomainTransactionRecord extends ImmutableObject
|
||||
implements Buildable, DatastoreAndSqlEntity {
|
||||
implements Buildable, DatastoreAndSqlEntity, UnsafeSerializable {
|
||||
|
||||
@Id
|
||||
@Ignore
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.googlecode.objectify.condition.IfNull;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.contact.ContactBase;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
@@ -83,7 +84,8 @@ import org.joda.time.DateTime;
|
||||
@Entity
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
public class HistoryEntry extends ImmutableObject implements Buildable, DatastoreEntity {
|
||||
public class HistoryEntry extends ImmutableObject
|
||||
implements Buildable, DatastoreEntity, UnsafeSerializable {
|
||||
|
||||
/** Represents the type of history entry. */
|
||||
public enum Type {
|
||||
|
||||
@@ -32,6 +32,8 @@ import google.registry.model.annotations.NotBackedUp;
|
||||
import google.registry.model.annotations.NotBackedUp.Reason;
|
||||
import google.registry.model.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.JpaTransactionManager;
|
||||
import google.registry.persistence.transaction.TransactionManager;
|
||||
import google.registry.util.RequestStatusChecker;
|
||||
import google.registry.util.RequestStatusCheckerImpl;
|
||||
import java.io.Serializable;
|
||||
@@ -212,6 +214,47 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
Duration leaseLength,
|
||||
RequestStatusChecker requestStatusChecker,
|
||||
boolean checkThreadRunning) {
|
||||
return acquireWithTransactionManager(
|
||||
resourceName, tld, leaseLength, requestStatusChecker, checkThreadRunning, tm());
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to acquire a lock in SQL. Returns absent if it can't be acquired.
|
||||
*
|
||||
* <p>This method exists so that Beam pipelines can acquire / load / release locks.
|
||||
*/
|
||||
public static Optional<Lock> acquireSql(
|
||||
String resourceName,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
RequestStatusChecker requestStatusChecker,
|
||||
boolean checkThreadRunning) {
|
||||
return acquireWithTransactionManager(
|
||||
resourceName, tld, leaseLength, requestStatusChecker, checkThreadRunning, jpaTm());
|
||||
}
|
||||
|
||||
/** Release the lock. */
|
||||
public void release() {
|
||||
releaseWithTransactionManager(tm());
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the lock from SQL.
|
||||
*
|
||||
* <p>This method exists so that Beam pipelines can acquire / load / release locks.
|
||||
*/
|
||||
public void releaseSql() {
|
||||
releaseWithTransactionManager(jpaTm());
|
||||
}
|
||||
|
||||
/** Try to acquire a lock. Returns absent if it can't be acquired. */
|
||||
private static Optional<Lock> acquireWithTransactionManager(
|
||||
String resourceName,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
RequestStatusChecker requestStatusChecker,
|
||||
boolean checkThreadRunning,
|
||||
TransactionManager transactionManager) {
|
||||
String scope = (tld != null) ? tld : GLOBAL;
|
||||
String lockId = makeLockId(resourceName, scope);
|
||||
// It's important to use transactNew rather than transact, because a Lock can be used to control
|
||||
@@ -219,11 +262,12 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
// must be definitively acquired before it is used, even when called inside another transaction.
|
||||
Supplier<AcquireResult> lockAcquirer =
|
||||
() -> {
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DateTime now = transactionManager.getTransactionTime();
|
||||
|
||||
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
|
||||
Lock lock =
|
||||
tm().loadByKeyIfPresent(
|
||||
transactionManager
|
||||
.loadByKeyIfPresent(
|
||||
VKey.create(
|
||||
Lock.class,
|
||||
new LockId(resourceName, scope),
|
||||
@@ -249,13 +293,15 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
create(resourceName, scope, requestStatusChecker.getLogId(), now, leaseLength);
|
||||
// Locks are not parented under an EntityGroupRoot (so as to avoid write
|
||||
// contention) and don't need to be backed up.
|
||||
tm().putIgnoringReadOnly(newLock);
|
||||
transactionManager.putIgnoringReadOnly(newLock);
|
||||
|
||||
return AcquireResult.create(now, lock, newLock, lockState);
|
||||
};
|
||||
// In ofy, backup is determined per-action, but in SQL it's determined per-transaction
|
||||
AcquireResult acquireResult =
|
||||
tm().isOfy() ? tm().transactNew(lockAcquirer) : jpaTm().transactWithoutBackup(lockAcquirer);
|
||||
transactionManager.isOfy()
|
||||
? transactionManager.transactNew(lockAcquirer)
|
||||
: ((JpaTransactionManager) transactionManager).transactWithoutBackup(lockAcquirer);
|
||||
|
||||
logAcquireResult(acquireResult);
|
||||
lockMetrics.recordAcquire(resourceName, scope, acquireResult.lockState());
|
||||
@@ -263,7 +309,7 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
}
|
||||
|
||||
/** Release the lock. */
|
||||
public void release() {
|
||||
private void releaseWithTransactionManager(TransactionManager transactionManager) {
|
||||
// Just use the default clock because we aren't actually doing anything that will use the clock.
|
||||
Supplier<Void> lockReleaser =
|
||||
() -> {
|
||||
@@ -274,15 +320,17 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
VKey<Lock> key =
|
||||
VKey.create(
|
||||
Lock.class, new LockId(resourceName, tld), Key.create(Lock.class, lockId));
|
||||
Lock loadedLock = tm().loadByKeyIfPresent(key).orElse(null);
|
||||
Lock loadedLock = transactionManager.loadByKeyIfPresent(key).orElse(null);
|
||||
if (Lock.this.equals(loadedLock)) {
|
||||
// Use deleteIgnoringReadOnly() so that we don't create a commit log entry for deleting
|
||||
// the lock.
|
||||
logger.atInfo().log("Deleting lock: %s", lockId);
|
||||
tm().deleteIgnoringReadOnly(key);
|
||||
transactionManager.deleteIgnoringReadOnly(key);
|
||||
|
||||
lockMetrics.recordRelease(
|
||||
resourceName, tld, new Duration(acquiredTime, tm().getTransactionTime()));
|
||||
resourceName,
|
||||
tld,
|
||||
new Duration(acquiredTime, transactionManager.getTransactionTime()));
|
||||
} else {
|
||||
logger.atSevere().log(
|
||||
"The lock we acquired was transferred to someone else before we"
|
||||
@@ -294,11 +342,12 @@ public class Lock extends ImmutableObject implements DatastoreAndSqlEntity, Seri
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// In ofy, backup is determined per-action, but in SQL it's determined per-transaction
|
||||
if (tm().isOfy()) {
|
||||
tm().transact(lockReleaser);
|
||||
if (transactionManager.isOfy()) {
|
||||
transactionManager.transact(lockReleaser);
|
||||
} else {
|
||||
jpaTm().transactWithoutBackup(lockReleaser);
|
||||
((JpaTransactionManager) transactionManager).transactWithoutBackup(lockReleaser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.googlecode.objectify.annotation.Parent;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.InCrossTld;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
@@ -88,7 +89,8 @@ import org.joda.time.Duration;
|
||||
@Entity
|
||||
@javax.persistence.Entity(name = "Tld")
|
||||
@InCrossTld
|
||||
public class Registry extends ImmutableObject implements Buildable, DatastoreAndSqlEntity {
|
||||
public class Registry extends ImmutableObject
|
||||
implements Buildable, DatastoreAndSqlEntity, UnsafeSerializable {
|
||||
|
||||
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||
|
||||
@@ -308,7 +310,7 @@ public class Registry extends ImmutableObject implements Buildable, DatastoreAnd
|
||||
* <p>There must be at least one entry in this set.
|
||||
*
|
||||
* <p>All entries of this list must be valid keys for the map of {@code DnsWriter}s injected by
|
||||
* <code>@Inject Map<String, DnsWriter></code>
|
||||
* {@code @Inject Map<String, DnsWriter>}
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
Set<String> dnsWriters;
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.transfer;
|
||||
|
||||
import google.registry.model.Buildable.GenericBuilder;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
@@ -27,7 +28,7 @@ import org.joda.time.DateTime;
|
||||
/** Fields common to {@link TransferData} and {@link TransferResponse}. */
|
||||
@XmlTransient
|
||||
@MappedSuperclass
|
||||
public abstract class BaseTransferObject extends ImmutableObject {
|
||||
public abstract class BaseTransferObject extends ImmutableObject implements UnsafeSerializable {
|
||||
/**
|
||||
* The status of the current or last transfer. Can be null if never transferred. Note that we
|
||||
* leave IgnoreSave off this field so that we can ensure that TransferData loaded from Objectify
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.model.common.TimedTransitionProperty;
|
||||
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
|
||||
import google.registry.persistence.converter.StringMapDescriptor.StringMap;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeConverter;
|
||||
@@ -30,7 +31,8 @@ import org.joda.time.DateTime;
|
||||
* Base JPA converter for {@link TimedTransitionProperty} objects that are stored in a column with
|
||||
* data type of hstore in the database.
|
||||
*/
|
||||
public abstract class TimedTransitionPropertyConverterBase<K, V extends TimedTransition<K>>
|
||||
public abstract class TimedTransitionPropertyConverterBase<
|
||||
K extends Serializable, V extends TimedTransition<K>>
|
||||
implements AttributeConverter<TimedTransitionProperty<K, V>, StringMap> {
|
||||
|
||||
abstract Map.Entry<String, String> convertToDatabaseMapEntry(Map.Entry<DateTime, V> entry);
|
||||
|
||||
@@ -22,8 +22,8 @@ import org.joda.time.Duration;
|
||||
/**
|
||||
* Code execution locked on some shared resource.
|
||||
*
|
||||
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of
|
||||
* null is used.
|
||||
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of null
|
||||
* is used.
|
||||
*/
|
||||
public interface LockHandler extends Serializable {
|
||||
|
||||
@@ -42,4 +42,22 @@ public interface LockHandler extends Serializable {
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames);
|
||||
|
||||
/**
|
||||
* Acquire one or more locks using only Cloud SQL and execute a Void {@link Callable}.
|
||||
*
|
||||
* <p>Runs on a thread that will be killed if it doesn't complete before the lease expires.
|
||||
*
|
||||
* <p>Note that locks are specific either to a given tld or to the entire system (in which case
|
||||
* tld should be passed as null).
|
||||
*
|
||||
* <p>This method exists so that Beam pipelines can acquire / load / release locks.
|
||||
*
|
||||
* @return true if all locks were acquired and the callable was run; false otherwise.
|
||||
*/
|
||||
boolean executeWithSqlLocks(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames);
|
||||
}
|
||||
|
||||
@@ -73,12 +73,42 @@ public class LockHandlerImpl implements LockHandler {
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames) {
|
||||
return executeWithLockAcquirer(callable, tld, leaseLength, this::acquire, lockNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire one or more locks using only Cloud SQL and execute a Void {@link Callable}.
|
||||
*
|
||||
* <p>Thread will be killed if it doesn't complete before the lease expires.
|
||||
*
|
||||
* <p>Note that locks are specific either to a given tld or to the entire system (in which case
|
||||
* tld should be passed as null).
|
||||
*
|
||||
* <p>This method exists so that Beam pipelines can acquire / load / release locks.
|
||||
*
|
||||
* @return whether all locks were acquired and the callable was run.
|
||||
*/
|
||||
@Override
|
||||
public boolean executeWithSqlLocks(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames) {
|
||||
return executeWithLockAcquirer(callable, tld, leaseLength, this::acquireSql, lockNames);
|
||||
}
|
||||
|
||||
private boolean executeWithLockAcquirer(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
LockAcquirer lockAcquirer,
|
||||
String... lockNames) {
|
||||
DateTime startTime = clock.nowUtc();
|
||||
String sanitizedTld = Strings.emptyToNull(tld);
|
||||
try {
|
||||
return AppEngineTimeLimiter.create()
|
||||
.callWithTimeout(
|
||||
new LockingCallable(callable, sanitizedTld, leaseLength, lockNames),
|
||||
new LockingCallable(callable, lockAcquirer, sanitizedTld, leaseLength, lockNames),
|
||||
leaseLength.minus(LOCK_TIMEOUT_FUDGE).getMillis(),
|
||||
TimeUnit.MILLISECONDS);
|
||||
} catch (ExecutionException | UncheckedExecutionException e) {
|
||||
@@ -108,17 +138,32 @@ public class LockHandlerImpl implements LockHandler {
|
||||
return Lock.acquire(lockName, tld, leaseLength, requestStatusChecker, true);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Optional<Lock> acquireSql(String lockName, @Nullable String tld, Duration leaseLength) {
|
||||
return Lock.acquireSql(lockName, tld, leaseLength, requestStatusChecker, true);
|
||||
}
|
||||
|
||||
private interface LockAcquirer {
|
||||
Optional<Lock> acquireLock(String lockName, @Nullable String tld, Duration leaseLength);
|
||||
}
|
||||
|
||||
/** A {@link Callable} that acquires and releases a lock around a delegate {@link Callable}. */
|
||||
private class LockingCallable implements Callable<Boolean> {
|
||||
private static class LockingCallable implements Callable<Boolean> {
|
||||
final Callable<Void> delegate;
|
||||
final LockAcquirer lockAcquirer;
|
||||
@Nullable final String tld;
|
||||
final Duration leaseLength;
|
||||
final Set<String> lockNames;
|
||||
|
||||
LockingCallable(
|
||||
Callable<Void> delegate, String tld, Duration leaseLength, String... lockNames) {
|
||||
Callable<Void> delegate,
|
||||
LockAcquirer lockAcquirer,
|
||||
String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames) {
|
||||
checkArgument(leaseLength.isLongerThan(LOCK_TIMEOUT_FUDGE));
|
||||
this.delegate = delegate;
|
||||
this.lockAcquirer = lockAcquirer;
|
||||
this.tld = tld;
|
||||
this.leaseLength = leaseLength;
|
||||
// Make sure we join locks in a fixed (lexicographical) order to avoid deadlock.
|
||||
@@ -130,7 +175,7 @@ public class LockHandlerImpl implements LockHandler {
|
||||
Set<Lock> acquiredLocks = new HashSet<>();
|
||||
try {
|
||||
for (String lockName : lockNames) {
|
||||
Optional<Lock> lock = acquire(lockName, tld, leaseLength);
|
||||
Optional<Lock> lock = lockAcquirer.acquireLock(lockName, tld, leaseLength);
|
||||
if (!lock.isPresent()) {
|
||||
logger.atInfo().log("Couldn't acquire lock named: %s for TLD %s.", lockName, tld);
|
||||
return false;
|
||||
|
||||
@@ -34,6 +34,7 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -111,6 +112,7 @@ public class ReplayCommitLogsToSqlActionTest {
|
||||
DelegationSignerData.class,
|
||||
DomainBase.class,
|
||||
GracePeriod.class,
|
||||
Lock.class,
|
||||
PremiumList.class,
|
||||
PremiumEntry.class,
|
||||
RegistrarContact.class,
|
||||
@@ -135,6 +137,7 @@ public class ReplayCommitLogsToSqlActionTest {
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
inject.setStaticField(Ofy.class, "clock", fakeClock);
|
||||
lenient().when(requestStatusChecker.getLogId()).thenReturn("requestLogId");
|
||||
action.gcsUtils = gcsUtils;
|
||||
action.response = response;
|
||||
action.requestStatusChecker = requestStatusChecker;
|
||||
@@ -464,9 +467,10 @@ public class ReplayCommitLogsToSqlActionTest {
|
||||
}
|
||||
});
|
||||
runAndAssertSuccess(now.minusMinutes(1), 1, 1);
|
||||
// jpaTm()::putIgnoringReadOnly should only have been called with the checkpoint
|
||||
// jpaTm()::putIgnoringReadOnly should only have been called with the checkpoint and the lock
|
||||
verify(spy, times(2)).putIgnoringReadOnly(any(SqlReplayCheckpoint.class));
|
||||
verify(spy, times(2)).putIgnoringReadOnly(any());
|
||||
verify(spy).putIgnoringReadOnly(any(Lock.class));
|
||||
verify(spy, times(3)).putIgnoringReadOnly(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -506,7 +510,7 @@ public class ReplayCommitLogsToSqlActionTest {
|
||||
@Test
|
||||
void testFailure_cannotAcquireLock() {
|
||||
Truth8.assertThat(
|
||||
Lock.acquire(
|
||||
Lock.acquireSql(
|
||||
ReplayCommitLogsToSqlAction.class.getSimpleName(),
|
||||
null,
|
||||
Duration.standardHours(1),
|
||||
|
||||
@@ -838,14 +838,19 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response_pending.xml"));
|
||||
|
||||
HistoryEntry deleteHistoryEntry = getOnlyHistoryEntryOfType(domain, DOMAIN_DELETE);
|
||||
DateTime now = clock.nowUtc();
|
||||
assertPollMessages(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setParent(deleteHistoryEntry)
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setEventTime(now)
|
||||
.setMsg(
|
||||
"Domain example.tld was deleted by registry administrator with final deletion"
|
||||
+ " effective: 2000-07-11T22:00:00.013Z")
|
||||
.setResponseData(
|
||||
ImmutableList.of(
|
||||
DomainPendingActionNotificationResponse.create(
|
||||
"example.tld", true, deleteHistoryEntry.getTrid(), now)))
|
||||
.build(),
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
|
||||
@@ -156,6 +156,30 @@ class PollRequestFlowTest extends FlowTestCase<PollRequestFlow> {
|
||||
runFlowAssertResponse(loadFile("poll_response_domain_pending_notification.xml"));
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testSuccess_domainPendingActionImmediateDelete() throws Exception {
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId(getRegistrarIdForFlow())
|
||||
.setEventTime(clock.nowUtc())
|
||||
.setMsg(
|
||||
String.format(
|
||||
"Domain %s was deleted by registry administrator with final deletion"
|
||||
+ " effective: %s",
|
||||
domain.getDomainName(), clock.nowUtc().minusMinutes(5)))
|
||||
.setResponseData(
|
||||
ImmutableList.of(
|
||||
DomainPendingActionNotificationResponse.create(
|
||||
domain.getDomainName(),
|
||||
true,
|
||||
Trid.create("ABC-12345", "other-trid"),
|
||||
clock.nowUtc())))
|
||||
.setParent(createHistoryEntryForEppResource(domain))
|
||||
.build());
|
||||
assertTransactionalFlow(false);
|
||||
runFlowAssertResponse(loadFile("poll_message_domain_pending_action_immediate_delete.xml"));
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testSuccess_domainAutorenewMessage() throws Exception {
|
||||
persistResource(
|
||||
|
||||
@@ -25,6 +25,7 @@ import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.SerializeUtils.serializeDeserialize;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -46,6 +47,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.DateTimeUtils;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -195,6 +197,20 @@ public class BillingEventTest extends EntityTestCase {
|
||||
ofyTmOrDoNothing(() -> assertThat(tm().loadByEntity(modification)).isEqualTo(modification));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
BillingEvent persisted = loadByEntity(oneTime);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(oneTimeSynthetic);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(recurring);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(cancellationOneTime);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
persisted = loadByEntity(cancellationRecurring);
|
||||
assertThat(serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testParenting() {
|
||||
// Note that these are all tested separately because BillingEvent is an abstract base class that
|
||||
|
||||
@@ -30,6 +30,8 @@ import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -46,6 +48,15 @@ public class CursorTest extends EntityTestCase {
|
||||
fakeClock.setTo(DateTime.parse("2010-10-17TZ"));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
final DateTime time = DateTime.parse("2012-07-12T03:30:00.000Z");
|
||||
tm().transact(() -> tm().put(Cursor.createGlobal(RECURRING_BILLING, time)));
|
||||
Cursor persisted =
|
||||
tm().transact(() -> tm().loadByKey(Cursor.createGlobalVKey(RECURRING_BILLING)));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testSuccess_persistScopedCursor() {
|
||||
createTld("tld");
|
||||
|
||||
@@ -48,6 +48,7 @@ import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/** Unit tests for {@link ContactResource}. */
|
||||
@@ -174,6 +175,14 @@ public class ContactResourceTest extends EntityTestCase {
|
||||
.hasValue(contactResource);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ContactResource persisted =
|
||||
loadByForeignKey(ContactResource.class, contactResource.getForeignKey(), fakeClock.nowUtc())
|
||||
.get();
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
verifyDatastoreIndexing(
|
||||
|
||||
@@ -56,6 +56,7 @@ import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.util.Arrays;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -354,6 +355,14 @@ public class DomainBaseSqlTest {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
createTld("com");
|
||||
insertInDb(contact, contact2, domain, host);
|
||||
DomainBase persisted = jpaTm().transact(() -> jpaTm().loadByEntity(domain));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testUpdates() {
|
||||
createTld("com");
|
||||
|
||||
@@ -41,6 +41,8 @@ import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -93,6 +95,44 @@ public class AllocationTokenTest extends EntityTestCase {
|
||||
assertThat(loadByEntity(singleUseToken)).isEqualTo(singleUseToken);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
AllocationToken unlimitedUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123Unlimited")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setAllowedTlds(ImmutableSet.of("dev", "app"))
|
||||
.setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar, NewRegistrar"))
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountPremiums(true)
|
||||
.setDiscountYears(3)
|
||||
.setTokenStatusTransitions(
|
||||
ImmutableSortedMap.<DateTime, TokenStatus>naturalOrder()
|
||||
.put(START_OF_TIME, NOT_STARTED)
|
||||
.put(DateTime.now(UTC), TokenStatus.VALID)
|
||||
.put(DateTime.now(UTC).plusWeeks(8), TokenStatus.ENDED)
|
||||
.build())
|
||||
.build());
|
||||
AllocationToken persisted = loadByEntity(unlimitedUseToken);
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
|
||||
DomainBase domain = persistActiveDomain("example.foo");
|
||||
Key<HistoryEntry> historyEntryKey = Key.create(Key.create(domain), HistoryEntry.class, 1);
|
||||
AllocationToken singleUseToken =
|
||||
persistResource(
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123Single")
|
||||
.setRedemptionHistoryEntry(HistoryEntry.createVKey(historyEntryKey))
|
||||
.setDomainName("example.foo")
|
||||
.setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z"))
|
||||
.setTokenType(SINGLE_USE)
|
||||
.build());
|
||||
persisted = loadByEntity(singleUseToken);
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
DomainBase domain = persistActiveDomain("blahdomain.foo");
|
||||
|
||||
@@ -39,6 +39,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
|
||||
/** Tests for {@link ContactHistory}. */
|
||||
@DualDatabaseTest
|
||||
@@ -64,6 +65,18 @@ public class ContactHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
insertInDb(contact);
|
||||
ContactResource contactFromDb = loadByEntity(contact);
|
||||
ContactHistory contactHistory = createContactHistory(contactFromDb);
|
||||
insertInDb(contactHistory);
|
||||
ContactHistory fromDatabase =
|
||||
jpaTm().transact(() -> jpaTm().loadByKey(contactHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullContactBase() {
|
||||
ContactResource contact = newContactResourceWithRoid("contactId", "contact1");
|
||||
|
||||
@@ -55,6 +55,7 @@ import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -87,6 +88,16 @@ public class DomainHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
|
||||
DomainHistory domainHistory = createDomainHistory(domain);
|
||||
insertInDb(domainHistory);
|
||||
DomainHistory fromDatabase =
|
||||
jpaTm().transact(() -> jpaTm().loadByKey(domainHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullResource() {
|
||||
DomainBase domain = addGracePeriodForSql(createDomainWithContactsAndHosts());
|
||||
|
||||
@@ -36,6 +36,7 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
|
||||
/** Tests for {@link HostHistory}. */
|
||||
@DualDatabaseTest
|
||||
@@ -61,6 +62,17 @@ public class HostHistoryTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
insertInDb(host);
|
||||
HostResource hostFromDb = loadByEntity(host);
|
||||
HostHistory hostHistory = createHostHistory(hostFromDb);
|
||||
insertInDb(hostHistory);
|
||||
HostHistory fromDatabase = jpaTm().transact(() -> jpaTm().loadByKey(hostHistory.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(fromDatabase)).isEqualTo(fromDatabase);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testLegacyPersistence_nullHostBase() {
|
||||
HostResource host = newHostResourceWithRoid("ns1.example.com", "host1");
|
||||
|
||||
@@ -45,6 +45,8 @@ import google.registry.model.transfer.TransferStatus;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -111,6 +113,14 @@ class HostResourceTest extends EntityTestCase {
|
||||
.containsExactly(newHost);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
HostResource newHost = host.asBuilder().setRepoId("NEWHOST").build();
|
||||
tm().transact(() -> tm().insert(newHost));
|
||||
HostResource persisted = tm().transact(() -> tm().loadByEntity(newHost));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testLoadingByForeignKey() {
|
||||
assertThat(loadByForeignKey(HostResource.class, host.getForeignKey(), fakeClock.nowUtc()))
|
||||
|
||||
@@ -36,6 +36,7 @@ import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/** Unit tests for {@link PollMessage}. */
|
||||
@@ -118,6 +119,20 @@ public class PollMessageTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializableOneTime() {
|
||||
PollMessage.OneTime pollMessage =
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.build());
|
||||
PollMessage persisted = tm().transact(() -> tm().loadByEntity(pollMessage));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testPersistenceAutorenew() {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
@@ -133,6 +148,22 @@ public class PollMessageTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByEntity(pollMessage))).isEqualTo(pollMessage);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializableAutorenew() {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
persistResource(
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setMsg("Test poll message")
|
||||
.setParent(historyEntry)
|
||||
.setAutorenewEndTime(fakeClock.nowUtc().plusDays(365))
|
||||
.setTargetId("foobar.foo")
|
||||
.build());
|
||||
PollMessage persisted = tm().transact(() -> tm().loadByEntity(pollMessage));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexingAutorenew() throws Exception {
|
||||
PollMessage.Autorenew pollMessage =
|
||||
|
||||
@@ -45,7 +45,9 @@ import google.registry.model.tld.Registries;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
@@ -135,6 +137,12 @@ class RegistrarTest extends EntityTestCase {
|
||||
assertThat(tm().transact(() -> tm().loadByKey(registrar.createVKey()))).isEqualTo(registrar);
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
Registrar persisted = tm().transact(() -> tm().loadByKey(registrar.createVKey()));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testIndexing() throws Exception {
|
||||
verifyDatastoreIndexing(registrar, "registrarName", "ianaIdentifier");
|
||||
|
||||
@@ -294,7 +294,7 @@ public class ReplicateToDatastoreActionTest {
|
||||
RequestStatusChecker requestStatusChecker = mock(RequestStatusChecker.class);
|
||||
when(requestStatusChecker.getLogId()).thenReturn("logId");
|
||||
Truth8.assertThat(
|
||||
Lock.acquire(
|
||||
Lock.acquireSql(
|
||||
ReplicateToDatastoreAction.class.getSimpleName(),
|
||||
null,
|
||||
Duration.standardHours(1),
|
||||
|
||||
@@ -20,6 +20,7 @@ import static google.registry.model.server.Lock.LockState.FREE;
|
||||
import static google.registry.model.server.Lock.LockState.IN_USE;
|
||||
import static google.registry.model.server.Lock.LockState.OWNER_DIED;
|
||||
import static google.registry.model.server.Lock.LockState.TIMED_OUT;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -28,8 +29,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.model.server.Lock.LockState;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.util.RequestStatusChecker;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.Duration;
|
||||
@@ -132,6 +135,19 @@ public class LockTest extends EntityTestCase {
|
||||
assertThat(acquire("b", ONE_DAY, IN_USE)).isEmpty();
|
||||
}
|
||||
|
||||
@TestOfyOnly
|
||||
void testSqlLock_inOfyMode() {
|
||||
Lock.lockMetrics = origLockMetrics;
|
||||
Optional<Lock> lock = Lock.acquireSql(RESOURCE_NAME, null, ONE_DAY, requestStatusChecker, true);
|
||||
assertThat(lock).isPresent();
|
||||
assertThat(DatabaseHelper.loadAllOf(Lock.class)).isEmpty();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(Lock.class))).containsExactly(lock.get());
|
||||
|
||||
lock.get().releaseSql();
|
||||
assertThat(DatabaseHelper.loadAllOf(Lock.class)).isEmpty();
|
||||
assertThat(jpaTm().transact(() -> jpaTm().loadAllOf(Lock.class))).isEmpty();
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testFailure_emptyResourceName() {
|
||||
IllegalArgumentException thrown =
|
||||
|
||||
@@ -47,6 +47,8 @@ import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.DualDatabaseTest;
|
||||
import google.registry.testing.TestOfyAndSql;
|
||||
import google.registry.testing.TestOfyOnly;
|
||||
import google.registry.testing.TestSqlOnly;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import org.joda.money.Money;
|
||||
@@ -87,6 +89,16 @@ public final class RegistryTest extends EntityTestCase {
|
||||
.isEqualTo(Registry.get("tld"));
|
||||
}
|
||||
|
||||
@TestSqlOnly
|
||||
void testSerializable() {
|
||||
ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED");
|
||||
Registry registry = Registry.get("tld").asBuilder().setReservedLists(rl15).build();
|
||||
tm().transact(() -> tm().put(registry));
|
||||
Registry persisted =
|
||||
tm().transact(() -> tm().loadByKey(Registry.createVKey(registry.tldStrId)));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
|
||||
@TestOfyAndSql
|
||||
void testFailure_registryNotFound() {
|
||||
createTld("foo");
|
||||
|
||||
@@ -40,7 +40,9 @@ final class LockHandlerImplTest {
|
||||
|
||||
private final FakeClock clock = new FakeClock(DateTime.parse("2001-08-29T12:20:00Z"));
|
||||
|
||||
@RegisterExtension final AppEngineExtension appEngine = AppEngineExtension.builder().build();
|
||||
@RegisterExtension
|
||||
final AppEngineExtension appEngine =
|
||||
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
|
||||
|
||||
private static class CountingCallable implements Callable<Void> {
|
||||
int numCalled = 0;
|
||||
@@ -69,18 +71,13 @@ final class LockHandlerImplTest {
|
||||
}
|
||||
|
||||
private boolean executeWithLocks(Callable<Void> callable, final @Nullable Lock acquiredLock) {
|
||||
LockHandlerImpl lockHandler = new LockHandlerImpl(new RequestStatusCheckerImpl(), clock) {
|
||||
private static final long serialVersionUID = 0L;
|
||||
@Override
|
||||
Optional<Lock> acquire(String resourceName, String tld, Duration leaseLength) {
|
||||
assertThat(resourceName).isEqualTo("resourceName");
|
||||
assertThat(tld).isEqualTo("tld");
|
||||
assertThat(leaseLength).isEqualTo(ONE_DAY);
|
||||
return Optional.ofNullable(acquiredLock);
|
||||
}
|
||||
};
|
||||
return createTestLockHandler(acquiredLock)
|
||||
.executeWithLocks(callable, "tld", ONE_DAY, "resourceName");
|
||||
}
|
||||
|
||||
return lockHandler.executeWithLocks(callable, "tld", ONE_DAY, "resourceName");
|
||||
private boolean executeWithSqlLocks(Callable<Void> callable, final @Nullable Lock acquiredLock) {
|
||||
return createTestLockHandler(acquiredLock)
|
||||
.executeWithSqlLocks(callable, "tld", ONE_DAY, "resourceName");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,6 +89,15 @@ final class LockHandlerImplTest {
|
||||
verify(lock, times(1)).release();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSqlLockSucceeds() {
|
||||
Lock lock = mock(Lock.class);
|
||||
CountingCallable countingCallable = new CountingCallable();
|
||||
assertThat(executeWithSqlLocks(countingCallable, lock)).isTrue();
|
||||
assertThat(countingCallable.numCalled).isEqualTo(1);
|
||||
verify(lock, times(1)).release();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLockSucceeds_uncheckedException() {
|
||||
Lock lock = mock(Lock.class);
|
||||
@@ -140,4 +146,23 @@ final class LockHandlerImplTest {
|
||||
assertThat(executeWithLocks(countingCallable, lock)).isFalse();
|
||||
assertThat(countingCallable.numCalled).isEqualTo(0);
|
||||
}
|
||||
|
||||
private LockHandler createTestLockHandler(@Nullable Lock acquiredLock) {
|
||||
return new LockHandlerImpl(new RequestStatusCheckerImpl(), clock) {
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
@Override
|
||||
Optional<Lock> acquire(String resourceName, String tld, Duration leaseLength) {
|
||||
assertThat(resourceName).isEqualTo("resourceName");
|
||||
assertThat(tld).isEqualTo("tld");
|
||||
assertThat(leaseLength).isEqualTo(ONE_DAY);
|
||||
return Optional.ofNullable(acquiredLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
Optional<Lock> acquireSql(String resourceName, String tld, Duration leaseLength) {
|
||||
return acquire(resourceName, tld, leaseLength);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.schema.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.registrar.RegistrarContact.Type.WHOIS;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadByEntity;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
@@ -27,6 +28,7 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.DatastoreEntityExtension;
|
||||
import google.registry.testing.TmOverrideExtension;
|
||||
import google.registry.util.SerializeUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -74,4 +76,11 @@ class RegistrarContactTest {
|
||||
insertInDb(testRegistrarPoc);
|
||||
assertThat(loadByEntity(testRegistrarPoc)).isEqualTo(testRegistrarPoc);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSerializable_succeeds() {
|
||||
insertInDb(testRegistrarPoc);
|
||||
RegistrarContact persisted = jpaTm().transact(() -> jpaTm().loadByEntity(testRegistrarPoc));
|
||||
assertThat(SerializeUtils.serializeDeserialize(persisted)).isEqualTo(persisted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ public class FakeLockHandler implements LockHandler {
|
||||
|
||||
private static final long serialVersionUID = 6437880915118738492L;
|
||||
|
||||
boolean lockSucceeds;
|
||||
private final boolean lockSucceeds;
|
||||
|
||||
/**
|
||||
* @param lockSucceeds if true - the lock acquisition will succeed and the callable will be
|
||||
* called. If false, lock acquisition will fail and the caller isn't called.
|
||||
* called. If false, lock acquisition will fail and the caller isn't called.
|
||||
*/
|
||||
public FakeLockHandler(boolean lockSucceeds) {
|
||||
this.lockSucceeds = lockSucceeds;
|
||||
@@ -38,10 +38,17 @@ public class FakeLockHandler implements LockHandler {
|
||||
|
||||
@Override
|
||||
public boolean executeWithLocks(
|
||||
final Callable<Void> callable,
|
||||
@Nullable String tld,
|
||||
Duration leaseLength,
|
||||
String... lockNames) {
|
||||
Callable<Void> callable, @Nullable String tld, Duration leaseLength, String... lockNames) {
|
||||
return execute(callable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeWithSqlLocks(
|
||||
Callable<Void> callable, @Nullable String tld, Duration leaseLength, String... lockNames) {
|
||||
return execute(callable);
|
||||
}
|
||||
|
||||
private boolean execute(Callable<Void> callable) {
|
||||
if (!lockSucceeds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<epp xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xmlns:fee="urn:ietf:params:xml:ns:fee-0.6" xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:fee11="urn:ietf:params:xml:ns:fee-0.11" xmlns:fee12="urn:ietf:params:xml:ns:fee-0.12" xmlns:launch="urn:ietf:params:xml:ns:launch-1.0" xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1" xmlns:host="urn:ietf:params:xml:ns:host-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<qDate>2011-01-02T01:01:01Z</qDate>
|
||||
<msg>Domain test.example was deleted by registry administrator with final deletion effective: 2011-01-02T00:56:01.009Z</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:panData>
|
||||
<domain:name paResult="1">test.example</domain:name>
|
||||
<domain:paTRID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>other-trid</svTRID>
|
||||
</domain:paTRID>
|
||||
<domain:paDate>2011-01-02T01:01:01Z</domain:paDate>
|
||||
</domain:panData>
|
||||
</resData>
|
||||
<trID>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
<svTRID>server-trid</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
||||
|
||||
+3
-2
@@ -105,13 +105,14 @@ mentioned above.
|
||||
|
||||
Navigate to `proxy/terraform`, create a folder called
|
||||
`envs`, and inside it, create a folder for the environment that proxy is
|
||||
deployed to ("alpha" for example). Copy `example_config.tf` to the environment
|
||||
folder.
|
||||
deployed to ("alpha" for example). Copy `example_config.tf` and `outputs.tf`
|
||||
to the environment folder.
|
||||
|
||||
```bash
|
||||
$ cd proxy/terraform
|
||||
$ mkdir -p envs/alpha
|
||||
$ cp example_config.tf envs/alpha/config.tf
|
||||
$ cp outputs.tf envs/alpha
|
||||
```
|
||||
|
||||
Now go to the environment folder, edit the `config.tf` file and replace
|
||||
|
||||
@@ -11,21 +11,8 @@ module "proxy" {
|
||||
proxy_project_name = "YOUR_PROXY_PROJECT"
|
||||
gcr_project_name = "YOUR_GCR_PROJECT"
|
||||
proxy_domain_name = "YOUR_PROXY_DOMAIN"
|
||||
proxy_certificate_bucket = "YOU_CERTIFICATE_BUCKET"
|
||||
}
|
||||
proxy_certificate_bucket = "YOUR_CERTIFICATE_BUCKET"
|
||||
|
||||
output "proxy_service_account" {
|
||||
value = module.proxy.proxy_service_account
|
||||
}
|
||||
|
||||
output "proxy_name_servers" {
|
||||
value = module.proxy.proxy_name_servers
|
||||
}
|
||||
|
||||
output "proxy_instance_groups" {
|
||||
value = module.proxy.proxy_instance_groups
|
||||
}
|
||||
|
||||
output "proxy_ip_addresses" {
|
||||
value = module.proxy.proxy_ip_addresses
|
||||
# Uncomment to disable forwarding of whois HTTP interfaces.
|
||||
# public_web_whois = 0
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
resource "google_dns_managed_zone" "proxy_domain" {
|
||||
name = "proxy-domain"
|
||||
dns_name = "${var.proxy_domain_name}."
|
||||
|
||||
# This is a safeguard for the google provider update to 2.8.0.
|
||||
# cl/264641943
|
||||
# If you like, you can remove this line after the update.
|
||||
lifecycle { prevent_destroy = true }
|
||||
}
|
||||
|
||||
module "proxy_networking" {
|
||||
@@ -14,6 +9,7 @@ module "proxy_networking" {
|
||||
proxy_ports = var.proxy_ports
|
||||
proxy_domain = google_dns_managed_zone.proxy_domain.name
|
||||
proxy_domain_name = google_dns_managed_zone.proxy_domain.dns_name
|
||||
public_web_whois = var.public_web_whois
|
||||
}
|
||||
|
||||
module "proxy_networking_canary" {
|
||||
@@ -23,4 +19,5 @@ module "proxy_networking_canary" {
|
||||
proxy_ports = var.proxy_ports_canary
|
||||
proxy_domain = google_dns_managed_zone.proxy_domain.name
|
||||
proxy_domain_name = google_dns_managed_zone.proxy_domain.dns_name
|
||||
public_web_whois = var.public_web_whois
|
||||
}
|
||||
|
||||
@@ -206,6 +206,7 @@ resource "google_compute_global_forwarding_rule" "https_whois_ipv4_forwarding_ru
|
||||
ip_address = google_compute_global_address.proxy_ipv4_address.address
|
||||
target = google_compute_target_tcp_proxy.https_whois_tcp_proxy.self_link
|
||||
port_range = "443"
|
||||
count = var.public_web_whois
|
||||
}
|
||||
|
||||
resource "google_compute_global_forwarding_rule" "https_whois_ipv6_forwarding_rule" {
|
||||
@@ -213,6 +214,7 @@ resource "google_compute_global_forwarding_rule" "https_whois_ipv6_forwarding_ru
|
||||
ip_address = google_compute_global_address.proxy_ipv6_address.address
|
||||
target = google_compute_target_tcp_proxy.https_whois_tcp_proxy.self_link
|
||||
port_range = "443"
|
||||
count = var.public_web_whois
|
||||
}
|
||||
|
||||
resource "google_compute_global_forwarding_rule" "http_whois_ipv4_forwarding_rule" {
|
||||
@@ -220,6 +222,7 @@ resource "google_compute_global_forwarding_rule" "http_whois_ipv4_forwarding_rul
|
||||
ip_address = google_compute_global_address.proxy_ipv4_address.address
|
||||
target = google_compute_target_http_proxy.http_whois_http_proxy.self_link
|
||||
port_range = "80"
|
||||
count = var.public_web_whois
|
||||
}
|
||||
|
||||
resource "google_compute_global_forwarding_rule" "http_whois_ipv6_forwarding_rule" {
|
||||
@@ -227,4 +230,5 @@ resource "google_compute_global_forwarding_rule" "http_whois_ipv6_forwarding_rul
|
||||
ip_address = google_compute_global_address.proxy_ipv6_address.address
|
||||
target = google_compute_target_http_proxy.http_whois_http_proxy.self_link
|
||||
port_range = "80"
|
||||
count = var.public_web_whois
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
# Instance groups that the load balancer forwards traffic to.
|
||||
variable "proxy_instance_groups" {
|
||||
type = map
|
||||
type = map
|
||||
description = "Instance groups that the load balancer forwards traffic to."
|
||||
}
|
||||
|
||||
# Suffix (such as "-canary") added to the resource names.
|
||||
variable "suffix" {
|
||||
default = ""
|
||||
default = ""
|
||||
description = "Suffix (such as '-canary') added to the resource names."
|
||||
}
|
||||
|
||||
# Node ports exposed by the proxy.
|
||||
variable "proxy_ports" {
|
||||
type = map
|
||||
type = map
|
||||
description = "Node ports exposed by the proxy."
|
||||
}
|
||||
|
||||
# DNS zone for the proxy domain.
|
||||
variable "proxy_domain" {}
|
||||
variable "proxy_domain" {
|
||||
description = "DNS zone for the proxy domain."
|
||||
}
|
||||
|
||||
# domain name of the zone.
|
||||
variable "proxy_domain_name" {}
|
||||
variable "proxy_domain_name" {
|
||||
description = "Domain name of the zone."
|
||||
}
|
||||
|
||||
variable "public_web_whois" {
|
||||
type = number
|
||||
description = <<EOF
|
||||
Set to 1 if the whois HTTP ports are external, 0 if not. This is necessary
|
||||
because our test projects are configured with
|
||||
constraints/compute.restrictLoadBalancerCreationForTypes, which prohibits
|
||||
forwarding external HTTP(s) connections.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -1,28 +1,37 @@
|
||||
# GCP project in which the proxy runs.
|
||||
variable "proxy_project_name" {}
|
||||
variable "proxy_project_name" {
|
||||
description = "GCP project in which the proxy runs."
|
||||
}
|
||||
|
||||
# GCP project from which the proxy image is pulled.
|
||||
variable "gcr_project_name" {}
|
||||
variable "gcr_project_name" {
|
||||
description = "GCP project from which the proxy image is pulled."
|
||||
}
|
||||
|
||||
# The base domain name of the proxy, without the whois. or epp. part.
|
||||
variable "proxy_domain_name" {}
|
||||
variable "proxy_domain_name" {
|
||||
description = <<EOF
|
||||
The base domain name of the proxy, without the whois. or epp. part.
|
||||
EOF
|
||||
}
|
||||
|
||||
# The GCS bucket that stores the encrypted SSL certificate.
|
||||
variable "proxy_certificate_bucket" {}
|
||||
variable "proxy_certificate_bucket" {
|
||||
description = <<EOF
|
||||
The GCS bucket that stores the encrypted SSL certificate. The "gs://"
|
||||
prefix should be omitted.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Cloud KMS keyring name
|
||||
variable "proxy_key_ring" {
|
||||
default = "proxy-key-ring"
|
||||
default = "proxy-key-ring"
|
||||
description = "Cloud KMS keyring name"
|
||||
}
|
||||
|
||||
# Cloud KMS key name
|
||||
variable "proxy_key" {
|
||||
default = "proxy-key"
|
||||
default = "proxy-key"
|
||||
description = "Cloud KMS key name"
|
||||
}
|
||||
|
||||
# Node ports exposed by the proxy.
|
||||
variable "proxy_ports" {
|
||||
type = map
|
||||
type = map
|
||||
description = "Node ports exposed by the proxy."
|
||||
|
||||
default = {
|
||||
health_check = 30000
|
||||
@@ -33,9 +42,9 @@ variable "proxy_ports" {
|
||||
}
|
||||
}
|
||||
|
||||
# Node ports exposed by the canary proxy.
|
||||
variable "proxy_ports_canary" {
|
||||
type = map
|
||||
type = map
|
||||
description = "Node ports exposed by the canary proxy."
|
||||
|
||||
default = {
|
||||
health_check = 31000
|
||||
@@ -45,3 +54,14 @@ variable "proxy_ports_canary" {
|
||||
https-whois = 31011
|
||||
}
|
||||
}
|
||||
|
||||
variable "public_web_whois" {
|
||||
type = number
|
||||
default = 1
|
||||
description = <<EOF
|
||||
Set to 1 if the whois HTTP ports are external, 0 if not. This is necessary
|
||||
because our test projects are configured with
|
||||
constraints/compute.restrictLoadBalancerCreationForTypes, which prohibits
|
||||
forwarding external HTTP(s) connections.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
output "proxy_service_account" {
|
||||
value = module.proxy.proxy_service_account
|
||||
description = "Service account the proxy runs under."
|
||||
}
|
||||
|
||||
output "proxy_name_servers" {
|
||||
value = module.proxy.proxy_name_servers
|
||||
description = "Name servers for the proxy's domain."
|
||||
}
|
||||
|
||||
output "proxy_instance_groups" {
|
||||
value = module.proxy.proxy_instance_groups
|
||||
description = <<EOF
|
||||
The name of the GCE instance group backing up the proxy's cluster.
|
||||
EOF
|
||||
}
|
||||
|
||||
output "proxy_ip_addresses" {
|
||||
value = module.proxy.proxy_ip_addresses
|
||||
description = "The proxy IP addresses."
|
||||
}
|
||||
@@ -65,5 +65,10 @@ public final class SerializeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Serializes an object then deserializes it. This is typically used in tests. */
|
||||
public static Object serializeDeserialize(Object object) {
|
||||
return deserialize(Object.class, serialize(object));
|
||||
}
|
||||
|
||||
private SerializeUtils() {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user