mirror of
https://github.com/google/nomulus.git
synced 2025-05-22 20:29:36 +02:00
Change primary key of DelegationSignerData and add its history table (#841)
* Change primary key of DelegationSignerData and add its history table * Change primary key and resolve comments * Rebase on HEAD
This commit is contained in:
parent
2000ea2d60
commit
b8d913ef64
14 changed files with 4405 additions and 3505 deletions
|
@ -14,14 +14,17 @@
|
|||
|
||||
package google.registry.model.domain;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.domain.secdns.DomainDsDataHistory;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
|
@ -40,10 +43,12 @@ import javax.persistence.CascadeType;
|
|||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinColumns;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PostLoad;
|
||||
|
@ -95,6 +100,24 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
|||
@Column(name = "host_repo_id")
|
||||
Set<VKey<HostResource>> nsHosts;
|
||||
|
||||
@OneToMany(
|
||||
cascade = {CascadeType.ALL},
|
||||
fetch = FetchType.EAGER,
|
||||
orphanRemoval = true)
|
||||
@JoinColumns({
|
||||
@JoinColumn(
|
||||
name = "domainHistoryRevisionId",
|
||||
referencedColumnName = "historyRevisionId",
|
||||
insertable = false,
|
||||
updatable = false),
|
||||
@JoinColumn(
|
||||
name = "domainRepoId",
|
||||
referencedColumnName = "domainRepoId",
|
||||
insertable = false,
|
||||
updatable = false)
|
||||
})
|
||||
Set<DomainDsDataHistory> dsDataHistories;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@Access(AccessType.PROPERTY)
|
||||
|
@ -162,6 +185,11 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
|||
return nsHosts;
|
||||
}
|
||||
|
||||
/** Returns the collection of {@link DomainDsDataHistory} instances. */
|
||||
public ImmutableSet<DomainDsDataHistory> getDsDataHistories() {
|
||||
return nullToEmptyImmutableCopy(dsDataHistories);
|
||||
}
|
||||
|
||||
/**
|
||||
* The values of all the fields on the {@link DomainContent} object after the action represented
|
||||
* by this history object was executed.
|
||||
|
@ -278,9 +306,6 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
|||
|
||||
public Builder setDomainContent(DomainContent domainContent) {
|
||||
getInstance().domainContent = domainContent;
|
||||
if (domainContent != null) {
|
||||
getInstance().nsHosts = nullToEmptyImmutableCopy(domainContent.nsHosts);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -288,5 +313,22 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
|||
getInstance().parent = Key.create(DomainBase.class, domainRepoId);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainHistory build() {
|
||||
DomainHistory instance = super.build();
|
||||
// TODO(b/171990736): Assert instance.domainContent is not null after database migration.
|
||||
// Note that we cannot assert that instance.domainContent is not null here because this
|
||||
// builder is also used to convert legacy HistoryEntry objects to DomainHistory, when
|
||||
// domainContent is not available.
|
||||
if (instance.domainContent != null) {
|
||||
instance.nsHosts = nullToEmptyImmutableCopy(instance.domainContent.nsHosts);
|
||||
instance.dsDataHistories =
|
||||
nullToEmptyImmutableCopy(instance.domainContent.getDsData()).stream()
|
||||
.map(dsData -> DomainDsDataHistory.createFrom(instance.id, dsData))
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,89 +17,68 @@ package google.registry.model.domain.secdns;
|
|||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData.DelegationSignerDataId;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData.DomainDsDataId;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
/**
|
||||
* Holds the data necessary to construct a single Delegation Signer (DS) record for a domain.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5910">RFC 5910</a>
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034">RFC 4034</a>
|
||||
* <p>TODO(shicong): Rename this class to DomainDsData.
|
||||
*/
|
||||
@Embed
|
||||
@XmlType(name = "dsData")
|
||||
@Entity
|
||||
@IdClass(DomainDsDataId.class)
|
||||
@Table(indexes = @Index(columnList = "domainRepoId"))
|
||||
@IdClass(DelegationSignerDataId.class)
|
||||
public class DelegationSignerData extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
public class DelegationSignerData extends DomainDsDataBase {
|
||||
|
||||
private DelegationSignerData() {}
|
||||
|
||||
@Ignore @XmlTransient @javax.persistence.Id String domainRepoId;
|
||||
|
||||
/** The identifier for this particular key in the domain. */
|
||||
@javax.persistence.Id
|
||||
@Column(nullable = false)
|
||||
int keyTag;
|
||||
|
||||
/**
|
||||
* The algorithm used by this key.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#appendix-A.1">RFC 4034 Appendix A.1</a>
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
@XmlElement(name = "alg")
|
||||
int algorithm;
|
||||
|
||||
/**
|
||||
* The algorithm used to generate the digest.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#appendix-A.2">RFC 4034 Appendix A.2</a>
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
int digestType;
|
||||
|
||||
/**
|
||||
* The hexBinary digest of the public key.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#section-5.1.4">RFC 4034 Section 5.1.4</a>
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
@XmlJavaTypeAdapter(HexBinaryAdapter.class)
|
||||
byte[] digest;
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public String getDomainRepoId() {
|
||||
return super.getDomainRepoId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getKeyTag() {
|
||||
return keyTag;
|
||||
return super.getKeyTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getAlgorithm() {
|
||||
return algorithm;
|
||||
return super.getAlgorithm();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getDigestType() {
|
||||
return digestType;
|
||||
return super.getDigestType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
public byte[] getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
public String getDigestAsString() {
|
||||
return digest == null ? "" : DatatypeConverter.printHexBinary(digest);
|
||||
return super.getDigest();
|
||||
}
|
||||
|
||||
public DelegationSignerData cloneWithDomainRepoId(String domainRepoId) {
|
||||
|
@ -135,30 +114,135 @@ public class DelegationSignerData extends ImmutableObject implements DatastoreAn
|
|||
return create(keyTag, algorithm, digestType, DatatypeConverter.parseHexBinary(digestAsHex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presentation format of this DS record.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc4034#section-5.3">RFC 4034 Section 5.3</a>
|
||||
*/
|
||||
public String toRrData() {
|
||||
return String.format(
|
||||
"%d %d %d %s",
|
||||
this.keyTag, this.algorithm, this.digestType, DatatypeConverter.printHexBinary(digest));
|
||||
}
|
||||
/** Class to represent the composite primary key of {@link DelegationSignerData} entity. */
|
||||
static class DomainDsDataId extends ImmutableObject implements Serializable {
|
||||
|
||||
static class DelegationSignerDataId extends ImmutableObject implements Serializable {
|
||||
String domainRepoId;
|
||||
|
||||
int keyTag;
|
||||
|
||||
private DelegationSignerDataId() {}
|
||||
int algorithm;
|
||||
|
||||
private DelegationSignerDataId(String domainRepoId, int keyTag) {
|
||||
int digestType;
|
||||
|
||||
byte[] digest;
|
||||
|
||||
/** Hibernate requires this default constructor. */
|
||||
private DomainDsDataId() {}
|
||||
|
||||
/** Constructs a {link DomainDsDataId} instance. */
|
||||
DomainDsDataId(String domainRepoId, int keyTag, int algorithm, int digestType, byte[] digest) {
|
||||
this.domainRepoId = domainRepoId;
|
||||
this.keyTag = keyTag;
|
||||
this.algorithm = algorithm;
|
||||
this.digestType = digestType;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the domain repository ID.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private String getDomainRepoId() {
|
||||
return domainRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key tag.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int getKeyTag() {
|
||||
return keyTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the digest type.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private int getDigestType() {
|
||||
return digestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the digest.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private byte[] getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the domain repository ID.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDomainRepoId(String domainRepoId) {
|
||||
this.domainRepoId = domainRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key tag.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setKeyTag(int keyTag) {
|
||||
this.keyTag = keyTag;
|
||||
}
|
||||
|
||||
public static DelegationSignerDataId create(String domainRepoId, int keyTag) {
|
||||
return new DelegationSignerDataId(checkArgumentNotNull(domainRepoId), keyTag);
|
||||
/**
|
||||
* Sets the algorithm.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setAlgorithm(int algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the digest type.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDigestType(int digestType) {
|
||||
this.digestType = digestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the digest.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDigest(byte[] digest) {
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public static DomainDsDataId create(
|
||||
String domainRepoId, int keyTag, int algorithm, int digestType, byte[] digest) {
|
||||
return new DomainDsDataId(
|
||||
domainRepoId, keyTag, algorithm, digestType, checkArgumentNotNull(digest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.domain.secdns;
|
||||
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Transient;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
/** Base class for {@link DelegationSignerData} and {@link DomainDsDataHistory}. */
|
||||
@Embed
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
public abstract class DomainDsDataBase extends ImmutableObject implements DatastoreAndSqlEntity {
|
||||
|
||||
@Ignore @XmlTransient @Transient String domainRepoId;
|
||||
|
||||
/** The identifier for this particular key in the domain. */
|
||||
@Transient int keyTag;
|
||||
|
||||
/**
|
||||
* The algorithm used by this key.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#appendix-A.1">RFC 4034 Appendix A.1</a>
|
||||
*/
|
||||
@Transient
|
||||
@XmlElement(name = "alg")
|
||||
int algorithm;
|
||||
|
||||
/**
|
||||
* The algorithm used to generate the digest.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#appendix-A.2">RFC 4034 Appendix A.2</a>
|
||||
*/
|
||||
@Transient int digestType;
|
||||
|
||||
/**
|
||||
* The hexBinary digest of the public key.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4034#section-5.1.4">RFC 4034 Section 5.1.4</a>
|
||||
*/
|
||||
@Transient
|
||||
@XmlJavaTypeAdapter(HexBinaryAdapter.class)
|
||||
byte[] digest;
|
||||
|
||||
public String getDomainRepoId() {
|
||||
return domainRepoId;
|
||||
}
|
||||
|
||||
public int getKeyTag() {
|
||||
return keyTag;
|
||||
}
|
||||
|
||||
public int getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public int getDigestType() {
|
||||
return digestType;
|
||||
}
|
||||
|
||||
public byte[] getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the domain repository ID.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDomainRepoId(String domainRepoId) {
|
||||
this.domainRepoId = domainRepoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key tag.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setKeyTag(int keyTag) {
|
||||
this.keyTag = keyTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the algorithm.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setAlgorithm(int algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the digest type.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDigestType(int digestType) {
|
||||
this.digestType = digestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the digest.
|
||||
*
|
||||
* <p>This method is private because it is only used by Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void setDigest(byte[] digest) {
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public String getDigestAsString() {
|
||||
return digest == null ? "" : DatatypeConverter.printHexBinary(digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presentation format of this DS record.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc4034#section-5.3">RFC 4034 Section 5.3</a>
|
||||
*/
|
||||
public String toRrData() {
|
||||
return String.format(
|
||||
"%d %d %d %s",
|
||||
this.keyTag, this.algorithm, this.digestType, DatatypeConverter.printHexBinary(digest));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.domain.secdns;
|
||||
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.ofy.ObjectifyService;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/** Entity class to represent a historic {@link DelegationSignerData}. */
|
||||
@Entity
|
||||
public class DomainDsDataHistory extends DomainDsDataBase {
|
||||
|
||||
@Id Long dsDataHistoryRevisionId;
|
||||
|
||||
/** ID of the {@link DomainHistory} entity that this entity is associated with. */
|
||||
@Column(nullable = false)
|
||||
Long domainHistoryRevisionId;
|
||||
|
||||
private DomainDsDataHistory() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link DomainDsDataHistory} instance from given {@link #domainHistoryRevisionId} and
|
||||
* {@link DelegationSignerData} instance.
|
||||
*/
|
||||
public static DomainDsDataHistory createFrom(
|
||||
long domainHistoryRevisionId, DelegationSignerData dsData) {
|
||||
DomainDsDataHistory instance = new DomainDsDataHistory();
|
||||
instance.domainHistoryRevisionId = domainHistoryRevisionId;
|
||||
instance.domainRepoId = dsData.domainRepoId;
|
||||
instance.keyTag = dsData.getKeyTag();
|
||||
instance.algorithm = dsData.getAlgorithm();
|
||||
instance.digestType = dsData.getDigestType();
|
||||
instance.digest = dsData.getDigest();
|
||||
instance.dsDataHistoryRevisionId = ObjectifyService.allocateId();
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public String getDomainRepoId() {
|
||||
return super.getDomainRepoId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getKeyTag() {
|
||||
return super.getKeyTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getAlgorithm() {
|
||||
return super.getAlgorithm();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public int getDigestType() {
|
||||
return super.getDigestType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(nullable = false)
|
||||
public byte[] getDigest() {
|
||||
return super.getDigest();
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@
|
|||
<class>google.registry.model.domain.DomainHistory</class>
|
||||
<class>google.registry.model.domain.GracePeriod</class>
|
||||
<class>google.registry.model.domain.secdns.DelegationSignerData</class>
|
||||
<class>google.registry.model.domain.secdns.DomainDsDataHistory</class>
|
||||
<class>google.registry.model.domain.token.AllocationToken</class>
|
||||
<class>google.registry.model.host.HostHistory</class>
|
||||
<class>google.registry.model.host.HostResource</class>
|
||||
|
|
|
@ -34,6 +34,7 @@ import google.registry.model.domain.DomainBase;
|
|||
import google.registry.model.domain.DomainContent;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
|
@ -141,6 +142,7 @@ public class DomainHistoryTest extends EntityTestCase {
|
|||
newDomainBase("example.tld", "domainRepoId", contact)
|
||||
.asBuilder()
|
||||
.setNameservers(host.createVKey())
|
||||
.setDsData(ImmutableSet.of(DelegationSignerData.create(1, 2, 3, new byte[] {0, 1, 2})))
|
||||
.build();
|
||||
jpaTm().transact(() -> jpaTm().insert(domain));
|
||||
return domain;
|
||||
|
|
|
@ -116,7 +116,8 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
|||
// The objects will be mostly the same, but the DomainHistory object has a couple extra fields
|
||||
assertAboutImmutableObjects()
|
||||
.that(legacyHistoryEntry)
|
||||
.isEqualExceptFields(fromObjectify, "domainContent", "domainRepoId", "nsHosts");
|
||||
.isEqualExceptFields(
|
||||
fromObjectify, "domainContent", "domainRepoId", "nsHosts", "dsDataHistories");
|
||||
assertThat(fromObjectify instanceof DomainHistory).isTrue();
|
||||
DomainHistory legacyDomainHistory = (DomainHistory) fromObjectify;
|
||||
|
||||
|
@ -129,7 +130,12 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
|
|||
.that(legacyDomainHistory)
|
||||
.isEqualExceptFields(
|
||||
// NB: period, transaction records, and other client ID are added in #794
|
||||
legacyHistoryFromSql, "period", "domainTransactionRecords", "otherClientId", "nsHosts");
|
||||
legacyHistoryFromSql,
|
||||
"period",
|
||||
"domainTransactionRecords",
|
||||
"otherClientId",
|
||||
"nsHosts",
|
||||
"dsDataHistories");
|
||||
assertThat(nullToEmpty(legacyDomainHistory.getNsHosts()))
|
||||
.isEqualTo(nullToEmpty(legacyHistoryFromSql.getNsHosts()));
|
||||
}
|
||||
|
|
|
@ -273,6 +273,7 @@ class google.registry.model.domain.DomainHistory {
|
|||
java.lang.String clientId;
|
||||
java.lang.String otherClientId;
|
||||
java.lang.String reason;
|
||||
java.util.Set<google.registry.model.domain.secdns.DomainDsDataHistory> dsDataHistories;
|
||||
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
|
||||
org.joda.time.DateTime modificationTime;
|
||||
}
|
||||
|
@ -315,6 +316,14 @@ class google.registry.model.domain.secdns.DelegationSignerData {
|
|||
int digestType;
|
||||
int keyTag;
|
||||
}
|
||||
class google.registry.model.domain.secdns.DomainDsDataHistory {
|
||||
byte[] digest;
|
||||
int algorithm;
|
||||
int digestType;
|
||||
int keyTag;
|
||||
java.lang.Long domainHistoryRevisionId;
|
||||
java.lang.Long dsDataHistoryRevisionId;
|
||||
}
|
||||
class google.registry.model.domain.token.AllocationToken {
|
||||
@Id java.lang.String token;
|
||||
boolean discountPremiums;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -66,3 +66,4 @@ V65__local_date_date_type.sql
|
|||
V66__create_rde_revision.sql
|
||||
V67__grace_period_history_ids.sql
|
||||
V68__make_reserved_list_nullable_in_registry.sql
|
||||
V69__change_primary_key_and_add_history_table_for_delegation_signer.sql
|
||||
|
|
|
@ -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.
|
||||
|
||||
alter table "DelegationSignerData" drop constraint "DelegationSignerData_pkey";
|
||||
|
||||
alter table "DelegationSignerData"
|
||||
add constraint "DelegationSignerData_pkey"
|
||||
primary key (domain_repo_id, key_tag, algorithm, digest_type, digest);
|
||||
|
||||
create table "DomainDsDataHistory" (
|
||||
ds_data_history_revision_id int8 not null,
|
||||
algorithm int4 not null,
|
||||
digest bytea not null,
|
||||
digest_type int4 not null,
|
||||
domain_history_revision_id int8 not null,
|
||||
key_tag int4 not null,
|
||||
domain_repo_id text,
|
||||
primary key (ds_data_history_revision_id)
|
||||
);
|
||||
|
||||
alter table if exists "DomainDsDataHistory"
|
||||
add constraint FKo4ilgyyfnvppbpuivus565i0j
|
||||
foreign key (domain_repo_id, domain_history_revision_id)
|
||||
references "DomainHistory";
|
|
@ -227,12 +227,12 @@
|
|||
);
|
||||
|
||||
create table "DelegationSignerData" (
|
||||
domain_repo_id text not null,
|
||||
key_tag int4 not null,
|
||||
algorithm int4 not null,
|
||||
algorithm int4 not null,
|
||||
digest bytea not null,
|
||||
digest_type int4 not null,
|
||||
primary key (domain_repo_id, key_tag)
|
||||
domain_repo_id text not null,
|
||||
key_tag int4 not null,
|
||||
primary key (algorithm, digest, digest_type, domain_repo_id, key_tag)
|
||||
);
|
||||
|
||||
create table "Domain" (
|
||||
|
@ -291,6 +291,17 @@
|
|||
primary key (repo_id)
|
||||
);
|
||||
|
||||
create table "DomainDsDataHistory" (
|
||||
ds_data_history_revision_id int8 not null,
|
||||
algorithm int4 not null,
|
||||
digest bytea not null,
|
||||
digest_type int4 not null,
|
||||
domain_history_revision_id int8 not null,
|
||||
domain_repo_id text,
|
||||
key_tag int4 not null,
|
||||
primary key (ds_data_history_revision_id)
|
||||
);
|
||||
|
||||
create table "DomainHistory" (
|
||||
domain_repo_id text not null,
|
||||
history_revision_id int8 not null,
|
||||
|
@ -729,6 +740,11 @@ create index spec11threatmatch_check_date_idx on "Spec11ThreatMatch" (check_date
|
|||
foreign key (domain_repo_id)
|
||||
references "Domain";
|
||||
|
||||
alter table if exists "DomainDsDataHistory"
|
||||
add constraint FKo4ilgyyfnvppbpuivus565i0j
|
||||
foreign key (domain_repo_id, domain_history_revision_id)
|
||||
references "DomainHistory";
|
||||
|
||||
alter table if exists "DomainHistoryHost"
|
||||
add constraint FKa9woh3hu8gx5x0vly6bai327n
|
||||
foreign key (domain_history_domain_repo_id, domain_history_history_revision_id)
|
||||
|
|
|
@ -376,6 +376,21 @@ CREATE TABLE public."Domain" (
|
|||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: DomainDsDataHistory; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."DomainDsDataHistory" (
|
||||
ds_data_history_revision_id bigint NOT NULL,
|
||||
algorithm integer NOT NULL,
|
||||
digest bytea NOT NULL,
|
||||
digest_type integer NOT NULL,
|
||||
domain_history_revision_id bigint NOT NULL,
|
||||
key_tag integer NOT NULL,
|
||||
domain_repo_id text
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: DomainHistory; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1072,7 +1087,15 @@ ALTER TABLE ONLY public."Cursor"
|
|||
--
|
||||
|
||||
ALTER TABLE ONLY public."DelegationSignerData"
|
||||
ADD CONSTRAINT "DelegationSignerData_pkey" PRIMARY KEY (domain_repo_id, key_tag);
|
||||
ADD CONSTRAINT "DelegationSignerData_pkey" PRIMARY KEY (domain_repo_id, key_tag, algorithm, digest_type, digest);
|
||||
|
||||
|
||||
--
|
||||
-- Name: DomainDsDataHistory DomainDsDataHistory_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."DomainDsDataHistory"
|
||||
ADD CONSTRAINT "DomainDsDataHistory_pkey" PRIMARY KEY (ds_data_history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
|
@ -2016,6 +2039,14 @@ ALTER TABLE ONLY public."PremiumEntry"
|
|||
ADD CONSTRAINT fko0gw90lpo1tuee56l0nb6y6g5 FOREIGN KEY (revision_id) REFERENCES public."PremiumList"(revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: DomainDsDataHistory fko4ilgyyfnvppbpuivus565i0j; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."DomainDsDataHistory"
|
||||
ADD CONSTRAINT fko4ilgyyfnvppbpuivus565i0j FOREIGN KEY (domain_repo_id, domain_history_revision_id) REFERENCES public."DomainHistory"(domain_repo_id, history_revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: DelegationSignerData fktr24j9v14ph2mfuw2gsmt12kq; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue