1
0
mirror of https://github.com/google/nomulus synced 2026-07-18 14:02:35 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
gbrodman 4ec7f23e84 Use the parent to store the history repo ID and fill in the base object (#830)
* Use the parent to store the history repo ID and fill in the base object

Storing the repo ID in the parent and in the base object has two primary
benefits.

First, it unifies the parent information in the HistoryEntry's `parent`
object. This simplifies the builders and the data flow.

Second, when possible (which should be always, post-migration) we fill
out the DomainContent's repo ID (similarly for the other EPP resources)
which means that when reconstituting the ofy keys we don't need to pass
the repo ID in from a separate object. This way, all the data are
encapsulated where they should be.

The primary downside here is that it further reduces the "immutability"
of the history objects (since we're using the Hibernate setter for the
parent repo ID) but we weren't immutable anyway.

* Respond to CR

- compare the entire vkeys in tests
- always return the parent for repo ID

* Simplify creation of parent VKeys

* Fix flipped isAssignableFrom check in VKey

* Merge remote-tracking branch 'origin/master' into historyRepoId
2020-10-09 16:01:51 -04:00
Shicong Huang 7a68b1b6f0 Revert package-lock.json to version from #676 (#834)
Co-authored-by: gbrodman <gbrodman@google.com>
2020-10-09 15:57:23 -04:00
Shicong Huang 14e593d9e1 Add SchemaCrawler as dependency (#833) 2020-10-09 15:02:11 -04:00
Weimin Yu 2d5de96fbd Minor python changes (#832)
* Minor python changes

Use dataclasses instead of attrs. The former is part of the standard lib
while the latter may need to be installed separately.

Also added python3 to the list of prerequisites.
2020-10-09 14:50:21 -04:00
Weimin Yu 13d30b0bfb Maintain a release-to-Version map in deployment (#831)
* Maintain a release-to-Version map in deployment

Keep track of the mapping between Nomulus release tags and AppEngine
version ids with a mapping file. This is necessary because AppEngine
does not support custom versioning. With this mapping, rollbacks could
be automated. Automation of rollbacks is important since there are
test-supporting metadata to be updated, but are easily forgotten.

During the last stage of deployment, current per-service version ids
are fetched using gcloud and are appended to a file on GCS. Each line
is of the format "{RELEASE_TAG},{APPENGINE_SERVICE},{APPENGINE_VERSION}.

This change has been tested in crash. The rollback script is still a
work in progress.
2020-10-09 13:32:52 -04:00
Shicong Huang b05f6b4ba3 Add SQL schema for DelegationSignerData (#713)
* Add SQL schema for DelegationSignerData

* Remove join table

* Rebased on HEAD

* Rebase on head
2020-10-09 10:22:31 -04:00
Shicong Huang 17a1387184 Disable auto-generation on id for HostHistory and ContactHistory (#827) 2020-10-08 12:30:54 -04:00
88 changed files with 671 additions and 199 deletions
+3 -3
View File
@@ -16,7 +16,7 @@
"""
import argparse
import attr
import dataclasses
import io
import os
import shutil
@@ -25,7 +25,7 @@ import sys
from typing import List, Union
@attr.s(auto_attribs=True)
@dataclasses.dataclass
class Property:
name : str = ''
desc : str = ''
@@ -39,7 +39,7 @@ class Property:
raise ValidationError('value of {self.name} must be "true" or '
'"false".')
@attr.s(auto_attribs=True)
@dataclasses.dataclass
class GradleFlag:
flags : Union[str, List[str]]
desc : str
+2
View File
@@ -270,6 +270,8 @@ dependencies {
compile deps['org.testcontainers:postgresql']
testCompile deps['org.testcontainers:selenium']
testCompile deps['org.testcontainers:testcontainers']
compile deps['us.fatehi:schemacrawler']
compile deps['us.fatehi:schemacrawler-diagram']
compile deps['xerces:xmlParserAPIs']
compile deps['xpp3:xpp3']
// This dependency must come after javax.mail:mail as it would otherwise
@@ -250,5 +250,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -247,5 +247,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -253,5 +253,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -250,5 +250,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -249,5 +249,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -298,5 +298,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -297,5 +297,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -302,5 +302,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -303,5 +303,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -67,6 +67,7 @@ import google.registry.model.domain.DomainCommand.Update.AddRemove;
import google.registry.model.domain.DomainCommand.Update.Change;
import google.registry.model.domain.fee.FeeUpdateCommandExtension;
import google.registry.model.domain.metadata.MetadataExtension;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.domain.secdns.SecDnsUpdateExtension;
import google.registry.model.domain.superuser.DomainUpdateSuperuserExtension;
import google.registry.model.eppcommon.AuthInfo;
@@ -238,10 +239,16 @@ public final class DomainUpdateFlow implements TransactionalFlow {
DomainBase.Builder domainBuilder =
domain
.asBuilder()
// Handle the secDNS extension.
// Handle the secDNS extension. As dsData in secDnsUpdate is read from EPP input and
// does not have domainRepoId set, we create a copy of the existing dsData without
// domainRepoId for comparison.
.setDsData(
secDnsUpdate.isPresent()
? updateDsData(domain.getDsData(), secDnsUpdate.get())
? updateDsData(
domain.getDsData().stream()
.map(DelegationSignerData::cloneWithoutDomainRepoId)
.collect(toImmutableSet()),
secDnsUpdate.get())
: domain.getDsData())
.setLastEppUpdateTime(now)
.setLastEppUpdateClientId(clientId)
@@ -17,7 +17,6 @@ package google.registry.model.contact;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.EntitySubclass;
import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.contact.ContactHistory.ContactHistoryId;
import google.registry.model.reporting.HistoryEntry;
@@ -31,8 +30,6 @@ import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.PostLoad;
@@ -60,10 +57,19 @@ public class ContactHistory extends HistoryEntry implements SqlEntity {
// Store ContactBase instead of ContactResource so we don't pick up its @Id
@Nullable ContactBase contactBase;
@Id String contactRepoId;
@Id
@Access(AccessType.PROPERTY)
public String getContactRepoId() {
return parent.getName();
}
/** This method is private because it is only used by Hibernate. */
@SuppressWarnings("unused")
private void setContactRepoId(String contactRepoId) {
parent = Key.create(ContactResource.class, contactRepoId);
}
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
@Column(name = "historyRevisionId")
@Access(AccessType.PROPERTY)
@Override
@@ -82,15 +88,14 @@ public class ContactHistory extends HistoryEntry implements SqlEntity {
}
/** The key to the {@link ContactResource} this is based off of. */
public VKey<ContactResource> getContactRepoId() {
return VKey.create(
ContactResource.class, contactRepoId, Key.create(ContactResource.class, contactRepoId));
public VKey<ContactResource> getParentVKey() {
return VKey.create(ContactResource.class, getContactRepoId());
}
/** Creates a {@link VKey} instance for this entity. */
public VKey<ContactHistory> createVKey() {
return VKey.create(
ContactHistory.class, new ContactHistoryId(contactRepoId, getId()), Key.create(this));
ContactHistory.class, new ContactHistoryId(getContactRepoId(), getId()), Key.create(this));
}
@PostLoad
@@ -100,8 +105,6 @@ public class ContactHistory extends HistoryEntry implements SqlEntity {
if (contactBase != null && contactBase.getContactId() == null) {
contactBase = null;
}
// Fill in the full, symmetric, parent repo ID key
parent = Key.create(ContactResource.class, contactRepoId);
}
// In Datastore, save as a HistoryEntry object regardless of this object's type
@@ -187,17 +190,8 @@ public class ContactHistory extends HistoryEntry implements SqlEntity {
}
public Builder setContactRepoId(String contactRepoId) {
getInstance().contactRepoId = contactRepoId;
getInstance().parent = Key.create(ContactResource.class, contactRepoId);
return this;
}
// We can remove this once all HistoryEntries are converted to History objects
@Override
public Builder setParent(Key<? extends EppResource> parent) {
super.setParent(parent);
getInstance().contactRepoId = parent.getName();
return this;
}
}
}
@@ -19,6 +19,7 @@ import google.registry.model.EppResource;
import google.registry.model.EppResource.ForeignKeyedEppResource;
import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.ReportedOn;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.persistence.WithStringVKey;
@@ -35,7 +36,6 @@ import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import org.joda.time.DateTime;
@@ -107,10 +107,30 @@ public class DomainBase extends DomainContent
return gracePeriods;
}
@PostLoad
/**
* Returns the set of {@link DelegationSignerData} associated with the domain.
*
* <p>This is the getter method specific for Hibernate to access the field so it is set to
* private. The caller can use the public {@link #getDsData()} to get the DS data.
*
* <p>Note that we need to set `insertable = false, updatable = false` for @JoinColumn, otherwise
* Hibernate would try to set the foreign key to null(through an UPDATE TABLE sql) instead of
* deleting the whole entry from the table when the {@link DelegationSignerData} is removed from
* the set.
*/
@Access(AccessType.PROPERTY)
@OneToMany(
cascade = {CascadeType.ALL},
fetch = FetchType.EAGER,
orphanRemoval = true)
@JoinColumn(
name = "domainRepoId",
referencedColumnName = "repoId",
insertable = false,
updatable = false)
@SuppressWarnings("UnusedMethod")
private final void postLoad() {
restoreOfyKeys(getRepoId());
private Set<DelegationSignerData> getInternalDelegationSignerData() {
return dsData;
}
@Override
@@ -35,6 +35,7 @@ import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
@@ -68,7 +69,6 @@ import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import javax.persistence.Access;
import javax.persistence.AccessType;
@@ -317,17 +317,15 @@ public class DomainContent extends EppResource
autorenewPollMessageHistoryId = getHistoryId(autorenewPollMessage);
autorenewBillingEventHistoryId = getHistoryId(autorenewBillingEvent);
deletePollMessageHistoryId = getHistoryId(deletePollMessage);
dsData =
nullToEmptyImmutableCopy(dsData).stream()
.map(dsData -> dsData.cloneWithDomainRepoId(getRepoId()))
.collect(toImmutableSet());
}
/**
* The {@link javax.persistence.PostLoad} method for {@link DomainContent}.
*
* <p>We name this domainContentPostLoad to distinguish it from the {@link PostLoad} method in
* DomainBase (if they share the same name, this one is never called).
*/
@PostLoad
@SuppressWarnings("UnusedMethod")
private final void domainContentPostLoad() {
private final void postLoad() {
// Reconstitute the contact list.
ImmutableSet.Builder<DesignatedContact> contactsBuilder = new ImmutableSet.Builder<>();
@@ -346,34 +344,9 @@ public class DomainContent extends EppResource
}
allContacts = contactsBuilder.build();
}
/**
* Restores the composite ofy keys from SQL data.
*
* <p>MUST ONLY BE CALLED FROM A PostLoad method. This is a package-visible method that
* effectively mutates an immutable object.
*
* <p>We have to do this because:
*
* <ul>
* <li>We've changed the {@link PostLoad} method behavior to make all {@link PostLoad} calls in
* the class hierarchy (and not merely the most specific one) be called after an object is
* loaded.
* <li>When restoring a {@link DomainBase} object (which is a subclass) the repo id is not
* populated until after our {@link PostLoad} method is called. Therefore, we need to
* restore these ofy keys (which depend on the repo id) from {@link DomainBase}'s {@link
* PostLoad} method.
* <li>When restoring a {@link DomainHistory} object, hibernate restores a {@link DomainContent}
* instance, therefore we need our own {@link PostLoad} method to restore the other fields.
* In order to restore the ofy keys, we need to invoke this method separately from {@link
* DomainHistory}'s {@link PostLoad} method and pass in the repo id, which is stored in a
* different field in {@link DomainHistory}.
* </ul>
*/
void restoreOfyKeys(String repoId) {
// Reconstitute the ofy keys.
Key<DomainBase> myKey = Key.create(DomainBase.class, repoId);
// Reconstitute the composite ofy keys from the SQL data.
Key<DomainBase> myKey = Key.create(DomainBase.class, getRepoId());
deletePollMessage = restoreOfyFrom(myKey, deletePollMessage, deletePollMessageHistoryId);
autorenewBillingEvent =
restoreOfyFrom(myKey, autorenewBillingEvent, autorenewBillingEventHistoryId);
@@ -469,6 +442,12 @@ public class DomainContent extends EppResource
this.gracePeriods = gracePeriods;
}
// Hibernate needs this in order to populate dsData but no one else should ever use it
@SuppressWarnings("UnusedMethod")
private void setInternalDelegationSignerData(Set<DelegationSignerData> dsData) {
this.dsData = dsData;
}
public final String getCurrentSponsorClientId() {
return getPersistedCurrentSponsorClientId();
}
@@ -754,7 +733,7 @@ public class DomainContent extends EppResource
/** An override of {@link EppResource#asBuilder} with tighter typing. */
@Override
public Builder asBuilder() {
public Builder<? extends DomainContent, ?> asBuilder() {
return new Builder<>(clone(this));
}
@@ -791,10 +770,16 @@ public class DomainContent extends EppResource
instance.tld = getTldFromDomainName(instance.fullyQualifiedDomainName);
T newDomain = super.build();
// Hibernate throws exception if gracePeriods is null because we enabled all cascadable
// operations and orphan removal.
// Hibernate throws exception if gracePeriods or dsData is null because we enabled all
// cascadable operations and orphan removal.
newDomain.gracePeriods =
newDomain.gracePeriods == null ? ImmutableSet.of() : newDomain.gracePeriods;
newDomain.dsData =
newDomain.dsData == null
? ImmutableSet.of()
: newDomain.dsData.stream()
.map(ds -> ds.cloneWithDomainRepoId(instance.getRepoId()))
.collect(toImmutableSet());
return newDomain;
}
@@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.EntitySubclass;
import com.googlecode.objectify.annotation.Ignore;
import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.domain.DomainHistory.DomainHistoryId;
import google.registry.model.host.HostResource;
@@ -73,7 +72,17 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
// Store DomainContent instead of DomainBase so we don't pick up its @Id
@Nullable DomainContent domainContent;
@Id String domainRepoId;
@Id
@Access(AccessType.PROPERTY)
public String getDomainRepoId() {
return parent.getName();
}
/** This method is private because it is only used by Hibernate. */
@SuppressWarnings("unused")
private void setDomainRepoId(String domainRepoId) {
parent = Key.create(DomainBase.class, domainRepoId);
}
// We could have reused domainContent.nsHosts here, but Hibernate throws a weird exception after
// we change to use a composite primary key.
@@ -152,14 +161,14 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
}
/** The key to the {@link DomainBase} this is based off of. */
public VKey<DomainBase> getDomainRepoId() {
return VKey.create(DomainBase.class, domainRepoId, Key.create(DomainBase.class, domainRepoId));
public VKey<DomainBase> getParentVKey() {
return VKey.create(DomainBase.class, getDomainRepoId());
}
/** Creates a {@link VKey} instance for this entity. */
public VKey<DomainHistory> createVKey() {
return VKey.create(
DomainHistory.class, new DomainHistoryId(domainRepoId, getId()), Key.create(this));
DomainHistory.class, new DomainHistoryId(getDomainRepoId(), getId()), Key.create(this));
}
@PostLoad
@@ -171,10 +180,11 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
if (domainContent.getDomainName() == null) {
domainContent = null;
} else {
domainContent.restoreOfyKeys(domainRepoId);
if (domainContent.getRepoId() == null) {
domainContent = domainContent.asBuilder().setRepoId(parent.getName()).build();
}
}
}
parent = Key.create(DomainBase.class, domainRepoId);
}
// In Datastore, save as a HistoryEntry object regardless of this object's type
@@ -263,17 +273,8 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
}
public Builder setDomainRepoId(String domainRepoId) {
getInstance().domainRepoId = domainRepoId;
getInstance().parent = Key.create(DomainBase.class, domainRepoId);
return this;
}
// We can remove this once all HistoryEntries are converted to History objects
@Override
public Builder setParent(Key<? extends EppResource> parent) {
super.setParent(parent);
getInstance().domainRepoId = parent.getName();
return this;
}
}
}
@@ -14,11 +14,22 @@
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 java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
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;
@@ -31,19 +42,26 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
*/
@Embed
@XmlType(name = "dsData")
@javax.persistence.Entity
@Entity
@Table(indexes = @Index(columnList = "domainRepoId"))
@IdClass(DelegationSignerDataId.class)
public class DelegationSignerData extends ImmutableObject implements DatastoreAndSqlEntity {
private DelegationSignerData() {}
@Ignore @XmlTransient @javax.persistence.Id String domainRepoId;
/** The identifier for this particular key in the domain. */
@javax.persistence.Id int keyTag;
@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;
@@ -52,6 +70,7 @@ public class DelegationSignerData extends ImmutableObject implements DatastoreAn
*
* @see <a href="http://tools.ietf.org/html/rfc4034#appendix-A.2">RFC 4034 Appendix A.2</a>
*/
@Column(nullable = false)
int digestType;
/**
@@ -59,6 +78,7 @@ public class DelegationSignerData extends ImmutableObject implements DatastoreAn
*
* @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;
@@ -82,16 +102,34 @@ public class DelegationSignerData extends ImmutableObject implements DatastoreAn
return digest == null ? "" : DatatypeConverter.printHexBinary(digest);
}
public DelegationSignerData cloneWithDomainRepoId(String domainRepoId) {
DelegationSignerData clone = clone(this);
clone.domainRepoId = checkArgumentNotNull(domainRepoId);
return clone;
}
public DelegationSignerData cloneWithoutDomainRepoId() {
DelegationSignerData clone = clone(this);
clone.domainRepoId = null;
return clone;
}
public static DelegationSignerData create(
int keyTag, int algorithm, int digestType, byte[] digest) {
int keyTag, int algorithm, int digestType, byte[] digest, String domainRepoId) {
DelegationSignerData instance = new DelegationSignerData();
instance.keyTag = keyTag;
instance.algorithm = algorithm;
instance.digestType = digestType;
instance.digest = digest;
instance.domainRepoId = domainRepoId;
return instance;
}
public static DelegationSignerData create(
int keyTag, int algorithm, int digestType, byte[] digest) {
return create(keyTag, algorithm, digestType, digest, null);
}
public static DelegationSignerData create(
int keyTag, int algorithm, int digestType, String digestAsHex) {
return create(keyTag, algorithm, digestType, DatatypeConverter.parseHexBinary(digestAsHex));
@@ -107,4 +145,20 @@ public class DelegationSignerData extends ImmutableObject implements DatastoreAn
"%d %d %d %s",
this.keyTag, this.algorithm, this.digestType, DatatypeConverter.printHexBinary(digest));
}
static class DelegationSignerDataId extends ImmutableObject implements Serializable {
String domainRepoId;
int keyTag;
private DelegationSignerDataId() {}
private DelegationSignerDataId(String domainRepoId, int keyTag) {
this.domainRepoId = domainRepoId;
this.keyTag = keyTag;
}
public static DelegationSignerDataId create(String domainRepoId, int keyTag) {
return new DelegationSignerDataId(checkArgumentNotNull(domainRepoId), keyTag);
}
}
}
@@ -20,8 +20,10 @@ import static com.google.common.base.Strings.nullToEmpty;
import com.google.common.collect.ImmutableSet;
import google.registry.model.EppResource;
import google.registry.model.contact.ContactBase;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.DomainContent;
import google.registry.model.host.HostBase;
import google.registry.model.host.HostResource;
import google.registry.model.translators.EnumToAttributeAdapter.EppEnum;
@@ -128,9 +130,15 @@ public enum StatusValue implements EppEnum {
/** Enum to help clearly list which resource types a status value is allowed to be present on. */
private enum AllowedOn {
ALL(ContactResource.class, DomainBase.class, HostBase.class, HostResource.class),
ALL(
ContactBase.class,
ContactResource.class,
DomainContent.class,
DomainBase.class,
HostBase.class,
HostResource.class),
NONE,
DOMAINS(DomainBase.class);
DOMAINS(DomainContent.class, DomainBase.class);
private final ImmutableSet<Class<? extends EppResource>> classes;
@@ -14,11 +14,9 @@
package google.registry.model.host;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.EntitySubclass;
import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.host.HostHistory.HostHistoryId;
import google.registry.model.reporting.HistoryEntry;
@@ -32,8 +30,6 @@ import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.PostLoad;
@@ -62,10 +58,19 @@ public class HostHistory extends HistoryEntry implements SqlEntity {
// Store HostBase instead of HostResource so we don't pick up its @Id
@Nullable HostBase hostBase;
@Id String hostRepoId;
@Id
@Access(AccessType.PROPERTY)
public String getHostRepoId() {
return parent.getName();
}
/** This method is private because it is only used by Hibernate. */
@SuppressWarnings("unused")
private void setHostRepoId(String hostRepoId) {
parent = Key.create(HostResource.class, hostRepoId);
}
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TempHistorySequenceGenerator")
@Column(name = "historyRevisionId")
@Access(AccessType.PROPERTY)
@Override
@@ -84,13 +89,14 @@ public class HostHistory extends HistoryEntry implements SqlEntity {
}
/** The key to the {@link google.registry.model.host.HostResource} this is based off of. */
public VKey<HostResource> getHostRepoId() {
return VKey.create(HostResource.class, hostRepoId, Key.create(HostResource.class, hostRepoId));
public VKey<HostResource> getParentVKey() {
return VKey.create(HostResource.class, getHostRepoId());
}
/** Creates a {@link VKey} instance for this entity. */
public VKey<HostHistory> createVKey() {
return VKey.create(HostHistory.class, new HostHistoryId(hostRepoId, getId()), Key.create(this));
return VKey.create(
HostHistory.class, new HostHistoryId(getHostRepoId(), getId()), Key.create(this));
}
@PostLoad
@@ -100,8 +106,6 @@ public class HostHistory extends HistoryEntry implements SqlEntity {
if (hostBase != null && hostBase.getHostName() == null) {
hostBase = null;
}
// Fill in the full, symmetric, parent repo ID key
parent = Key.create(HostResource.class, hostRepoId);
}
// In Datastore, save as a HistoryEntry object regardless of this object's type
@@ -187,17 +191,8 @@ public class HostHistory extends HistoryEntry implements SqlEntity {
}
public Builder setHostRepoId(String hostRepoId) {
getInstance().hostRepoId = hostRepoId;
getInstance().parent = Key.create(HostResource.class, hostRepoId);
return this;
}
// We can remove this once all HistoryEntries are converted to History objects
@Override
public Builder setParent(Key<? extends EppResource> parent) {
super.setParent(parent);
getInstance().hostRepoId = parent.getName();
return this;
}
}
}
@@ -88,7 +88,7 @@ public class VKey<T> extends ImmutableObject implements Serializable {
*/
public static <T> VKey<T> create(Class<T> kind, long id) {
checkArgument(
kind.isAssignableFrom(BackupGroupRoot.class),
BackupGroupRoot.class.isAssignableFrom(kind),
"The kind %s is not a BackupGroupRoot and thus needs its entire entity group chain"
+ " specified in a parent",
kind.getCanonicalName());
@@ -106,7 +106,7 @@ public class VKey<T> extends ImmutableObject implements Serializable {
*/
public static <T> VKey<T> create(Class<T> kind, String name) {
checkArgument(
kind.isAssignableFrom(BackupGroupRoot.class),
BackupGroupRoot.class.isAssignableFrom(kind),
"The kind %s is not a BackupGroupRoot and thus needs its entire entity group chain"
+ " specified in a parent",
kind.getCanonicalName());
-5
View File
@@ -11,11 +11,6 @@
</attributes>
</embeddable>
<sequence-generator name="HistorySequenceGenerator" sequence-name="history_id_sequence"/>
<!-- TODO(shicong): Drop this sequence and change all history tables to use the above one. -->
<sequence-generator name="TempHistorySequenceGenerator" sequence-name="temp_history_id_sequence"/>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
@@ -821,10 +821,12 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
setEppInput("domain_create_dsdata_no_maxsiglife.xml");
persistContactsAndHosts("tld"); // For some reason this sample uses "tld".
doSuccessfulTest("tld");
DomainBase domain = reloadResourceByForeignKey();
assertAboutDomains()
.that(reloadResourceByForeignKey())
.that(domain)
.hasExactlyDsData(
DelegationSignerData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")));
DelegationSignerData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC"))
.cloneWithDomainRepoId(domain.getRepoId()));
}
@Test
@@ -14,6 +14,7 @@
package google.registry.flows.domain;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Sets.union;
import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.truth.Truth.assertThat;
@@ -470,7 +471,11 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
.that(resource)
.hasOnlyOneHistoryEntryWhich()
.hasType(HistoryEntry.Type.DOMAIN_UPDATE);
assertThat(resource.getDsData()).isEqualTo(expectedDsData);
assertThat(resource.getDsData())
.isEqualTo(
expectedDsData.stream()
.map(ds -> ds.cloneWithDomainRepoId(resource.getRepoId()))
.collect(toImmutableSet()));
assertDnsTasksEnqueued("example.tld");
}
@@ -25,6 +25,7 @@ import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
@@ -342,6 +343,50 @@ public class DomainBaseSqlTest {
});
}
@Test
void testModifyDsData_addThenRemoveSuccessfully() {
persistDomain();
DelegationSignerData extraDsData =
DelegationSignerData.create(2, 2, 3, new byte[] {0, 1, 2}, "4-COM");
ImmutableSet<DelegationSignerData> unionDsData =
Sets.union(domain.getDsData(), ImmutableSet.of(extraDsData)).immutableCopy();
// Add an extra DelegationSignerData to dsData set.
jpaTm()
.transact(
() -> {
DomainBase persisted = jpaTm().load(domain.createVKey());
assertThat(persisted.getDsData()).containsExactlyElementsIn(domain.getDsData());
DomainBase modified = persisted.asBuilder().setDsData(unionDsData).build();
jpaTm().put(modified);
});
// Verify that the persisted domain entity contains both DelegationSignerData records.
jpaTm()
.transact(
() -> {
DomainBase persisted = jpaTm().load(domain.createVKey());
assertThat(persisted.getDsData()).containsExactlyElementsIn(unionDsData);
assertEqualDomainExcept(persisted, "dsData");
});
// Remove the extra DelegationSignerData record from dsData set.
jpaTm()
.transact(
() -> {
DomainBase persisted = jpaTm().load(domain.createVKey());
jpaTm().put(persisted.asBuilder().setDsData(domain.getDsData()).build());
});
// Verify that the persisted domain is equal to the original domain.
jpaTm()
.transact(
() -> {
DomainBase persisted = jpaTm().load(domain.createVKey());
assertEqualDomainExcept(persisted);
});
}
@Test
void testUpdates() {
jpaTm()
@@ -358,16 +403,6 @@ public class DomainBaseSqlTest {
.transact(
() -> {
DomainBase result = jpaTm().load(domain.createVKey());
// Fix DS data, since we can't persist that yet.
result =
result
.asBuilder()
.setDsData(
ImmutableSet.of(
DelegationSignerData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build();
assertAboutImmutableObjects()
.that(result)
.isEqualExceptFields(domain, "updateTimestamp", "creationTime");
@@ -572,13 +607,6 @@ public class DomainBaseSqlTest {
}
private void assertEqualDomainExcept(DomainBase thatDomain, String... excepts) {
// Fix DS data, since we can't persist it yet.
thatDomain =
thatDomain
.asBuilder()
.setDsData(ImmutableSet.of(DelegationSignerData.create(1, 2, 3, new byte[] {0, 1, 2})))
.build();
// Fix the original creation timestamp (this gets initialized on first write)
DomainBase org = domain.asBuilder().setCreationTime(thatDomain.getCreationTime()).build();
@@ -48,15 +48,13 @@ public class ContactHistoryTest extends EntityTestCase {
VKey<ContactResource> contactVKey = contact.createVKey();
ContactResource contactFromDb = jpaTm().transact(() -> jpaTm().load(contactVKey));
ContactHistory contactHistory = createContactHistory(contactFromDb, contact.getRepoId());
contactHistory.id = null;
jpaTm().transact(() -> jpaTm().insert(contactHistory));
jpaTm()
.transact(
() -> {
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
assertContactHistoriesEqual(fromDatabase, contactHistory);
assertThat(fromDatabase.getContactRepoId().getSqlKey())
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(contactHistory.getParentVKey());
});
}
@@ -73,7 +71,6 @@ public class ContactHistoryTest extends EntityTestCase {
.asBuilder()
.setContactBase(null)
.build();
contactHistory.id = null;
jpaTm().transact(() -> jpaTm().insert(contactHistory));
jpaTm()
@@ -81,8 +78,7 @@ public class ContactHistoryTest extends EntityTestCase {
() -> {
ContactHistory fromDatabase = jpaTm().load(contactHistory.createVKey());
assertContactHistoriesEqual(fromDatabase, contactHistory);
assertThat(fromDatabase.getContactRepoId().getSqlKey())
.isEqualTo(contactHistory.getContactRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(contactHistory.getParentVKey());
});
}
@@ -66,8 +66,7 @@ public class DomainHistoryTest extends EntityTestCase {
() -> {
DomainHistory fromDatabase = jpaTm().load(domainHistory.createVKey());
assertDomainHistoriesEqual(fromDatabase, domainHistory);
assertThat(fromDatabase.getDomainRepoId().getSqlKey())
.isEqualTo(domainHistory.getDomainRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(domainHistory.getParentVKey());
});
}
@@ -83,8 +82,7 @@ public class DomainHistoryTest extends EntityTestCase {
() -> {
DomainHistory fromDatabase = jpaTm().load(domainHistory.createVKey());
assertDomainHistoriesEqual(fromDatabase, domainHistory);
assertThat(fromDatabase.getDomainRepoId().getSqlKey())
.isEqualTo(domainHistory.getDomainRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(domainHistory.getParentVKey());
assertThat(fromDatabase.getNsHosts())
.containsExactlyElementsIn(
domainHistory.getNsHosts().stream()
@@ -49,15 +49,13 @@ public class HostHistoryTest extends EntityTestCase {
VKey.create(HostResource.class, "host1", Key.create(HostResource.class, "host1"));
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(hostVKey));
HostHistory hostHistory = createHostHistory(hostFromDb, host.getRepoId());
hostHistory.id = null;
jpaTm().transact(() -> jpaTm().insert(hostHistory));
jpaTm()
.transact(
() -> {
HostHistory fromDatabase = jpaTm().load(hostHistory.createVKey());
assertHostHistoriesEqual(fromDatabase, hostHistory);
assertThat(fromDatabase.getHostRepoId().getSqlKey())
.isEqualTo(hostHistory.getHostRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(hostHistory.getParentVKey());
});
}
@@ -70,7 +68,6 @@ public class HostHistoryTest extends EntityTestCase {
HostResource hostFromDb = jpaTm().transact(() -> jpaTm().load(host.createVKey()));
HostHistory hostHistory =
createHostHistory(hostFromDb, host.getRepoId()).asBuilder().setHostBase(null).build();
hostHistory.id = null;
jpaTm().transact(() -> jpaTm().insert(hostHistory));
jpaTm()
@@ -78,8 +75,7 @@ public class HostHistoryTest extends EntityTestCase {
() -> {
HostHistory fromDatabase = jpaTm().load(hostHistory.createVKey());
assertHostHistoriesEqual(fromDatabase, hostHistory);
assertThat(fromDatabase.getHostRepoId().getSqlKey())
.isEqualTo(hostHistory.getHostRepoId().getSqlKey());
assertThat(fromDatabase.getParentVKey()).isEqualTo(hostHistory.getParentVKey());
});
}
@@ -80,7 +80,6 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
ContactHistory legacyContactHistory = (ContactHistory) fromObjectify;
// Next, save that from-Datastore object in SQL and verify we can load it back in
legacyContactHistory.id = null;
jpaTm()
.transact(
() -> {
@@ -93,8 +92,8 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
.that(legacyContactHistory)
.isEqualExceptFields(legacyHistoryFromSql);
// can't compare contactRepoId directly since it doesn't save the ofy key
assertThat(legacyContactHistory.getContactRepoId().getSqlKey())
.isEqualTo(legacyHistoryFromSql.getContactRepoId().getSqlKey());
assertThat(legacyContactHistory.getParentVKey().getSqlKey())
.isEqualTo(legacyHistoryFromSql.getParentVKey().getSqlKey());
}
@Test
@@ -160,7 +159,6 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
HostHistory legacyHostHistory = (HostHistory) fromObjectify;
// Next, save that from-Datastore object in SQL and verify we can load it back in
legacyHostHistory.id = null;
jpaTm()
.transact(
() -> {
@@ -171,8 +169,8 @@ public class LegacyHistoryObjectTest extends EntityTestCase {
jpaTm().transact(() -> jpaTm().load(legacyHostHistory.createVKey()));
assertAboutImmutableObjects().that(legacyHostHistory).isEqualExceptFields(legacyHistoryFromSql);
// can't compare hostRepoId directly since it doesn't save the ofy key in SQL
assertThat(legacyHostHistory.getHostRepoId().getSqlKey())
.isEqualTo(legacyHistoryFromSql.getHostRepoId().getSqlKey());
assertThat(legacyHostHistory.getParentVKey().getSqlKey())
.isEqualTo(legacyHistoryFromSql.getParentVKey().getSqlKey());
}
private HistoryEntry historyEntryForDomain(DomainBase domain) {
@@ -133,7 +133,6 @@ class google.registry.model.contact.ContactHistory {
google.registry.model.reporting.HistoryEntry$Type type;
java.lang.Boolean requestedByRegistrar;
java.lang.String clientId;
java.lang.String contactRepoId;
java.lang.String otherClientId;
java.lang.String reason;
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
@@ -272,7 +271,6 @@ class google.registry.model.domain.DomainHistory {
google.registry.model.reporting.HistoryEntry$Type type;
java.lang.Boolean requestedByRegistrar;
java.lang.String clientId;
java.lang.String domainRepoId;
java.lang.String otherClientId;
java.lang.String reason;
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
@@ -403,7 +401,6 @@ class google.registry.model.host.HostHistory {
google.registry.model.reporting.HistoryEntry$Type type;
java.lang.Boolean requestedByRegistrar;
java.lang.String clientId;
java.lang.String hostRepoId;
java.lang.String otherClientId;
java.lang.String reason;
java.util.Set<google.registry.model.reporting.DomainTransactionRecord> domainTransactionRecords;
+2
View File
@@ -59,3 +59,5 @@ V58__drop_default_value_and_sequences_for_billing_event.sql
V59__use_composite_primary_key_for_contact_and_host_history_table.sql
V60__remove_pollmessage_sequence.sql
V61__domain_hist_columns.sql
V62__disable_key_auto_generation_for_history_tables.sql
V63__add_schema_for_ds_data.sql
@@ -0,0 +1,17 @@
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
drop sequence "history_id_sequence";
drop sequence "temp_history_id_sequence";
@@ -0,0 +1,29 @@
-- 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.
create table "DelegationSignerData" (
domain_repo_id text not null,
key_tag int4 not null,
algorithm int4 not null,
digest bytea not null,
digest_type int4 not null,
primary key (domain_repo_id, key_tag)
);
create index IDXhlqqd5uy98cjyos72d81x9j95 on "DelegationSignerData" (domain_repo_id);
alter table if exists "DelegationSignerData"
add constraint FKtr24j9v14ph2mfuw2gsmt12kq
foreign key (domain_repo_id)
references "Domain";
@@ -11,7 +11,6 @@
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
create sequence temp_history_id_sequence start 1 increment 50;
create table "AllocationToken" (
token text not null,
@@ -228,11 +227,12 @@ create sequence temp_history_id_sequence start 1 increment 50;
);
create table "DelegationSignerData" (
key_tag int4 not null,
domain_repo_id text not null,
key_tag int4 not null,
algorithm int4 not null,
digest bytea,
digest bytea not null,
digest_type int4 not null,
primary key (key_tag)
primary key (domain_repo_id, key_tag)
);
create table "Domain" (
@@ -669,6 +669,7 @@ create index IDXo1xdtpij2yryh0skxe9v91sep on "ContactHistory" (creation_time);
create index IDXhp33wybmb6tbpr1bq7ttwk8je on "ContactHistory" (history_registrar_id);
create index IDX9q53px6r302ftgisqifmc6put on "ContactHistory" (history_type);
create index IDXsudwswtwqnfnx2o1hx4s0k0g5 on "ContactHistory" (history_modification_time);
create index IDXhlqqd5uy98cjyos72d81x9j95 on "DelegationSignerData" (domain_repo_id);
create index IDX8nr0ke9mrrx4ewj6pd2ag4rmr on "Domain" (creation_time);
create index IDXhsjqiy2lyobfymplb28nm74lm on "Domain" (current_sponsor_registrar_id);
create index IDX5mnf0wn20tno4b9do88j61klr on "Domain" (deletion_time);
@@ -706,6 +707,11 @@ create index spec11threatmatch_check_date_idx on "Spec11ThreatMatch" (check_date
foreign key (revision_id)
references "ClaimsList";
alter table if exists "DelegationSignerData"
add constraint FKtr24j9v14ph2mfuw2gsmt12kq
foreign key (domain_repo_id)
references "Domain";
alter table if exists "DomainHistoryHost"
add constraint FKa9woh3hu8gx5x0vly6bai327n
foreign key (domain_history_domain_repo_id, domain_history_history_revision_id)
@@ -303,6 +303,19 @@ CREATE TABLE public."Cursor" (
);
--
-- Name: DelegationSignerData; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."DelegationSignerData" (
domain_repo_id text NOT NULL,
key_tag integer NOT NULL,
algorithm integer NOT NULL,
digest bytea NOT NULL,
digest_type integer NOT NULL
);
--
-- Name: Domain; Type: TABLE; Schema: public; Owner: -
--
@@ -931,30 +944,6 @@ CREATE SEQUENCE public."Transaction_id_seq"
ALTER SEQUENCE public."Transaction_id_seq" OWNED BY public."Transaction".id;
--
-- Name: history_id_sequence; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.history_id_sequence
START WITH 1
INCREMENT BY 50
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: temp_history_id_sequence; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.temp_history_id_sequence
START WITH 1
INCREMENT BY 50
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: ClaimsList revision_id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -1083,6 +1072,14 @@ ALTER TABLE ONLY public."Cursor"
ADD CONSTRAINT "Cursor_pkey" PRIMARY KEY (scope, type);
--
-- Name: DelegationSignerData DelegationSignerData_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."DelegationSignerData"
ADD CONSTRAINT "DelegationSignerData_pkey" PRIMARY KEY (domain_repo_id, key_tag);
--
-- Name: DomainHistory DomainHistory_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -1396,6 +1393,13 @@ CREATE INDEX idxeokttmxtpq2hohcioe5t2242b ON public."BillingCancellation" USING
CREATE INDEX idxfg2nnjlujxo6cb9fha971bq2n ON public."HostHistory" USING btree (creation_time);
--
-- Name: idxhlqqd5uy98cjyos72d81x9j95; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX idxhlqqd5uy98cjyos72d81x9j95 ON public."DelegationSignerData" USING btree (domain_repo_id);
--
-- Name: idxhmv411mdqo5ibn4vy7ykxpmlv; Type: INDEX; Schema: public; Owner: -
--
@@ -2009,6 +2013,14 @@ ALTER TABLE ONLY public."PremiumEntry"
ADD CONSTRAINT fko0gw90lpo1tuee56l0nb6y6g5 FOREIGN KEY (revision_id) REFERENCES public."PremiumList"(revision_id);
--
-- Name: DelegationSignerData fktr24j9v14ph2mfuw2gsmt12kq; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."DelegationSignerData"
ADD CONSTRAINT fktr24j9v14ph2mfuw2gsmt12kq FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id);
--
-- PostgreSQL database dump complete
--
+2
View File
@@ -157,6 +157,8 @@ ext {
'org.testcontainers:selenium:1.14.3',
'org.testcontainers:testcontainers:1.14.3',
'org.yaml:snakeyaml:1.17',
'us.fatehi:schemacrawler:16.10.1',
'us.fatehi:schemacrawler-diagram:16.10.1',
'xerces:xmlParserAPIs:2.6.2',
'xpp3:xpp3:1.1.4c'
]
@@ -253,5 +253,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -249,5 +249,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -253,5 +253,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -253,5 +253,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -263,5 +263,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -261,5 +261,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -263,5 +263,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -263,5 +263,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
+1
View File
@@ -11,6 +11,7 @@ You will need the following programs installed on your local machine:
* [Google App Engine SDK for Java][app-engine-sdk], and configure aliases to
to the `gcloud` and `appcfg.sh` utilities (you'll use them a lot).
* [Git](https://git-scm.com/) version control system.
* Python version 3.7 or newer.
**Note:** App Engine does not yet support Java 9. Also, the instructions in this
document have only been tested on Linux. They might work with some alterations
+33 -11
View File
@@ -63,17 +63,6 @@ steps:
- --credential
- tool-credential.json
- deploy_invoicing_pipeline
# Save the deployed tag for the current environment on GCS. Because of b/137891685
# which causes the for-loop in the next step to fail, this may not be the last step.
# TODO(weiminyu): do this in last step.
- name: 'gcr.io/$PROJECT_ID/builder:latest'
entrypoint: /bin/bash
args:
- -c
- |
set -e
echo ${TAG_NAME} | \
gsutil cp - gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tag
# Deploy the GAE config files.
# First authorize the gcloud tool to use the credential json file, then
# download and unzip the tarball that contains the relevant config files
@@ -97,6 +86,39 @@ steps:
gcloud -q --project $project_id app deploy \
default/WEB-INF/appengine-generated/$filename.yaml
done
# Save the deployed tag for the current environment on GCS, and update the
# mappings from Nomulus releases to Appengine versions.
- name: 'gcr.io/$PROJECT_ID/builder:latest'
entrypoint: /bin/bash
args:
- -c
- |
set -e
echo ${TAG_NAME} | \
gsutil cp - gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tag
# Update the release to AppEngine version mapping.
if [ ${_ENV} == production ]; then
project_id="domain-registry"
else
project_id="domain-registry-${_ENV}"
fi
local_map="nomulus.${_ENV}.tmp"
gcloud app versions list \
--project $project_id --hide-no-traffic \
--format="csv[no-heading](SERVICE,VERSION.ID)" | \
grep -e "^backend\|^default\|^pubapi\|^tools" |\
while read line; do echo "${TAG_NAME},$line"; done | tee "$local_map"
num_versions=$(cat "$local_map" | wc -l)
if [ "$num_versions" -ne 4 ]; then
echo "Expecting exactly four active services. Found $num_versions"
exit 1
fi
gsutil cp "$local_map" gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tmp
# Atomically append uploaded tmp file to nomulus.${_ENV}.versions
gsutil compose \
gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.versions \
gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tmp \
gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.versions
timeout: 3600s
options:
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c
@@ -251,5 +251,10 @@ org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
us.fatehi:schemacrawler-diagram:16.10.1
us.fatehi:schemacrawler-tools:16.10.1
us.fatehi:schemacrawler-utility:16.10.1
us.fatehi:schemacrawler:16.10.1
xerces:xmlParserAPIs:2.6.2
xpp3:xpp3:1.1.4c