1
0
mirror of https://github.com/google/nomulus synced 2026-06-09 16:33:02 +00:00

Compare commits

...

9 Commits

Author SHA1 Message Date
Shicong Huang 3705f37fab Add a build task to upload ER diagrams to GCS (#844)
* Add a build task to upload ER diagrams to GCS

* Merge ER diagram task into cloudbuild-javadoc
2020-10-27 10:41:12 -04:00
Michael Muller 86bdd154bc Restore ofy keys in GracePeriod objects (#846)
* Restore ofy keys in GracePeriod objects

Restore the ofy keys when loading GracePeriod object from SQL.  There's no
clear way to do this using the normal approach (fix-up during a PostLoad
method) because fixups to these violate immutability after hibernate has
already obtained their hash values.  Instead, we force reconstitution of the
ofy keys in all public methods that access them (including equals() and
hashCode()) so that they can be generated before an invalid hash is generated.

As part of this change, convert the GracePeriod id from an autogenerated
sequence to a UUID allocated from ObjectifyService and enhance ImmutableObject
to allow it to exclude certain fields from hash/equals and print.

The ImmutableObject enhancements are necessary because we compare grace
periods against locally created test objects in a number of unit tests and
there's no way this can work with GracePeriods loaded from SQL currently, as
they will have an identifier field generated from the database and the test
objects will have an identifier field of null (or a new unique value, after
this change).

Removing autogeneration from GracePeriod ids ended up being likely not
strictly necessary for this change (it was a consequence of an earlier
iteration).  However, it does alleviate the problem of mutation of an
immutable object after creation and is more in line with how we've decided to
allocate other identifiers.

* Changed needed after rebase.
2020-10-26 13:38:14 -04:00
sarahcaseybot 576c05ff5f Add certificate checks to RegistrarSettingsAction (#843)
* Add certificate checks to RegistrarSettingsAction

* Add some comments

* Add more functionality to CertificateChecker and update call sites

* Small code cleanups

* Small format fix
2020-10-23 15:46:57 -04:00
gbrodman f52e887db5 Create SQL schema for RdeRevision (#835)
* Create SQL schema for RdeRevision

* Split RdeRevision IDs into three separate DB fields as unified pkey

* Rename variable

* Merge remote-tracking branch 'origin/master' into rdeRevision

* Rename variable in one other location

* Implement no-op toDatastore/Sql for RdeRevision

* Responses to CR

* Merge remote-tracking branch 'origin/master' into rdeRevision

* Use a date for the date column

* Fix exception messages in tests

* Regen diagram to fix the test

* Use assignment in static factory methods

* Merge remote-tracking branch 'origin/master' into rdeRevision
2020-10-23 13:14:07 -04:00
Weimin Yu 6ed286e3bc Upgrade error-prone to 3.3.4 (#848)
* Upgrade error-prone to 3.3.4

This would fix the failure with openjdk 11.0.9 in
3.3.3.

Fixed new antipatterns raised by the new version:
- Replaced unnecessary lambdas with methods.
- Switched wait/sleep calls to equivalent methods using java.time types
- Types inheriting Object.toString() should not be assigned to string
parameter in logging statements.
2020-10-23 11:17:57 -04:00
sarahcaseybot 93d922af6f Add certificate checks for create and update registrar commands (#837)
* Add certificatechecks for create and update registrar commands

* Add CertificateCheckerModule

* Remove commented out code

* Still tring to get dependency injection to work

* Get this actually working

* Add tests for multiple violations

* Small formatting fixes

* Rename configs and fix collectors

* Add checks for failover client certificate

* Fix formatting
2020-10-22 11:43:22 -04:00
gbrodman 0b73e9032c Use a SQL date object for LocalDates (#842)
* Use a SQL date object for LocalDates

* Clean up comment
2020-10-20 15:44:23 -04:00
Shicong Huang 4d5d9700b8 Add a command to generate ER diagram for SQL schema (#839)
* Add a command to generate ER diagram for SQL schema

* Add graphviz as runtime dependency

* Update ER diagrams for #838
2020-10-15 17:31:43 -04:00
Michael Muller 3534a146e4 Restore ofy keys in DomainTransferData (#838)
* Restore ofy keys in DomainTransferData

Restore composite VKeys correctly in DomainTransferData (they were previously
missing their ofy keys).

* Use "AlsoLoad" to populate history ids
2020-10-15 07:54:47 -04:00
169 changed files with 20520 additions and 617 deletions
@@ -1,25 +1,28 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto.value:auto-value:1.6.3
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -24,6 +24,7 @@ import java.time.ZonedDateTime;
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
/** Utilities methods and constants related to Joda {@link DateTime} objects. */
public class DateTimeUtils {
@@ -108,4 +109,12 @@ public class DateTimeUtils {
zonedDateTime.toInstant().toEpochMilli(),
DateTimeZone.forTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone())));
}
public static java.sql.Date toSqlDate(LocalDate localDate) {
return new java.sql.Date(localDate.toDateTimeAtStartOfDay().getMillis());
}
public static LocalDate toLocalDate(java.sql.Date date) {
return new LocalDate(date.getTime(), DateTimeZone.UTC);
}
}
@@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.util.concurrent.Uninterruptibles;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import org.joda.time.ReadableDuration;
@@ -41,6 +40,6 @@ public final class SystemSleeper implements Sleeper, Serializable {
@Override
public void sleepUninterruptibly(ReadableDuration duration) {
checkArgument(duration.getMillis() >= 0);
Uninterruptibles.sleepUninterruptibly(duration.getMillis(), TimeUnit.MILLISECONDS);
Uninterruptibles.sleepUninterruptibly(java.time.Duration.ofMillis(duration.getMillis()));
}
}
+4
View File
@@ -221,6 +221,7 @@ dependencies {
compile deps['com.jcraft:jsch']
testCompile deps['com.thoughtworks.qdox:qdox']
compile deps['dnsjava:dnsjava']
runtime deps['guru.nidi:graphviz-java-all-j2v8']
testCompile deps['io.github.classgraph:classgraph']
testRuntime deps['io.github.java-diff-utils:java-diff-utils']
testCompile deps['javax.annotation:javax.annotation-api']
@@ -258,6 +259,7 @@ dependencies {
compile deps['org.hibernate:hibernate-core']
compile deps['org.joda:joda-money']
compile deps['org.json:json']
compile deps['org.jsoup:jsoup']
testCompile deps['org.mortbay.jetty:jetty']
compile deps['org.postgresql:postgresql']
testCompile deps['org.seleniumhq.selenium:selenium-api']
@@ -271,7 +273,9 @@ dependencies {
testCompile deps['org.testcontainers:selenium']
testCompile deps['org.testcontainers:testcontainers']
compile deps['us.fatehi:schemacrawler']
compile deps['us.fatehi:schemacrawler-api']
compile deps['us.fatehi:schemacrawler-diagram']
compile deps['us.fatehi:schemacrawler-tools']
compile deps['xerces:xmlParserAPIs']
compile deps['xpp3:xpp3']
// This dependency must come after javax.mail:mail as it would otherwise
@@ -1,8 +1,8 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto.value:auto-value:1.6.3
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
@@ -11,11 +11,11 @@ com.google.dagger:dagger-compiler:2.28
com.google.dagger:dagger-producers:2.28
com.google.dagger:dagger-spi:2.28
com.google.dagger:dagger:2.28
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.errorprone:javac-shaded:9-dev-r4023-3
com.google.googlejavaformat:google-java-format:1.5
com.google.guava:failureaccess:1.0.1
@@ -30,11 +30,14 @@ javax.inject:javax.inject:1
javax.persistence:javax.persistence-api:2.2
net.ltgt.gradle.incap:incap:0.2
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:2.11.1
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.61
org.jetbrains.kotlin:kotlin-stdlib:1.3.61
org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0
org.jetbrains:annotations:13.0
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -226,6 +226,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -223,6 +223,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -130,6 +134,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -177,6 +184,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.12
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -198,6 +206,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -228,6 +237,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -242,6 +252,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.14.3
@@ -251,6 +263,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -130,6 +134,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -176,6 +183,7 @@ javax.validation:validation-api:1.0.0.GA
javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -197,6 +205,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -226,6 +235,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -240,6 +250,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.14.3
@@ -249,6 +261,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -226,6 +226,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -225,6 +225,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -129,6 +133,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -176,6 +183,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.12
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -197,6 +205,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -227,6 +236,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -241,6 +251,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.testcontainers:database-commons:1.14.3
org.testcontainers:jdbc:1.14.3
@@ -249,6 +261,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -129,6 +133,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -176,6 +183,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.12
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -197,6 +205,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -227,6 +236,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -241,6 +251,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.testcontainers:database-commons:1.14.3
org.testcontainers:jdbc:1.14.3
@@ -249,6 +261,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -129,6 +133,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -176,6 +183,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.12
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -197,6 +205,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -227,6 +236,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -241,6 +251,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.testcontainers:database-commons:1.14.3
org.testcontainers:jdbc:1.14.3
@@ -249,6 +261,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -130,6 +134,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -176,6 +183,7 @@ javax.validation:validation-api:1.0.0.GA
javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -197,6 +205,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -226,6 +235,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -240,6 +250,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.14.3
@@ -249,6 +261,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -1,8 +1,8 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto.value:auto-value:1.6.3
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
@@ -11,11 +11,11 @@ com.google.dagger:dagger-compiler:2.28
com.google.dagger:dagger-producers:2.28
com.google.dagger:dagger-spi:2.28
com.google.dagger:dagger:2.28
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.errorprone:javac-shaded:9-dev-r4023-3
com.google.googlejavaformat:google-java-format:1.5
com.google.guava:failureaccess:1.0.1
@@ -30,11 +30,14 @@ javax.inject:javax.inject:1
javax.persistence:javax.persistence-api:2.2
net.ltgt.gradle.incap:incap:0.2
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:2.11.1
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.61
org.jetbrains.kotlin:kotlin-stdlib:1.3.61
org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0
org.jetbrains:annotations:13.0
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -248,6 +248,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.junit-pioneer:junit-pioneer:0.7.0
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -247,6 +247,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.junit-pioneer:junit-pioneer:0.7.0
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.11.2
com.fasterxml.jackson.core:jackson-core:2.11.2
com.fasterxml.jackson.core:jackson-databind:2.11.2
@@ -138,6 +142,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.github.java-diff-utils:java-diff-utils:4.0
@@ -186,6 +193,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.13
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy-agent:1.10.5
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
@@ -252,6 +260,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.junit-pioneer:junit-pioneer:0.7.0
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -290,6 +299,8 @@ org.seleniumhq.selenium:selenium-opera-driver:3.141.59
org.seleniumhq.selenium:selenium-remote-driver:3.141.59
org.seleniumhq.selenium:selenium-safari-driver:3.141.59
org.seleniumhq.selenium:selenium-support:3.141.59
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.testcontainers:database-commons:1.14.3
org.testcontainers:jdbc:1.14.3
@@ -300,6 +311,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.11.2
com.fasterxml.jackson.core:jackson-core:2.11.2
com.fasterxml.jackson.core:jackson-databind:2.11.2
@@ -138,6 +142,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.github.java-diff-utils:java-diff-utils:4.0
@@ -186,6 +193,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.13
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy-agent:1.10.5
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
@@ -252,6 +260,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.junit-pioneer:junit-pioneer:0.7.0
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -290,6 +299,8 @@ org.seleniumhq.selenium:selenium-opera-driver:3.141.59
org.seleniumhq.selenium:selenium-remote-driver:3.141.59
org.seleniumhq.selenium:selenium-safari-driver:3.141.59
org.seleniumhq.selenium:selenium-support:3.141.59
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.14.3
@@ -301,6 +312,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -0,0 +1,44 @@
// 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.config;
import com.google.common.collect.ImmutableSortedMap;
import dagger.Module;
import dagger.Provides;
import google.registry.config.RegistryConfig.Config;
import google.registry.util.CertificateChecker;
import google.registry.util.Clock;
import javax.inject.Singleton;
import org.joda.time.DateTime;
/** Dagger module that provides the {@link CertificateChecker} used in the application. */
// TODO(sarahbot@): Move this module to a better location. Possibly flows/. If we decide to move
// CertificateChecker.java to core/ delete this file and inject the CertificateChecker constructor
// instead.
@Module
public abstract class CertificateCheckerModule {
@Provides
@Singleton
static CertificateChecker provideCertificateChecker(
@Config("maxValidityDaysSchedule") ImmutableSortedMap<DateTime, Integer> validityDaysMap,
@Config("expirationWarningDays") int daysToExpiration,
@Config("minimumRsaKeyLength") int minimumRsaKeyLength,
Clock clock) {
return new CertificateChecker(validityDaysMap, daysToExpiration, minimumRsaKeyLength, clock);
}
private CertificateCheckerModule() {}
}
@@ -16,9 +16,12 @@ package google.registry.config;
import static com.google.common.base.Suppliers.memoize;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static google.registry.config.ConfigUtils.makeUrl;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.Comparator.naturalOrder;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
@@ -27,6 +30,7 @@ import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import dagger.Module;
import dagger.Provides;
import google.registry.util.TaskQueueUtils;
@@ -46,6 +50,7 @@ import javax.inject.Qualifier;
import javax.inject.Singleton;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Duration;
@@ -1345,6 +1350,33 @@ public final class RegistryConfig {
public static String provideRdapTosStaticUrl(RegistryConfigSettings config) {
return config.registryPolicy.rdapTosStaticUrl;
}
@Provides
@Config("maxValidityDaysSchedule")
public static ImmutableSortedMap<DateTime, Integer> provideValidityDaysMap(
RegistryConfigSettings config) {
return config.sslCertificateValidation.maxValidityDaysSchedule.entrySet().stream()
.collect(
toImmutableSortedMap(
naturalOrder(),
e ->
e.getKey().equals("START_OF_TIME")
? START_OF_TIME
: DateTime.parse(e.getKey()),
e -> e.getValue()));
}
@Provides
@Config("expirationWarningDays")
public static int provideDaysToExpiration(RegistryConfigSettings config) {
return config.sslCertificateValidation.expirationWarningDays;
}
@Provides
@Config("minimumRsaKeyLength")
public static int provideMinimumRsaKeyLength(RegistryConfigSettings config) {
return config.sslCertificateValidation.minimumRsaKeyLength;
}
}
/** Returns the App Engine project ID, which is based off the environment name. */
@@ -15,6 +15,7 @@
package google.registry.config;
import java.util.List;
import java.util.Map;
/** The POJO that YAML config files are deserialized into. */
public class RegistryConfigSettings {
@@ -38,6 +39,7 @@ public class RegistryConfigSettings {
public Beam beam;
public Keyring keyring;
public RegistryTool registryTool;
public SslCertificateValidation sslCertificateValidation;
/** Configuration options that apply to the entire App Engine project. */
public static class AppEngine {
@@ -218,4 +220,11 @@ public class RegistryConfigSettings {
public String clientSecret;
public String username;
}
/** Configuration for the certificate checker. */
public static class SslCertificateValidation {
public Map<String, Integer> maxValidityDaysSchedule;
public int expirationWarningDays;
public int minimumRsaKeyLength;
}
}
@@ -446,3 +446,17 @@ registryTool:
# OAuth client secret used by the tool.
clientSecret: YOUR_CLIENT_SECRET
username: toolusername
# Configuration options for checking SSL certificates.
sslCertificateValidation:
# A map specifying the maximum amount of days the certificate can be valid.
# The entry key is the date closest before the date the certificate was issued
# and the entry value is the applicable maximum validity days for that certificate.
maxValidityDaysSchedule:
"START_OF_TIME": 825
"2020-09-01T00:00:00Z": 398
# The number of days before a certificate expires that indicates the
# certificate is nearing expiration and warnings should be sent.
expirationWarningDays: 30
# The minimum number of bits an RSA key must contain
minimumRsaKeyLength: 2048
@@ -24,7 +24,6 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.util.CollectionUtils.nullToEmpty;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
@@ -387,7 +386,7 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
private static LoadingCache<VKey<? extends EppResource>, EppResource> createEppResourcesCache(
Duration expiry) {
return CacheBuilder.newBuilder()
.expireAfterWrite(expiry.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(expiry.getMillis()))
.maximumSize(getEppResourceMaxCachedEntries())
.build(CACHE_LOADER);
}
@@ -61,7 +61,17 @@ public abstract class ImmutableObject implements Cloneable {
private boolean equalsImmutableObject(ImmutableObject other) {
return getClass().equals(other.getClass())
&& hashCode() == other.hashCode()
&& ModelUtils.getFieldValues(this).equals(ModelUtils.getFieldValues(other));
&& getSignificantFields().equals(other.getSignificantFields());
}
/**
* Returns the map of significant fields (fields that we care about for purposes of comparison and
* display).
*
* <p>Isolated into a method so that derived classes can override it.
*/
protected Map<Field, Object> getSignificantFields() {
return ModelUtils.getFieldValues(this);
}
@Override
@@ -72,7 +82,7 @@ public abstract class ImmutableObject implements Cloneable {
@Override
public int hashCode() {
if (hashCode == null) {
hashCode = Arrays.hashCode(ModelUtils.getFieldValues(this).values().toArray());
hashCode = Arrays.hashCode(getSignificantFields().values().toArray());
}
return hashCode;
}
@@ -111,7 +121,7 @@ public abstract class ImmutableObject implements Cloneable {
@Override
public String toString() {
NavigableMap<String, Object> sortedFields = new TreeMap<>();
for (Entry<Field, Object> entry : ModelUtils.getFieldValues(this).entrySet()) {
for (Entry<Field, Object> entry : getSignificantFields().entrySet()) {
sortedFields.put(entry.getKey().getName(), entry.getValue());
}
return toStringHelper(sortedFields);
@@ -121,7 +131,7 @@ public abstract class ImmutableObject implements Cloneable {
public String toHydratedString() {
// We can't use ImmutableSortedMap because we need to allow null values.
NavigableMap<String, Object> sortedFields = new TreeMap<>();
for (Entry<Field, Object> entry : ModelUtils.getFieldValues(this).entrySet()) {
for (Entry<Field, Object> entry : getSignificantFields().entrySet()) {
Field field = entry.getKey();
Object value = entry.getValue();
sortedFields.put(
@@ -161,7 +171,7 @@ public abstract class ImmutableObject implements Cloneable {
// LinkedHashMap to preserve field ordering and because ImmutableMap forbids null
// values.
Map<String, Object> result = new LinkedHashMap<>();
for (Entry<Field, Object> entry : ModelUtils.getFieldValues(o).entrySet()) {
for (Entry<Field, Object> entry : ((ImmutableObject) o).getSignificantFields().entrySet()) {
Field field = entry.getKey();
if (!field.isAnnotationPresent(IgnoredInDiffableMap.class)) {
result.put(field.getName(), toMapRecursive(entry.getValue()));
@@ -194,7 +194,7 @@ public class ModelUtils {
* returned map in its implementation of {@link ImmutableObject#toString} and {@link
* ImmutableObject#equals}, which work by comparing and printing these maps.
*/
static Map<Field, Object> getFieldValues(Object instance) {
public static Map<Field, Object> getFieldValues(Object instance) {
// Don't make this ImmutableMap because field values can be null.
Map<Field, Object> values = new LinkedHashMap<>();
for (Field field : getAllFields(instance.getClass()).values()) {
@@ -59,25 +59,11 @@ public class OteStats {
private OteStats() {}
private static final Predicate<EppInput> HAS_CLAIMS_NOTICE =
eppInput -> {
Optional<LaunchCreateExtension> launchCreate =
eppInput.getSingleExtension(LaunchCreateExtension.class);
return launchCreate.isPresent() && launchCreate.get().getNotice() != null;
};
private static final Predicate<EppInput> HAS_SEC_DNS =
eppInput ->
eppInput.getSingleExtension(SecDnsCreateExtension.class).isPresent()
|| eppInput.getSingleExtension(SecDnsUpdateExtension.class).isPresent();
private static final Predicate<EppInput> IS_SUNRISE =
eppInput -> {
Optional<LaunchCreateExtension> launchCreate =
eppInput.getSingleExtension(LaunchCreateExtension.class);
return launchCreate.isPresent() && !isNullOrEmpty(launchCreate.get().getSignedMarks());
};
private static final Predicate<EppInput> IS_IDN =
eppInput ->
((DomainCommand.Create)
@@ -94,6 +80,18 @@ public class OteStats {
.getResourceCommand())
.getInetAddresses());
private static boolean hasClaimsNotice(EppInput eppInput) {
Optional<LaunchCreateExtension> launchCreate =
eppInput.getSingleExtension(LaunchCreateExtension.class);
return launchCreate.isPresent() && launchCreate.get().getNotice() != null;
}
private static boolean isSunrise(EppInput eppInput) {
Optional<LaunchCreateExtension> launchCreate =
eppInput.getSingleExtension(LaunchCreateExtension.class);
return launchCreate.isPresent() && !isNullOrEmpty(launchCreate.get().getSignedMarks());
}
/** Enum defining the distinct statistics (types of registrar actions) to record. */
public enum StatType {
CONTACT_CREATES(0, equalTo(Type.CONTACT_CREATE)),
@@ -107,8 +105,8 @@ public class OteStats {
DOMAIN_CREATES(0, equalTo(Type.DOMAIN_CREATE)),
DOMAIN_CREATES_ASCII(1, equalTo(Type.DOMAIN_CREATE), IS_IDN.negate()),
DOMAIN_CREATES_IDN(1, equalTo(Type.DOMAIN_CREATE), IS_IDN),
DOMAIN_CREATES_START_DATE_SUNRISE(1, equalTo(Type.DOMAIN_CREATE), IS_SUNRISE),
DOMAIN_CREATES_WITH_CLAIMS_NOTICE(1, equalTo(Type.DOMAIN_CREATE), HAS_CLAIMS_NOTICE),
DOMAIN_CREATES_START_DATE_SUNRISE(1, equalTo(Type.DOMAIN_CREATE), OteStats::isSunrise),
DOMAIN_CREATES_WITH_CLAIMS_NOTICE(1, equalTo(Type.DOMAIN_CREATE), OteStats::hasClaimsNotice),
DOMAIN_CREATES_WITH_FEE(
1,
equalTo(Type.DOMAIN_CREATE),
@@ -303,14 +303,13 @@ public class DomainContent extends EppResource
allContacts.stream().map(DesignatedContact::reconstitute).collect(toImmutableSet());
setContactFields(allContacts, true);
// We have to return the cloned object here because the original object's
// hashcode is not correct due to the change to its domainRepoId. The cloned
// object will have a null hashcode so that it can get a recalculated hashcode
// when its hashCode() is invoked.
// We have to return the cloned object here because the original object's hashcode is not
// correct due to the change to its domainRepoId and history ids. The cloned object will have a
// null hashcode so that it can get a recalculated hashcode when its hashCode() is invoked.
// TODO(b/162739503): Remove this after fully migrating to Cloud SQL.
gracePeriods =
nullToEmptyImmutableCopy(gracePeriods).stream()
.map(gracePeriod -> gracePeriod.cloneWithDomainRepoId(getRepoId()))
.map(gracePeriod -> gracePeriod.cloneAfterOfyLoad(getRepoId()))
.collect(toImmutableSet());
// Restore history record ids.
@@ -352,9 +351,13 @@ public class DomainContent extends EppResource
restoreOfyFrom(myKey, autorenewBillingEvent, autorenewBillingEventHistoryId);
autorenewPollMessage =
restoreOfyFrom(myKey, autorenewPollMessage, autorenewPollMessageHistoryId);
if (transferData != null) {
transferData.restoreOfyKeys(myKey);
}
}
private <T> VKey<T> restoreOfyFrom(Key<DomainBase> domainKey, VKey<T> key, Long historyId) {
public static <T> VKey<T> restoreOfyFrom(Key<DomainBase> domainKey, VKey<T> key, Long historyId) {
if (historyId == null) {
// This is a legacy key (or a null key, in which case this works too)
return VKey.restoreOfyFrom(key, EntityGroupRoot.class, "per-tld");
@@ -716,7 +719,14 @@ public class DomainContent extends EppResource
+ " use DomainBase instead");
}
private static Long getHistoryId(VKey<?> key) {
/**
* Obtains a history id from the given key.
*
* <p>The key must be a composite key either of the form domain-key/history-key/long-event-key or
* EntityGroupRoot/long-event-key (for legacy keys). In the latter case or for a null key returns
* a history id of null.
*/
public static Long getHistoryId(VKey<?> key) {
if (key == null) {
return null;
}
@@ -21,6 +21,7 @@ import com.googlecode.objectify.annotation.Embed;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Recurring;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.ofy.ObjectifyService;
import google.registry.persistence.VKey;
import google.registry.schema.replay.DatastoreAndSqlEntity;
import javax.annotation.Nullable;
@@ -53,12 +54,15 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
(billingEventRecurring != null) == GracePeriodStatus.AUTO_RENEW.equals(type),
"Recurring billing events must be present on (and only on) autorenew grace periods");
GracePeriod instance = new GracePeriod();
instance.id = ObjectifyService.allocateId();
instance.type = checkArgumentNotNull(type);
instance.domainRepoId = checkArgumentNotNull(domainRepoId);
instance.expirationTime = checkArgumentNotNull(expirationTime);
instance.clientId = checkArgumentNotNull(clientId);
instance.billingEventOneTime = billingEventOneTime;
instance.billingEventOneTimeHistoryId = DomainBase.getHistoryId(billingEventOneTime);
instance.billingEventRecurring = billingEventRecurring;
instance.billingEventRecurringHistoryId = DomainBase.getHistoryId(billingEventRecurring);
return instance;
}
@@ -108,14 +112,16 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
}
/**
* Returns a clone of this {@link GracePeriod} with {@link #domainRepoId} set to the given value.
* Returns a clone of this {@link GracePeriod} with {@link #domainRepoId} set to the given value
* and reconstructed history ids.
*
* <p>TODO(b/162739503): Remove this function after fully migrating to Cloud SQL.
*/
public GracePeriod cloneWithDomainRepoId(String domainRepoId) {
public GracePeriod cloneAfterOfyLoad(String domainRepoId) {
GracePeriod clone = clone(this);
clone.id = ObjectifyService.allocateId();
clone.domainRepoId = checkArgumentNotNull(domainRepoId);
clone.restoreHistoryIds();
return clone;
}
}
@@ -14,18 +14,21 @@
package google.registry.model.domain;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Ignore;
import google.registry.model.ImmutableObject;
import google.registry.model.ModelUtils;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.OneTime;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.persistence.VKey;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.MappedSuperclass;
import org.joda.time.DateTime;
@@ -36,7 +39,6 @@ public class GracePeriodBase extends ImmutableObject {
/** Unique id required for hibernate representation. */
@javax.persistence.Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Ignore
Long id;
@@ -67,6 +69,10 @@ public class GracePeriodBase extends ImmutableObject {
@Column(name = "billing_event_id")
VKey<OneTime> billingEventOneTime = null;
@Ignore
@Column(name = "billing_event_history_id")
Long billingEventOneTimeHistoryId;
/**
* The recurring billing event corresponding to the action that triggered this grace period, if
* applicable - i.e. if the action was an autorenew - or null in all other cases.
@@ -75,6 +81,14 @@ public class GracePeriodBase extends ImmutableObject {
@Column(name = "billing_recurrence_id")
VKey<BillingEvent.Recurring> billingEventRecurring = null;
@Ignore
@Column(name = "billing_recurrence_history_id")
Long billingEventRecurringHistoryId;
public long getId() {
return id;
}
public GracePeriodStatus getType() {
return type;
}
@@ -101,6 +115,7 @@ public class GracePeriodBase extends ImmutableObject {
* period is not AUTO_RENEW.
*/
public VKey<BillingEvent.OneTime> getOneTimeBillingEvent() {
restoreOfyKeys();
return billingEventOneTime;
}
@@ -109,6 +124,63 @@ public class GracePeriodBase extends ImmutableObject {
* period is AUTO_RENEW.
*/
public VKey<BillingEvent.Recurring> getRecurringBillingEvent() {
restoreOfyKeys();
return billingEventRecurring;
}
/**
* Restores history ids for composite VKeys after a load from datastore.
*
* <p>For use by DomainContent.load() ONLY.
*/
protected void restoreHistoryIds() {
billingEventOneTimeHistoryId = DomainBase.getHistoryId(billingEventOneTime);
billingEventRecurringHistoryId = DomainBase.getHistoryId(billingEventRecurring);
}
/**
* Override {@link ImmutableObject#getSignificantFields()} to exclude "id", which breaks equality
* testing in the unit tests.
*/
@Override
protected Map<Field, Object> getSignificantFields() {
restoreOfyKeys();
// Can't use streams or ImmutableMap because we can have null values.
Map<Field, Object> result = new LinkedHashMap();
for (Map.Entry<Field, Object> entry : ModelUtils.getFieldValues(this).entrySet()) {
if (!entry.getKey().getName().equals("id")) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
/**
* Restores Ofy keys in the billing events.
*
* <p>This must be called by all methods that access the one time or recurring billing event keys.
* When the billing event keys are loaded from SQL, they are loaded as asymmetric keys because the
* database columns that we load them from do not contain all of the information necessary to
* reconsitute the Ofy side of the key. In other cases, we restore the Ofy key during the
* hibernate {@link javax.persistence.PostLoad} method from the other fields of the object, but we
* have been unable to make this work with hibernate's internal persistence model in this case
* because the {@link GracePeriod}'s hash code is evaluated prior to these calls, and would be
* invalidated by changing the fields.
*/
private final synchronized void restoreOfyKeys() {
if (billingEventOneTime != null && !billingEventOneTime.maybeGetOfyKey().isPresent()) {
billingEventOneTime =
DomainBase.restoreOfyFrom(
Key.create(DomainBase.class, domainRepoId),
billingEventOneTime,
billingEventOneTimeHistoryId);
}
if (billingEventRecurring != null && !billingEventRecurring.maybeGetOfyKey().isPresent()) {
billingEventRecurring =
DomainBase.restoreOfyFrom(
Key.create(DomainBase.class, domainRepoId),
billingEventRecurring,
billingEventRecurringHistoryId);
}
}
}
@@ -20,7 +20,6 @@ import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntri
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.TypeUtils.instantiate;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
@@ -244,7 +243,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
private static LoadingCache<Key<ForeignKeyIndex<?>>, Optional<ForeignKeyIndex<?>>>
createForeignKeyIndexesCache(Duration expiry) {
return CacheBuilder.newBuilder()
.expireAfterWrite(expiry.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(expiry.getMillis()))
.maximumSize(getEppResourceMaxCachedEntries())
.build(CACHE_LOADER);
}
@@ -15,17 +15,32 @@
package google.registry.model.rde;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
import static com.google.common.base.Verify.verifyNotNull;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.rde.RdeNamingUtils.makePartialName;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import google.registry.model.BackupGroupRoot;
import google.registry.model.ImmutableObject;
import google.registry.model.rde.RdeRevision.RdeRevisionId;
import google.registry.persistence.VKey;
import google.registry.persistence.converter.LocalDateConverter;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import java.io.Serializable;
import java.util.Optional;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.IdClass;
import javax.persistence.Transient;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
/**
* Datastore entity for tracking RDE revisions.
@@ -35,32 +50,67 @@ import org.joda.time.DateTime;
* flag is included in the generated XML.
*/
@Entity
public final class RdeRevision extends ImmutableObject {
@javax.persistence.Entity
@IdClass(RdeRevisionId.class)
public final class RdeRevision extends BackupGroupRoot implements DatastoreEntity, SqlEntity {
/** String triplet of tld, date, and mode, e.g. {@code soy_2015-09-01_full}. */
@Id
String id;
@Id @Transient String id;
@javax.persistence.Id @Ignore String tld;
@javax.persistence.Id @Ignore LocalDate date;
@javax.persistence.Id @Ignore RdeMode mode;
/**
* Number of last revision successfully staged to GCS.
*
* <p>This values begins at zero upon object creation and thenceforth incremented transactionally.
*/
@Column(nullable = false)
int revision;
/** Hibernate requires an empty constructor. */
private RdeRevision() {}
public static RdeRevision create(
String id, String tld, LocalDate date, RdeMode mode, int revision) {
RdeRevision instance = new RdeRevision();
instance.id = id;
instance.tld = tld;
instance.date = date;
instance.mode = mode;
instance.revision = revision;
return instance;
}
public int getRevision() {
return revision;
}
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // we don't care about RdeRevision history
}
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // we don't care about RdeRevision history
}
/**
* Returns next revision ID to use when staging a new deposit file for the given triplet.
*
* @return {@code 0} for first deposit generation and {@code >0} for resends
*/
public static int getNextRevision(String tld, DateTime date, RdeMode mode) {
RdeRevision object =
ofy().load().type(RdeRevision.class).id(makePartialName(tld, date, mode)).now();
return object == null ? 0 : object.revision + 1;
String id = makePartialName(tld, date, mode);
RdeRevisionId sqlKey = RdeRevisionId.create(tld, date.toLocalDate(), mode);
Key<RdeRevision> ofyKey = Key.create(RdeRevision.class, id);
Optional<RdeRevision> revisionOptional =
tm().maybeLoad(VKey.create(RdeRevision.class, sqlKey, ofyKey));
return revisionOptional.map(rdeRevision -> rdeRevision.revision + 1).orElse(0);
}
/**
@@ -76,17 +126,56 @@ public final class RdeRevision extends ImmutableObject {
checkArgument(revision >= 0, "Negative revision: %s", revision);
String triplet = makePartialName(tld, date, mode);
tm().assertInTransaction();
RdeRevision object = ofy().load().type(RdeRevision.class).id(triplet).now();
RdeRevisionId sqlKey = RdeRevisionId.create(tld, date.toLocalDate(), mode);
Key<RdeRevision> ofyKey = Key.create(RdeRevision.class, triplet);
Optional<RdeRevision> revisionOptional =
tm().maybeLoad(VKey.create(RdeRevision.class, sqlKey, ofyKey));
if (revision == 0) {
verify(object == null, "RdeRevision object already created: %s", object);
revisionOptional.ifPresent(
rdeRevision -> {
throw new IllegalArgumentException(
String.format(
"RdeRevision object already created and revision 0 specified: %s",
rdeRevision));
});
} else {
verifyNotNull(object, "RDE revision object missing for %s?! revision=%s", triplet, revision);
verify(object.revision == revision - 1,
"RDE revision object should be at %s but was: %s", revision - 1, object);
checkArgument(
revisionOptional.isPresent(),
"Couldn't find existing RDE revision %s when trying to save new revision %s",
triplet,
revision);
checkArgument(
revisionOptional.get().revision == revision - 1,
"RDE revision object should be at revision %s but was: %s",
revision - 1,
revisionOptional.get());
}
RdeRevision object = RdeRevision.create(triplet, tld, date.toLocalDate(), mode, revision);
tm().put(object);
}
/** Class to represent the composite primary key of {@link RdeRevision} entity. */
static class RdeRevisionId extends ImmutableObject implements Serializable {
String tld;
// Auto-conversion doesn't work for ID classes, we must specify @Column and @Convert
@Column(columnDefinition = "date")
@Convert(converter = LocalDateConverter.class)
LocalDate date;
@Enumerated(EnumType.STRING)
RdeMode mode;
/** Hibernate requires this default constructor. */
private RdeRevisionId() {}
static RdeRevisionId create(String tld, LocalDate date, RdeMode mode) {
RdeRevisionId instance = new RdeRevisionId();
instance.tld = tld;
instance.date = date;
instance.mode = mode;
return instance;
}
object = new RdeRevision();
object.id = triplet;
object.revision = revision;
ofy().save().entity(object);
}
}
@@ -28,7 +28,6 @@ import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.joda.money.CurrencyUnit.USD;
import com.google.common.annotations.VisibleForTesting;
@@ -260,7 +259,8 @@ public class Registry extends ImmutableObject implements Buildable, DatastoreAnd
/** A cache that loads the {@link Registry} for a given tld. */
private static final LoadingCache<String, Optional<Registry>> CACHE =
CacheBuilder.newBuilder()
.expireAfterWrite(getSingletonCacheRefreshDuration().getMillis(), MILLISECONDS)
.expireAfterWrite(
java.time.Duration.ofMillis(getSingletonCacheRefreshDuration().getMillis()))
.build(
new CacheLoader<String, Optional<Registry>>() {
@Override
@@ -25,7 +25,6 @@ import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static google.registry.model.ofy.ObjectifyService.allocateId;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
@@ -197,7 +196,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
@VisibleForTesting
static LoadingCache<String, PremiumList> createCachePremiumLists(Duration cachePersistDuration) {
return CacheBuilder.newBuilder()
.expireAfterWrite(cachePersistDuration.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(cachePersistDuration.getMillis()))
.build(
new CacheLoader<String, PremiumList>() {
@Override
@@ -221,7 +220,8 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
static final LoadingCache<Key<PremiumListRevision>, PremiumListRevision>
cachePremiumListRevisions =
CacheBuilder.newBuilder()
.expireAfterWrite(getSingletonCachePersistDuration().getMillis(), MILLISECONDS)
.expireAfterWrite(
java.time.Duration.ofMillis(getSingletonCachePersistDuration().getMillis()))
.build(
new CacheLoader<Key<PremiumListRevision>, PremiumListRevision>() {
@Override
@@ -260,14 +260,14 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
static LoadingCache<Key<PremiumListEntry>, Optional<PremiumListEntry>>
createCachePremiumListEntries(Duration cachePersistDuration) {
return CacheBuilder.newBuilder()
.expireAfterWrite(cachePersistDuration.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(cachePersistDuration.getMillis()))
.maximumSize(getStaticPremiumListMaxCachedEntries())
.build(
new CacheLoader<Key<PremiumListEntry>, Optional<PremiumListEntry>>() {
@Override
public Optional<PremiumListEntry> load(final Key<PremiumListEntry> entryKey) {
return tm()
.doTransactionless(() -> Optional.ofNullable(ofy().load().key(entryKey).now()));
return tm().doTransactionless(
() -> Optional.ofNullable(ofy().load().key(entryKey).now()));
}
});
}
@@ -20,7 +20,6 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.config.RegistryConfig.getDomainLabelListCacheDuration;
import static google.registry.model.registry.label.ReservationType.FULLY_BLOCKED;
import static google.registry.util.CollectionUtils.nullToEmpty;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.base.Splitter;
@@ -241,7 +240,8 @@ public final class ReservedList
private static LoadingCache<String, ReservedList> cache =
CacheBuilder.newBuilder()
.expireAfterWrite(getDomainLabelListCacheDuration().getMillis(), MILLISECONDS)
.expireAfterWrite(
java.time.Duration.ofMillis(getDomainLabelListCacheDuration().getMillis()))
.build(
new CacheLoader<String, ReservedList>() {
@Override
@@ -75,7 +75,7 @@ public class Spec11ThreatMatch extends ImmutableObject implements Buildable, Sql
String registrarId;
/** Date on which the check was run, on which the domain was flagged as abusive. */
@Column(nullable = false)
@Column(nullable = false, columnDefinition = "date")
LocalDate checkDate;
/** The domain's top-level domain. */
@@ -16,23 +16,25 @@ package google.registry.model.reporting;
import com.google.common.collect.ImmutableList;
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.util.DateTimeUtils;
import javax.persistence.TemporalType;
import org.joda.time.LocalDate;
/**
* Data access object for {@link google.registry.model.reporting.Spec11ThreatMatch}.
*
* <p>A JpaTransactionManager is passed into each static method because they are called from a BEAM
* pipeline and we don't know where it's coming from.</p>
* pipeline and we don't know where it's coming from.
*/
public class Spec11ThreatMatchDao {
/** Delete all entries with the specified date from the database. */
public static void deleteEntriesByDate(JpaTransactionManager jpaTm, LocalDate date) {
jpaTm.assertInTransaction();
jpaTm
.getEntityManager()
.createQuery("DELETE FROM Spec11ThreatMatch WHERE check_date = :date")
.setParameter("date", date.toString())
.setParameter("date", DateTimeUtils.toSqlDate(date), TemporalType.DATE)
.executeUpdate();
}
@@ -57,7 +57,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
@@ -146,8 +145,7 @@ public class ClaimsListShard extends ImmutableObject implements DatastoreAndSqlE
private static final Retrier LOADER_RETRIER = new Retrier(new SystemSleeper(), 2);
private static final Callable<ClaimsListShard> LOADER_CALLABLE =
() -> {
private static ClaimsListShard loadClaimsListShard() {
// Find the most recent revision.
Key<ClaimsListRevision> revisionKey = getCurrentRevision();
@@ -246,7 +244,9 @@ public class ClaimsListShard extends ImmutableObject implements DatastoreAndSqlE
*/
private static final Supplier<ClaimsListShard> CACHE =
memoizeWithShortExpiration(
() -> LOADER_RETRIER.callWithRetry(LOADER_CALLABLE, IllegalStateException.class));
() ->
LOADER_RETRIER.callWithRetry(
ClaimsListShard::loadClaimsListShard, IllegalStateException.class));
/** Returns the revision id of this claims list, or throws exception if it is null. */
public Long getRevisionId() {
@@ -14,12 +14,16 @@
package google.registry.model.transfer;
import com.google.common.annotations.VisibleForTesting;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.AlsoLoad;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Unindex;
import com.googlecode.objectify.condition.IfNull;
import google.registry.model.billing.BillingEvent;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.Period;
import google.registry.model.domain.Period.Unit;
import google.registry.model.poll.PollMessage;
@@ -86,6 +90,10 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
@Column(name = "transfer_billing_event_id")
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
@Ignore
@Column(name = "transfer_billing_event_history_id")
Long serverApproveBillingEventHistoryId;
/**
* The autorenew billing event that should be associated with this resource after the transfer.
*
@@ -96,6 +104,10 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
@Column(name = "transfer_billing_recurrence_id")
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
@Ignore
@Column(name = "transfer_billing_recurrence_history_id")
Long serverApproveAutorenewEventHistoryId;
/**
* The autorenew poll message that should be associated with this resource after the transfer.
*
@@ -106,11 +118,50 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
@Column(name = "transfer_autorenew_poll_message_id")
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage;
@Ignore
@Column(name = "transfer_autorenew_poll_message_history_id")
Long serverApproveAutorenewPollMessageHistoryId;
@Override
public Builder copyConstantFieldsToBuilder() {
return super.copyConstantFieldsToBuilder().setTransferPeriod(this.transferPeriod);
}
/**
* Restores the set of ofy keys after loading from SQL using the specified {@code rootKey}.
*
* <p>This is for use by DomainBase/DomainHistory PostLoad methods ONLY.
*/
public void restoreOfyKeys(Key<DomainBase> rootKey) {
serverApproveBillingEvent =
DomainBase.restoreOfyFrom(
rootKey, serverApproveBillingEvent, serverApproveBillingEventHistoryId);
serverApproveAutorenewEvent =
DomainBase.restoreOfyFrom(
rootKey, serverApproveAutorenewEvent, serverApproveAutorenewEventHistoryId);
serverApproveAutorenewPollMessage =
DomainBase.restoreOfyFrom(
rootKey, serverApproveAutorenewPollMessage, serverApproveAutorenewPollMessageHistoryId);
}
@SuppressWarnings("unused") // For Hibernate.
private void loadServerApproveBillingEventHistoryId(
@AlsoLoad("serverApproveBillingEvent") VKey<BillingEvent.OneTime> val) {
serverApproveBillingEventHistoryId = DomainBase.getHistoryId(val);
}
@SuppressWarnings("unused") // For Hibernate.
private void loadServerApproveAutorenewEventHistoryId(
@AlsoLoad("serverApproveAutorenewEvent") VKey<BillingEvent.Recurring> val) {
serverApproveAutorenewEventHistoryId = DomainBase.getHistoryId(val);
}
@SuppressWarnings("unused") // For Hibernate.
private void loadServerApproveAutorenewPollMessageHistoryId(
@AlsoLoad("serverApproveAutorenewPollMessage") VKey<PollMessage.Autorenew> val) {
serverApproveAutorenewPollMessageHistoryId = DomainBase.getHistoryId(val);
}
public Period getTransferPeriod() {
return transferPeriod;
}
@@ -125,16 +176,34 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
return serverApproveBillingEvent;
}
@VisibleForTesting
@Nullable
public Long getServerApproveBillingEventHistoryId() {
return serverApproveBillingEventHistoryId;
}
@Nullable
public VKey<BillingEvent.Recurring> getServerApproveAutorenewEvent() {
return serverApproveAutorenewEvent;
}
@VisibleForTesting
@Nullable
public Long getServerApproveAutorenewEventHistoryId() {
return serverApproveAutorenewEventHistoryId;
}
@Nullable
public VKey<PollMessage.Autorenew> getServerApproveAutorenewPollMessage() {
return serverApproveAutorenewPollMessage;
}
@VisibleForTesting
@Nullable
public Long getServerApproveAutorenewPollMessageHistoryId() {
return serverApproveAutorenewPollMessageHistoryId;
}
@Override
public boolean isEmpty() {
return EMPTY.equals(this);
@@ -168,18 +237,24 @@ public class DomainTransferData extends TransferData<DomainTransferData.Builder>
public Builder setServerApproveBillingEvent(
VKey<BillingEvent.OneTime> serverApproveBillingEvent) {
getInstance().serverApproveBillingEvent = serverApproveBillingEvent;
getInstance().serverApproveBillingEventHistoryId =
DomainBase.getHistoryId(serverApproveBillingEvent);
return this;
}
public Builder setServerApproveAutorenewEvent(
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent) {
getInstance().serverApproveAutorenewEvent = serverApproveAutorenewEvent;
getInstance().serverApproveAutorenewEventHistoryId =
DomainBase.getHistoryId(serverApproveAutorenewEvent);
return this;
}
public Builder setServerApproveAutorenewPollMessage(
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage) {
getInstance().serverApproveAutorenewPollMessage = serverApproveAutorenewPollMessage;
getInstance().serverApproveAutorenewPollMessageHistoryId =
DomainBase.getHistoryId(serverApproveAutorenewPollMessage);
return this;
}
}
@@ -22,7 +22,6 @@ import google.registry.request.RequestHandler;
import google.registry.util.SystemClock;
import java.io.IOException;
import java.security.Security;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -51,13 +50,16 @@ public class ServletBase extends HttpServlet {
// etc), we log the error but keep the main thread running. Also the shutdown hook will only be
// registered if metric reporter starts up correctly.
try {
metricReporter.get().startAsync().awaitRunning(10, TimeUnit.SECONDS);
metricReporter.get().startAsync().awaitRunning(java.time.Duration.ofSeconds(10));
logger.atInfo().log("Started up MetricReporter");
LifecycleManager.getInstance()
.setShutdownHook(
() -> {
try {
metricReporter.get().stopAsync().awaitTerminated(10, TimeUnit.SECONDS);
metricReporter
.get()
.stopAsync()
.awaitTerminated(java.time.Duration.ofSeconds(10));
logger.atInfo().log("Shut down MetricReporter");
} catch (TimeoutException e) {
logger.atSevere().withCause(e).log("Failed to stop MetricReporter.");
@@ -17,6 +17,7 @@ package google.registry.module.frontend;
import com.google.monitoring.metrics.MetricReporter;
import dagger.Component;
import dagger.Lazy;
import google.registry.config.CertificateCheckerModule;
import google.registry.config.CredentialModule;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.flows.ServerTridProviderModule;
@@ -44,6 +45,7 @@ import javax.inject.Singleton;
@Component(
modules = {
AuthModule.class,
CertificateCheckerModule.class,
ConfigModule.class,
ConsoleConfigModule.class,
CredentialModule.class,
@@ -14,17 +14,23 @@
package google.registry.persistence.converter;
import google.registry.util.DateTimeUtils;
import java.sql.Date;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.joda.time.LocalDate;
import org.joda.time.format.ISODateTimeFormat;
/** JPA converter for {@link LocalDate}. */
/** JPA converter for {@link LocalDate}, to/from {@link Date}. */
@Converter(autoApply = true)
public class LocalDateConverter extends ToStringConverterBase<LocalDate> {
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {
/** Converts the string (a date in ISO-8601 format) into a LocalDate. */
@Override
public LocalDate convertToEntityAttribute(String columnValue) {
return (columnValue == null) ? null : LocalDate.parse(columnValue, ISODateTimeFormat.date());
public Date convertToDatabaseColumn(LocalDate attribute) {
return attribute == null ? null : DateTimeUtils.toSqlDate(attribute);
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return dbData == null ? null : DateTimeUtils.toLocalDate(dbData);
}
}
@@ -18,7 +18,6 @@ import static google.registry.config.RegistryConfig.getDomainLabelListCacheDurat
import static google.registry.config.RegistryConfig.getSingletonCachePersistDuration;
import static google.registry.config.RegistryConfig.getStaticPremiumListMaxCachedEntries;
import static google.registry.schema.tld.PremiumListDao.getPriceForLabel;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
@@ -48,7 +47,7 @@ class PremiumListCache {
static LoadingCache<String, Optional<PremiumList>> createCachePremiumLists(
Duration cachePersistDuration) {
return CacheBuilder.newBuilder()
.expireAfterWrite(cachePersistDuration.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(cachePersistDuration.getMillis()))
.build(
new CacheLoader<String, Optional<PremiumList>>() {
@Override
@@ -81,7 +80,7 @@ class PremiumListCache {
static LoadingCache<RevisionIdAndLabel, Optional<BigDecimal>> createCachePremiumEntries(
Duration cachePersistDuration) {
return CacheBuilder.newBuilder()
.expireAfterWrite(cachePersistDuration.getMillis(), MILLISECONDS)
.expireAfterWrite(java.time.Duration.ofMillis(cachePersistDuration.getMillis()))
.maximumSize(getStaticPremiumListMaxCachedEntries())
.build(
new CacheLoader<RevisionIdAndLabel, Optional<BigDecimal>>() {
@@ -18,7 +18,6 @@ import static google.registry.config.RegistryConfig.ConfigModule.TmchCaMode.PILO
import static google.registry.config.RegistryConfig.ConfigModule.TmchCaMode.PRODUCTION;
import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@@ -77,7 +76,8 @@ public final class TmchCertificateAuthority {
*/
private static final LoadingCache<TmchCaMode, X509CRL> CRL_CACHE =
CacheBuilder.newBuilder()
.expireAfterWrite(getSingletonCacheRefreshDuration().getMillis(), MILLISECONDS)
.expireAfterWrite(
java.time.Duration.ofMillis(getSingletonCacheRefreshDuration().getMillis()))
.build(
new CacheLoader<TmchCaMode, X509CRL>() {
@Override
@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import java.io.File;
import java.util.function.Predicate;
/**
* Compares two Datastore backups in V3 format on local file system. This is for use in tests and
@@ -30,8 +29,10 @@ import java.util.function.Predicate;
*/
class CompareDbBackups {
private static final String DS_V3_BACKUP_FILE_PREFIX = "output-";
private static final Predicate<File> DATA_FILE_MATCHER =
file -> file.isFile() && file.getName().startsWith(DS_V3_BACKUP_FILE_PREFIX);
private static boolean isDatastoreV3File(File file) {
return file.isFile() && file.getName().startsWith(DS_V3_BACKUP_FILE_PREFIX);
}
public static void main(String[] args) {
if (args.length != 2) {
@@ -40,9 +41,11 @@ class CompareDbBackups {
}
ImmutableSet<EntityWrapper> entities1 =
RecordAccumulator.readDirectory(new File(args[0]), DATA_FILE_MATCHER).getEntityWrapperSet();
RecordAccumulator.readDirectory(new File(args[0]), CompareDbBackups::isDatastoreV3File)
.getEntityWrapperSet();
ImmutableSet<EntityWrapper> entities2 =
RecordAccumulator.readDirectory(new File(args[1]), DATA_FILE_MATCHER).getEntityWrapperSet();
RecordAccumulator.readDirectory(new File(args[1]), CompareDbBackups::isDatastoreV3File)
.getEntityWrapperSet();
// Calculate the entities added and removed.
SetView<EntityWrapper> added = Sets.difference(entities2, entities1);
@@ -38,6 +38,7 @@ import google.registry.tools.params.OptionalLongParameter;
import google.registry.tools.params.OptionalPhoneNumberParameter;
import google.registry.tools.params.OptionalStringParameter;
import google.registry.tools.params.PathParameter;
import google.registry.util.CertificateChecker;
import google.registry.util.CidrAddressBlock;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -49,6 +50,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
@@ -57,9 +59,9 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
static final FluentLogger logger = FluentLogger.forEnclosingClass();
@Parameter(
description = "Client identifier of the registrar account",
required = true)
@Inject CertificateChecker certificateChecker;
@Parameter(description = "Client identifier of the registrar account", required = true)
List<String> mainParameters;
@Parameter(
@@ -356,11 +358,21 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
}
if (clientCertificateFilename != null) {
String asciiCert = new String(Files.readAllBytes(clientCertificateFilename), US_ASCII);
// An empty certificate file is allowed in order to provide a functionality for removing an
// existing certificate without providing a replacement. An uploaded empty certificate file
// will prevent the registrar from being able to establish EPP connections.
if (!asciiCert.equals("")) {
certificateChecker.validateCertificate(asciiCert);
}
builder.setClientCertificate(asciiCert, now);
}
if (failoverClientCertificateFilename != null) {
String asciiCert =
new String(Files.readAllBytes(failoverClientCertificateFilename), US_ASCII);
if (!asciiCert.equals("")) {
certificateChecker.validateCertificate(asciiCert);
}
builder.setFailoverClientCertificate(asciiCert, now);
}
if (!isNullOrEmpty(clientCertificateHash)) {
@@ -20,6 +20,7 @@ import dagger.Lazy;
import google.registry.batch.BatchModule;
import google.registry.beam.initsql.BeamJpaModule;
import google.registry.bigquery.BigqueryModule;
import google.registry.config.CertificateCheckerModule;
import google.registry.config.CredentialModule.LocalCredentialJson;
import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryConfig.ConfigModule;
@@ -60,6 +61,7 @@ import javax.inject.Singleton;
BatchModule.class,
BeamJpaModule.class,
BigqueryModule.class,
CertificateCheckerModule.class,
ConfigModule.class,
CloudDnsWriterModule.class,
DatastoreAdminModule.class,
@@ -83,42 +85,83 @@ import javax.inject.Singleton;
})
interface RegistryToolComponent {
void inject(AckPollMessagesCommand command);
void inject(CheckDomainClaimsCommand command);
void inject(CheckDomainCommand command);
void inject(CountDomainsCommand command);
void inject(CreateAnchorTenantCommand command);
void inject(CreateCdnsTld command);
void inject(CreateContactCommand command);
void inject(CreateDomainCommand command);
void inject(CreateRegistrarCommand command);
void inject(CreateTldCommand command);
void inject(DeployInvoicingPipelineCommand command);
void inject(DeploySpec11PipelineCommand command);
void inject(EncryptEscrowDepositCommand command);
void inject(GenerateAllocationTokensCommand command);
void inject(GenerateDnsReportCommand command);
void inject(GenerateEscrowDepositCommand command);
void inject(GetKeyringSecretCommand command);
void inject(GetOperationStatusCommand command);
void inject(GhostrydeCommand command);
void inject(ImportDatastoreCommand command);
void inject(ListCursorsCommand command);
void inject(ListDatastoreOperationsCommand command);
void inject(LoadSnapshotCommand command);
void inject(LockDomainCommand command);
void inject(LoginCommand command);
void inject(LogoutCommand command);
void inject(PendingEscrowCommand command);
void inject(RenewDomainCommand command);
void inject(SendEscrowReportToIcannCommand command);
void inject(SetNumInstancesCommand command);
void inject(SetupOteCommand command);
void inject(UnlockDomainCommand command);
void inject(UnrenewDomainCommand command);
void inject(UpdateCursorsCommand command);
void inject(UpdateDomainCommand command);
void inject(UpdateKmsKeyringCommand command);
void inject(UpdateRegistrarCommand command);
void inject(UpdateTldCommand command);
void inject(ValidateEscrowDepositCommand command);
void inject(WhoisQueryCommand command);
AppEngineConnection appEngineConnection();
@@ -56,6 +56,7 @@ import google.registry.ui.forms.FormFieldException;
import google.registry.ui.server.RegistrarFormFields;
import google.registry.ui.server.SendEmailUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.CertificateChecker;
import google.registry.util.CollectionUtils;
import google.registry.util.DiffUtils;
import java.util.HashSet;
@@ -64,7 +65,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import javax.inject.Inject;
import org.joda.time.DateTime;
@@ -93,11 +93,13 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
@Inject SendEmailUtils sendEmailUtils;
@Inject AuthenticatedRegistrarAccessor registrarAccessor;
@Inject AuthResult authResult;
@Inject CertificateChecker certificateChecker;
@Inject RegistrarSettingsAction() {}
private static final Predicate<RegistrarContact> HAS_PHONE =
contact -> contact.getPhoneNumber() != null;
private static boolean hasPhone(RegistrarContact contact) {
return contact.getPhoneNumber() != null;
}
@Override
public void run() {
@@ -306,19 +308,43 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
RegistrarFormFields.IP_ADDRESS_ALLOW_LIST_FIELD
.extractUntyped(args)
.orElse(ImmutableList.of()));
RegistrarFormFields.CLIENT_CERTIFICATE_FIELD
.extractUntyped(args)
.ifPresent(
certificate -> builder.setClientCertificate(certificate, tm().getTransactionTime()));
RegistrarFormFields.FAILOVER_CLIENT_CERTIFICATE_FIELD
.extractUntyped(args)
.ifPresent(
certificate ->
builder.setFailoverClientCertificate(certificate, tm().getTransactionTime()));
Optional<String> certificateString =
RegistrarFormFields.CLIENT_CERTIFICATE_FIELD.extractUntyped(args);
if (certificateString.isPresent()) {
if (validateCertificate(initialRegistrar.getClientCertificate(), certificateString.get())) {
builder.setClientCertificate(certificateString.get(), tm().getTransactionTime());
}
}
Optional<String> failoverCertificateString =
RegistrarFormFields.FAILOVER_CLIENT_CERTIFICATE_FIELD.extractUntyped(args);
if (failoverCertificateString.isPresent()) {
if (validateCertificate(
initialRegistrar.getFailoverClientCertificate(), failoverCertificateString.get())) {
builder.setFailoverClientCertificate(
failoverCertificateString.get(), tm().getTransactionTime());
}
}
return checkNotChangedUnlessAllowed(builder, initialRegistrar, Role.OWNER);
}
/**
* Returns true if the registrar should accept the new certificate. Returns false if the
* certificate is already the one stored for the registrar.
*/
private boolean validateCertificate(String existingCertificate, String certificateString) {
if ((existingCertificate == null) || !existingCertificate.equals(certificateString)) {
// TODO(sarhabot): remove this check after November 1, 2020
if (tm().getTransactionTime().isAfter(DateTime.parse("2020-11-01T00:00:00Z"))) {
certificateChecker.validateCertificate(certificateString);
}
return true;
}
return false;
}
/**
* Updates a registrar with the ADMIN-controlled args from the http request.
*
@@ -512,8 +538,8 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA
Multimap<Type, RegistrarContact> newContactsByType,
Type... types) {
for (Type type : types) {
if (oldContactsByType.get(type).stream().anyMatch(HAS_PHONE)
&& newContactsByType.get(type).stream().noneMatch(HAS_PHONE)) {
if (oldContactsByType.get(type).stream().anyMatch(RegistrarSettingsAction::hasPhone)
&& newContactsByType.get(type).stream().noneMatch(RegistrarSettingsAction::hasPhone)) {
throw new ContactRequirementException(
String.format(
"Please provide a phone number for at least one %s contact",
@@ -53,6 +53,7 @@
<class>google.registry.model.poll.PollMessage</class>
<class>google.registry.model.poll.PollMessage$OneTime</class>
<class>google.registry.model.poll.PollMessage$Autorenew</class>
<class>google.registry.model.rde.RdeRevision</class>
<class>google.registry.model.registrar.Registrar</class>
<class>google.registry.model.registrar.RegistrarContact</class>
<class>google.registry.model.registry.label.PremiumList</class>
@@ -28,6 +28,7 @@ public class DevTool {
public static final ImmutableMap<String, Class<? extends Command>> COMMAND_MAP =
ImmutableMap.of(
"dump_golden_schema", DumpGoldenSchemaCommand.class,
"generate_sql_er_diagram", GenerateSqlErDiagramCommand.class,
"generate_sql_schema", GenerateSqlSchemaCommand.class);
public static void main(String[] args) throws Exception {
@@ -0,0 +1,227 @@
// 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.tools;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.tools.GenerateSqlErDiagramCommand.DiagramType.ALL;
import static google.registry.tools.GenerateSqlErDiagramCommand.DiagramType.BRIEF;
import static google.registry.tools.GenerateSqlErDiagramCommand.DiagramType.FULL;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.converters.PathConverter;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Iterables;
import com.google.common.io.Resources;
import google.registry.persistence.NomulusPostgreSql;
import google.registry.util.ResourceUtils;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.testcontainers.containers.PostgreSQLContainer;
import schemacrawler.schemacrawler.LoadOptionsBuilder;
import schemacrawler.schemacrawler.SchemaCrawlerOptions;
import schemacrawler.schemacrawler.SchemaCrawlerOptionsBuilder;
import schemacrawler.schemacrawler.SchemaInfoLevelBuilder;
import schemacrawler.tools.executable.SchemaCrawlerExecutable;
import schemacrawler.tools.integration.diagram.DiagramOutputFormat;
import schemacrawler.tools.options.OutputOptions;
import schemacrawler.tools.options.OutputOptionsBuilder;
/** Command to generate ER diagrams for SQL schema. */
@Parameters(separators = " =", commandDescription = "Generate ER diagrams for SQL schmea.")
public class GenerateSqlErDiagramCommand implements Command {
private static final String DB_NAME = "postgres";
private static final String DB_USER = "username";
private static final String DB_PASSWORD = "password";
private static final String FULL_DIAGRAM_COMMAND = "schema";
private static final String BRIEF_DIAGRAM_COMMAND = "brief";
private static final String FULL_DIAGRAM_FILE_NAME = "full_er_diagram.html";
private static final String BRIEF_DIAGRAM_FILE_NAME = "brief_er_diagram.html";
private static final String NOMULUS_GOLDEN_SCHEMA = "sql/schema/nomulus.golden.sql";
private static final String FLYWAY_FILE = "sql/flyway.txt";
private static final String SVG_PAN_ZOOM_LIB = "google/registry/tools/svg-pan-zoom.min.js";
// The HTML element ID for the last flyway file name
static final String FLYWAY_FILE_ELEMENT_ID = "lastFlywayFile";
@Parameter(
names = {"-o", "--out_dir"},
description = "Name of the output directory to store ER diagrams.",
converter = PathConverter.class,
required = true)
private Path outDir;
@Parameter(
names = "--diagram_type",
description =
"Type of the generated ER diagram, can be FULL, BRIEF and ALL (defaults to ALL).")
private DiagramType diagramType = ALL;
/** The type of ER diagram. */
public enum DiagramType {
/** An HTML file that has an embedded ER diagram showing the full SQL schema. */
FULL,
/**
* An HTML file that has an embedded ER diagram showing only significant columns, such as
* primary and foreign key columns, and columns that are part of unique indexes.
*/
BRIEF,
/** Generates all types of ER diagrams. */
ALL
}
@Override
public void run() throws Exception {
if (!outDir.toFile().exists()) {
checkState(outDir.toFile().mkdirs(), "Failed to create directory %s", outDir);
}
PostgreSQLContainer postgresContainer =
new PostgreSQLContainer(NomulusPostgreSql.getDockerTag())
.withDatabaseName(DB_NAME)
.withUsername(DB_USER)
.withPassword(DB_PASSWORD);
postgresContainer.start();
try (Connection conn = getConnection(postgresContainer)) {
initDb(conn);
if (diagramType == ALL || diagramType == FULL) {
improveDiagramHtml(generateErDiagram(conn, FULL_DIAGRAM_COMMAND, FULL_DIAGRAM_FILE_NAME));
}
if (diagramType == ALL || diagramType == BRIEF) {
improveDiagramHtml(generateErDiagram(conn, BRIEF_DIAGRAM_COMMAND, BRIEF_DIAGRAM_FILE_NAME));
}
} finally {
postgresContainer.stop();
}
}
private void improveDiagramHtml(Path diagram) {
try {
Document doc = Jsoup.parse(diagram.toFile(), StandardCharsets.UTF_8.name());
// Add the last name of the flyway file to the HTML so we can have a test to verify that if
// the generated diagram is up to date.
doc.select("body > table > tbody")
.first()
.append(
String.format(
"<tr>"
+ "<td class=\"property_name\">last flyway file</td>"
+ "<td id=\""
+ FLYWAY_FILE_ELEMENT_ID
+ "\" class=\"property_value\">"
+ getLastFlywayFileName()
+ "</td>"
+ "</tr>"));
// Add pan and zoom support for the embedded SVG in the HTML.
StringBuilder svgPanZoomLib =
new StringBuilder("<script>")
.append(ResourceUtils.readResourceUtf8(Resources.getResource(SVG_PAN_ZOOM_LIB)))
.append("</script>");
doc.select("head").first().append(svgPanZoomLib.toString());
doc.select("svg")
.first()
.attributes()
.add("id", "erDiagram")
.add("style", "overflow: hidden; width: 100%; height: 800px");
doc.select("body")
.first()
.append(
"<script>"
+ "svgPanZoom('#erDiagram', {"
+ " zoomEnabled: true,"
+ " controlIconsEnabled: true,"
+ " fit: true,"
+ " center: true,"
+ " minZoom: 0.1"
+ "});"
+ "</script>");
Files.write(
diagram, doc.outerHtml().getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private Path generateErDiagram(Connection connection, String command, String fileName) {
Path outputFile = outDir.resolve(fileName);
LoadOptionsBuilder loadOptionsBuilder =
LoadOptionsBuilder.builder().withSchemaInfoLevel(SchemaInfoLevelBuilder.standard());
SchemaCrawlerOptions options =
SchemaCrawlerOptionsBuilder.newSchemaCrawlerOptions()
.withLoadOptions(loadOptionsBuilder.toOptions());
OutputOptions outputOptions =
OutputOptionsBuilder.newOutputOptions(DiagramOutputFormat.htmlx, outputFile);
SchemaCrawlerExecutable executable = new SchemaCrawlerExecutable(command);
executable.setSchemaCrawlerOptions(options);
executable.setOutputOptions(outputOptions);
executable.setConnection(connection);
try {
executable.execute();
} catch (Exception e) {
throw new RuntimeException(e);
}
return outputFile;
}
private static Connection getConnection(PostgreSQLContainer container) {
Properties info = new Properties();
info.put("user", container.getUsername());
info.put("password", container.getPassword());
try {
return container.getJdbcDriverInstance().connect(container.getJdbcUrl(), info);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private static void initDb(Connection connection) {
try (Statement statement = connection.createStatement()) {
statement.execute(
ResourceUtils.readResourceUtf8(Resources.getResource(NOMULUS_GOLDEN_SCHEMA)));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@VisibleForTesting
static String getLastFlywayFileName() {
try {
return Iterables.getLast(
Resources.readLines(Resources.getResource(FLYWAY_FILE), StandardCharsets.UTF_8));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
File diff suppressed because one or more lines are too long
@@ -143,6 +143,7 @@ public class TestPipelineExtension extends Pipeline
// Null until the pipeline has been run
@Nullable private List<TransformHierarchy.Node> runVisitedNodes;
@SuppressWarnings("UnnecessaryLambda") // Stay true to the original class.
private final Predicate<Node> isPAssertNode =
node ->
node.getTransform() instanceof PAssert.GroupThenAssert
@@ -805,30 +805,35 @@ class EppLifecycleDomainTest extends EppTestCase {
// As the losing registrar, read the request poll message, and then ack it.
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
String messageId = "1-C-EXAMPLE-20-26-2001";
assertThatCommand("poll.xml")
.atTime("2001-01-01T00:01:00Z")
.hasResponse("poll_response_domain_transfer_request.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-23-2001"))
.hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId))
.atTime("2001-01-01T00:01:00Z")
.hasResponse("poll_ack_response_empty.xml");
// Five days in the future, expect a server approval poll message to the loser, and ack it.
messageId = "1-C-EXAMPLE-20-25-2001";
assertThatCommand("poll.xml")
.atTime("2001-01-06T00:01:00Z")
.hasResponse("poll_response_domain_transfer_server_approve_loser.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-22-2001"))
.hasResponse(
"poll_response_domain_transfer_server_approve_loser.xml",
ImmutableMap.of("ID", messageId));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId))
.atTime("2001-01-06T00:01:00Z")
.hasResponse("poll_ack_response_empty.xml");
assertThatLogoutSucceeds();
// Also expect a server approval poll message to the winner, with the transfer request trid.
messageId = "1-C-EXAMPLE-20-24-2001";
assertThatLoginSucceeds("TheRegistrar", "password2");
assertThatCommand("poll.xml")
.atTime("2001-01-06T00:02:00Z")
.hasResponse(
"poll_response_domain_transfer_server_approve_winner.xml",
ImmutableMap.of("SERVER_TRID", transferRequestTrid));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-21-2001"))
ImmutableMap.of("SERVER_TRID", transferRequestTrid, "ID", messageId));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId))
.atTime("2001-01-06T00:02:00Z")
.hasResponse("poll_ack_response_empty.xml");
assertThatLogoutSucceeds();
@@ -21,6 +21,7 @@ import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation;
import static google.registry.testing.SqlHelper.saveRegistrar;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.USD;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.fail;
@@ -42,12 +43,14 @@ import google.registry.model.host.HostResource;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import java.util.Arrays;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
@@ -75,6 +78,7 @@ public class DomainBaseSqlTest {
private HostResource host;
private ContactResource contact;
private ContactResource contact2;
private ImmutableSet<GracePeriod> gracePeriods;
@BeforeEach
void setUp() {
@@ -445,6 +449,7 @@ public class DomainBaseSqlTest {
() -> {
historyEntry =
new DomainHistory.Builder()
.setId(100L)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setPeriod(Period.create(1, Period.Unit.YEARS))
.setModificationTime(DateTime.now(UTC))
@@ -458,6 +463,7 @@ public class DomainBaseSqlTest {
.build();
BillingEvent.Recurring billEvent =
new BillingEvent.Recurring.Builder()
.setId(200L)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.com")
@@ -470,16 +476,51 @@ public class DomainBaseSqlTest {
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setId(300L)
.setClientId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
PollMessage.OneTime deletePollMessage =
new PollMessage.OneTime.Builder()
.setId(400L)
.setClientId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
BillingEvent.OneTime oneTimeBillingEvent =
new BillingEvent.OneTime.Builder()
.setId(500L)
// Use SERVER_STATUS so we don't have to add a period.
.setReason(Reason.SERVER_STATUS)
.setTargetId("example.com")
.setClientId("registrar1")
.setDomainRepoId("4-COM")
.setBillingTime(DateTime.now(UTC))
.setCost(Money.of(USD, 100))
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
DomainTransferData transferData =
new DomainTransferData.Builder()
.setServerApproveBillingEvent(oneTimeBillingEvent.createVKey())
.setServerApproveAutorenewEvent(billEvent.createVKey())
.setServerApproveAutorenewPollMessage(autorenewPollMessage.createVKey())
.build();
gracePeriods =
ImmutableSet.of(
GracePeriod.create(
GracePeriodStatus.ADD,
"4-COM",
END_OF_TIME,
"registrar1",
oneTimeBillingEvent.createVKey()),
GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,
"4-COM",
END_OF_TIME,
"registrar1",
billEvent.createVKey()));
jpaTm().insert(contact);
jpaTm().insert(contact2);
@@ -490,12 +531,15 @@ public class DomainBaseSqlTest {
.setAutorenewBillingEvent(billEvent.createVKey())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.setDeletePollMessage(deletePollMessage.createVKey())
.setTransferData(transferData)
.setGracePeriods(gracePeriods)
.build();
historyEntry = historyEntry.asBuilder().setDomainContent(domain).build();
jpaTm().insert(historyEntry);
jpaTm().insert(autorenewPollMessage);
jpaTm().insert(billEvent);
jpaTm().insert(deletePollMessage);
jpaTm().insert(oneTimeBillingEvent);
jpaTm().insert(domain);
});
@@ -516,6 +560,16 @@ public class DomainBaseSqlTest {
.isEqualTo(domain.getAutorenewBillingEvent());
assertThat(persistedHistoryEntry.getDomainContent().get().getDeletePollMessage())
.isEqualTo(domain.getDeletePollMessage());
DomainTransferData persistedTransferData =
persistedHistoryEntry.getDomainContent().get().getTransferData();
DomainTransferData originalTransferData = domain.getTransferData();
assertThat(persistedTransferData.getServerApproveBillingEvent())
.isEqualTo(originalTransferData.getServerApproveBillingEvent());
assertThat(persistedTransferData.getServerApproveAutorenewEvent())
.isEqualTo(originalTransferData.getServerApproveAutorenewEvent());
assertThat(persistedTransferData.getServerApproveAutorenewPollMessage())
.isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage());
assertThat(persisted.getGracePeriods()).isEqualTo(gracePeriods);
}
@Test
@@ -525,6 +579,7 @@ public class DomainBaseSqlTest {
() -> {
historyEntry =
new DomainHistory.Builder()
.setId(100L)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setPeriod(Period.create(1, Period.Unit.YEARS))
.setModificationTime(DateTime.now(UTC))
@@ -538,6 +593,7 @@ public class DomainBaseSqlTest {
.build();
BillingEvent.Recurring billEvent =
new BillingEvent.Recurring.Builder()
.setId(200L)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.com")
@@ -550,16 +606,56 @@ public class DomainBaseSqlTest {
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setId(300L)
.setClientId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
PollMessage.OneTime deletePollMessage =
new PollMessage.OneTime.Builder()
.setId(400L)
.setClientId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
BillingEvent.OneTime oneTimeBillingEvent =
new BillingEvent.OneTime.Builder()
.setId(500L)
// Use SERVER_STATUS so we don't have to add a period.
.setReason(Reason.SERVER_STATUS)
.setTargetId("example.com")
.setClientId("registrar1")
.setDomainRepoId("4-COM")
.setBillingTime(DateTime.now(UTC))
.setCost(Money.of(USD, 100))
.setEventTime(DateTime.now(UTC).plusYears(1))
.setParent(historyEntry)
.build();
DomainTransferData transferData =
new DomainTransferData.Builder()
.setServerApproveBillingEvent(
createLegacyVKey(BillingEvent.OneTime.class, oneTimeBillingEvent.getId()))
.setServerApproveAutorenewEvent(
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))
.setServerApproveAutorenewPollMessage(
createLegacyVKey(
PollMessage.Autorenew.class, autorenewPollMessage.getId()))
.build();
gracePeriods =
ImmutableSet.of(
GracePeriod.create(
GracePeriodStatus.ADD,
"4-COM",
END_OF_TIME,
"registrar1",
createLegacyVKey(
BillingEvent.OneTime.class, oneTimeBillingEvent.getId())),
GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,
"4-COM",
END_OF_TIME,
"registrar1",
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId())));
jpaTm().insert(contact);
jpaTm().insert(contact2);
@@ -570,15 +666,19 @@ public class DomainBaseSqlTest {
.setAutorenewBillingEvent(
createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))
.setAutorenewPollMessage(
createLegacyVKey(PollMessage.Autorenew.class, deletePollMessage.getId()))
createLegacyVKey(
PollMessage.Autorenew.class, autorenewPollMessage.getId()))
.setDeletePollMessage(
createLegacyVKey(PollMessage.OneTime.class, autorenewPollMessage.getId()))
createLegacyVKey(PollMessage.OneTime.class, deletePollMessage.getId()))
.setTransferData(transferData)
.setGracePeriods(gracePeriods)
.build();
historyEntry = historyEntry.asBuilder().setDomainContent(domain).build();
jpaTm().insert(historyEntry);
jpaTm().insert(autorenewPollMessage);
jpaTm().insert(billEvent);
jpaTm().insert(deletePollMessage);
jpaTm().insert(oneTimeBillingEvent);
jpaTm().insert(domain);
});
@@ -599,6 +699,16 @@ public class DomainBaseSqlTest {
.isEqualTo(domain.getAutorenewBillingEvent());
assertThat(persistedHistoryEntry.getDomainContent().get().getDeletePollMessage())
.isEqualTo(domain.getDeletePollMessage());
DomainTransferData persistedTransferData =
persistedHistoryEntry.getDomainContent().get().getTransferData();
DomainTransferData originalTransferData = domain.getTransferData();
assertThat(persistedTransferData.getServerApproveBillingEvent())
.isEqualTo(originalTransferData.getServerApproveBillingEvent());
assertThat(persistedTransferData.getServerApproveAutorenewEvent())
.isEqualTo(originalTransferData.getServerApproveAutorenewEvent());
assertThat(persistedTransferData.getServerApproveAutorenewPollMessage())
.isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage());
assertThat(domain.getGracePeriods()).isEqualTo(gracePeriods);
}
private <T> VKey<T> createLegacyVKey(Class<T> clazz, long id) {
@@ -38,6 +38,7 @@ import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.ImmutableObject;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.contact.ContactResource;
@@ -67,6 +68,7 @@ public class DomainBaseTest extends EntityTestCase {
private DomainBase domain;
private VKey<BillingEvent.OneTime> oneTimeBillKey;
private VKey<BillingEvent.Recurring> recurringBillKey;
private Key<HistoryEntry> historyEntryKey;
@BeforeEach
void setUp() {
@@ -94,7 +96,7 @@ public class DomainBaseTest extends EntityTestCase {
.setRepoId("3-COM")
.build())
.createVKey();
Key<HistoryEntry> historyEntryKey =
historyEntryKey =
Key.create(
persistResource(new HistoryEntry.Builder().setParent(domainKey.getOfyKey()).build()));
oneTimeBillKey = VKey.from(Key.create(historyEntryKey, BillingEvent.OneTime.class, 1));
@@ -164,10 +166,26 @@ public class DomainBaseTest extends EntityTestCase {
@Test
void testPersistence() {
// Note that this only verifies that the value stored under the foreign key is the same as that
// stored under the primary key ("domain" is the domain loaded from the datastore, not the
// original domain object).
assertThat(loadByForeignKey(DomainBase.class, domain.getForeignKey(), fakeClock.nowUtc()))
.hasValue(domain);
}
@Test
void testVKeyRestoration() {
assertThat(domain.deletePollMessageHistoryId).isEqualTo(historyEntryKey.getId());
assertThat(domain.autorenewBillingEventHistoryId).isEqualTo(historyEntryKey.getId());
assertThat(domain.autorenewPollMessageHistoryId).isEqualTo(historyEntryKey.getId());
assertThat(domain.getTransferData().getServerApproveBillingEventHistoryId())
.isEqualTo(historyEntryKey.getId());
assertThat(domain.getTransferData().getServerApproveAutorenewEventHistoryId())
.isEqualTo(historyEntryKey.getId());
assertThat(domain.getTransferData().getServerApproveAutorenewPollMessageHistoryId())
.isEqualTo(historyEntryKey.getId());
}
@Test
void testIndexing() throws Exception {
verifyIndexing(
@@ -813,4 +831,63 @@ public class DomainBaseTest extends EntityTestCase {
assertThat(getOnlyElement(clone.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.TRANSFER);
}
@Test
void testHistoryIdRestoration() {
// Verify that history ids for billing events are restored during load from datastore. History
// ids are not used by business code or persisted in datastore, but only to reconstruct
// objectify keys when loading from SQL.
DateTime now = fakeClock.nowUtc();
domain =
persistResource(
domain
.asBuilder()
.setRegistrationExpirationTime(now.plusYears(1))
.setGracePeriods(
ImmutableSet.of(
GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,
domain.getRepoId(),
now.plusDays(1),
"NewRegistrar",
recurringBillKey),
GracePeriod.create(
GracePeriodStatus.RENEW,
domain.getRepoId(),
now.plusDays(1),
"NewRegistrar",
oneTimeBillKey)))
.build());
ImmutableSet<BillEventInfo> historyIds =
domain.getGracePeriods().stream()
.map(
gp ->
new BillEventInfo(
gp.getRecurringBillingEvent(), gp.billingEventRecurringHistoryId,
gp.getOneTimeBillingEvent(), gp.billingEventOneTimeHistoryId))
.collect(toImmutableSet());
assertThat(historyIds)
.isEqualTo(
ImmutableSet.of(
new BillEventInfo(null, null, oneTimeBillKey, historyEntryKey.getId()),
new BillEventInfo(recurringBillKey, historyEntryKey.getId(), null, null)));
}
static class BillEventInfo extends ImmutableObject {
VKey<BillingEvent.Recurring> billingEventRecurring;
Long billingEventRecurringHistoryId;
VKey<BillingEvent.OneTime> billingEventOneTime;
Long billingEventOneTimeHistoryId;
BillEventInfo(
VKey<BillingEvent.Recurring> billingEventRecurring,
Long billingEventRecurringHistoryId,
VKey<BillingEvent.OneTime> billingEventOneTime,
Long billingEventOneTimeHistoryId) {
this.billingEventRecurring = billingEventRecurring;
this.billingEventRecurringHistoryId = billingEventRecurringHistoryId;
this.billingEventOneTime = billingEventOneTime;
this.billingEventOneTimeHistoryId = billingEventOneTimeHistoryId;
}
}
}
@@ -44,6 +44,7 @@ public class GracePeriodTest {
private final DateTime now = DateTime.now(UTC);
private BillingEvent.OneTime onetime;
private VKey<BillingEvent.Recurring> recurringKey;
@BeforeEach
void before() {
@@ -59,6 +60,14 @@ public class GracePeriodTest {
.setPeriodYears(1)
.setTargetId("foo.google")
.build();
recurringKey =
VKey.create(
Recurring.class,
12345,
Key.create(
Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L),
Recurring.class,
12345));
}
@Test
@@ -71,6 +80,24 @@ public class GracePeriodTest {
assertThat(gracePeriod.getClientId()).isEqualTo("TheRegistrar");
assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1));
assertThat(gracePeriod.hasBillingEvent()).isTrue();
assertThat(gracePeriod.billingEventOneTimeHistoryId).isEqualTo(12345L);
assertThat(gracePeriod.billingEventRecurringHistoryId).isNull();
}
@Test
void testSuccess_forRecurringEvent() {
GracePeriod gracePeriod =
GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW, "1-TEST", now.plusDays(1), "TheRegistrar", recurringKey);
assertThat(gracePeriod.getType()).isEqualTo(GracePeriodStatus.AUTO_RENEW);
assertThat(gracePeriod.getDomainRepoId()).isEqualTo("1-TEST");
assertThat(gracePeriod.getOneTimeBillingEvent()).isNull();
assertThat(gracePeriod.getRecurringBillingEvent()).isEqualTo(recurringKey);
assertThat(gracePeriod.getClientId()).isEqualTo("TheRegistrar");
assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1));
assertThat(gracePeriod.hasBillingEvent()).isTrue();
assertThat(gracePeriod.billingEventOneTimeHistoryId).isNull();
assertThat(gracePeriod.billingEventRecurringHistoryId).isEqualTo(343L);
}
@Test
@@ -98,11 +125,6 @@ public class GracePeriodTest {
@Test
void testFailure_createForRecurring_notAutoRenew() {
Key<Recurring> recurringKey =
Key.create(
Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L),
Recurring.class,
12345);
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
@@ -112,7 +134,7 @@ public class GracePeriodTest {
"1-TEST",
now.plusDays(1),
"TheRegistrar",
VKey.create(Recurring.class, 12345, recurringKey)));
recurringKey));
assertThat(thrown).hasMessageThat().contains("autorenew");
}
}
@@ -27,7 +27,6 @@ import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
@@ -225,7 +224,7 @@ public class OfyTest {
if (firstAttemptTime == null) {
// Sleep a bit to ensure that the next attempt is at a new millisecond.
firstAttemptTime = tm().getTransactionTime();
sleepUninterruptibly(10, MILLISECONDS);
sleepUninterruptibly(java.time.Duration.ofMillis(10));
throw new ConcurrentModificationException();
}
assertThat(tm().getTransactionTime()).isGreaterThan(firstAttemptTime);
@@ -15,118 +15,116 @@
package google.registry.model.rde;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.rde.RdeMode.FULL;
import static google.registry.model.rde.RdeRevision.getNextRevision;
import static google.registry.model.rde.RdeRevision.saveRevision;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.base.VerifyException;
import google.registry.testing.AppEngineExtension;
import google.registry.model.EntityTestCase;
import google.registry.testing.DualDatabaseTest;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestTemplate;
/** Unit tests for {@link RdeRevision}. */
public class RdeRevisionTest {
@DualDatabaseTest
public class RdeRevisionTest extends EntityTestCase {
@RegisterExtension
final AppEngineExtension appEngine =
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
public RdeRevisionTest() {
super(JpaEntityCoverageCheck.ENABLED);
}
@Test
@BeforeEach
void beforeEach() {
fakeClock.setTo(DateTime.parse("1984-12-18TZ"));
}
@TestTemplate
void testGetNextRevision_objectDoesntExist_returnsZero() {
assertThat(getNextRevision("torment", DateTime.parse("1984-12-18TZ"), FULL)).isEqualTo(0);
tm().transact(
() -> assertThat(getNextRevision("torment", fakeClock.nowUtc(), FULL)).isEqualTo(0));
}
@Test
@TestTemplate
void testGetNextRevision_objectExistsAtZero_returnsOne() {
save("sorrow", DateTime.parse("1984-12-18TZ"), FULL, 0);
assertThat(getNextRevision("sorrow", DateTime.parse("1984-12-18TZ"), FULL)).isEqualTo(1);
save("sorrow", fakeClock.nowUtc(), FULL, 0);
tm().transact(
() -> assertThat(getNextRevision("sorrow", fakeClock.nowUtc(), FULL)).isEqualTo(1));
}
@Test
@TestTemplate
void testSaveRevision_objectDoesntExist_newRevisionIsZero_nextRevIsOne() {
tm().transact(() -> saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 0));
tm().transact(() -> saveRevision("despondency", fakeClock.nowUtc(), FULL, 0));
tm().transact(
() ->
assertThat(getNextRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL))
.isEqualTo(1));
assertThat(getNextRevision("despondency", fakeClock.nowUtc(), FULL)).isEqualTo(1));
}
@Test
@TestTemplate
void testSaveRevision_objectDoesntExist_newRevisionIsOne_throwsVe() {
VerifyException thrown =
IllegalArgumentException thrown =
assertThrows(
VerifyException.class,
() ->
tm().transact(
() ->
saveRevision("despondency", DateTime.parse("1984-12-18TZ"), FULL, 1)));
assertThat(thrown).hasMessageThat().contains("object missing");
IllegalArgumentException.class,
() -> tm().transact(() -> saveRevision("despondency", fakeClock.nowUtc(), FULL, 1)));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"Couldn't find existing RDE revision despondency_1984-12-18_full "
+ "when trying to save new revision 1");
}
@Test
@TestTemplate
void testSaveRevision_objectExistsAtZero_newRevisionIsZero_throwsVe() {
save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0);
VerifyException thrown =
save("melancholy", fakeClock.nowUtc(), FULL, 0);
IllegalArgumentException thrown =
assertThrows(
VerifyException.class,
() ->
tm().transact(
() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0)));
IllegalArgumentException.class,
() -> tm().transact(() -> saveRevision("melancholy", fakeClock.nowUtc(), FULL, 0)));
assertThat(thrown).hasMessageThat().contains("object already created");
}
@Test
@TestTemplate
void testSaveRevision_objectExistsAtZero_newRevisionIsOne_nextRevIsTwo() {
save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0);
tm().transact(() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 1));
tm().transact(
() ->
assertThat(getNextRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL))
.isEqualTo(2));
DateTime startOfDay = fakeClock.nowUtc().withTimeAtStartOfDay();
save("melancholy", startOfDay, FULL, 0);
fakeClock.advanceOneMilli();
tm().transact(() -> saveRevision("melancholy", startOfDay, FULL, 1));
tm().transact(() -> assertThat(getNextRevision("melancholy", startOfDay, FULL)).isEqualTo(2));
}
@Test
@TestTemplate
void testSaveRevision_objectExistsAtZero_newRevisionIsTwo_throwsVe() {
save("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 0);
VerifyException thrown =
save("melancholy", fakeClock.nowUtc(), FULL, 0);
IllegalArgumentException thrown =
assertThrows(
VerifyException.class,
() ->
tm().transact(
() -> saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, 2)));
assertThat(thrown).hasMessageThat().contains("should be at 1 ");
IllegalArgumentException.class,
() -> tm().transact(() -> saveRevision("melancholy", fakeClock.nowUtc(), FULL, 2)));
assertThat(thrown)
.hasMessageThat()
.contains("RDE revision object should be at revision 1 but was");
}
@Test
@TestTemplate
void testSaveRevision_negativeRevision_throwsIae() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
tm().transact(
() ->
saveRevision("melancholy", DateTime.parse("1984-12-18TZ"), FULL, -1)));
() -> tm().transact(() -> saveRevision("melancholy", fakeClock.nowUtc(), FULL, -1)));
assertThat(thrown).hasMessageThat().contains("Negative revision");
}
@Test
@TestTemplate
void testSaveRevision_callerNotInTransaction_throwsIse() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
() -> saveRevision("frenzy", DateTime.parse("1984-12-18TZ"), FULL, 1));
IllegalStateException.class, () -> saveRevision("frenzy", fakeClock.nowUtc(), FULL, 1));
assertThat(thrown).hasMessageThat().contains("transaction");
}
public static void save(String tld, DateTime date, RdeMode mode, int revision) {
String triplet = RdeNamingUtils.makePartialName(tld, date, mode);
RdeRevision object = new RdeRevision();
object.id = triplet;
object.revision = revision;
ofy().saveWithoutBackup().entity(object).now();
RdeRevision object = RdeRevision.create(triplet, tld, date.toLocalDate(), mode, revision);
tm().transact(() -> tm().put(object));
}
}
@@ -92,15 +92,13 @@ public class Spec11ThreatMatchDaoTest extends EntityTestCase {
}
private Spec11ThreatMatch createThreatMatch(String domainName, LocalDate date) {
Spec11ThreatMatch threatMatch =
new Spec11ThreatMatch()
.asBuilder()
.setThreatTypes(ImmutableSet.of(ThreatType.MALWARE))
.setCheckDate(date)
.setDomainName(domainName)
.setRegistrarId("Example Registrar")
.setDomainRepoId("1-COM")
.build();
return threatMatch;
return new Spec11ThreatMatch()
.asBuilder()
.setThreatTypes(ImmutableSet.of(ThreatType.MALWARE))
.setCheckDate(date)
.setDomainName(domainName)
.setRegistrarId("Example Registrar")
.setDomainRepoId("1-COM")
.build();
}
}
@@ -24,6 +24,7 @@ import google.registry.model.history.ContactHistoryTest;
import google.registry.model.history.DomainHistoryTest;
import google.registry.model.history.HostHistoryTest;
import google.registry.model.poll.PollMessageTest;
import google.registry.model.rde.RdeRevisionTest;
import google.registry.model.registry.RegistryLockDaoTest;
import google.registry.model.registry.RegistryTest;
import google.registry.model.registry.label.ReservedListSqlDaoTest;
@@ -86,6 +87,7 @@ import org.junit.runner.RunWith;
LockDaoTest.class,
PollMessageTest.class,
PremiumListDaoTest.class,
RdeRevisionTest.class,
RegistrarDaoTest.class,
RegistryTest.class,
ReservedListSqlDaoTest.class,
@@ -88,5 +88,40 @@ public final class CertificateSamples {
*/
public static final String SAMPLE_CERT2_HASH = "GNd6ZP8/n91t9UTnpxR8aH7aAW4+CpvufYx9ViGbcMY";
/*
* openssl req -new -nodes -x509 -days 200 -newkey rsa:2048 -keyout client1.key -out client1.crt
* -subj "/C=US/ST=New York/L=New York/O=Google/OU=domain-registry-test/CN=client1"
*/
public static final String SAMPLE_CERT3 =
"-----BEGIN CERTIFICATE-----\n"
+ "MIIDyzCCArOgAwIBAgIUJnhiVrxAxgwkLJzHPm1w/lBoNs4wDQYJKoZIhvcNAQEL\n"
+ "BQAwdTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMREwDwYDVQQHDAhO\n"
+ "ZXcgWW9yazEPMA0GA1UECgwGR29vZ2xlMR0wGwYDVQQLDBRkb21haW4tcmVnaXN0\n"
+ "cnktdGVzdDEQMA4GA1UEAwwHY2xpZW50MTAeFw0yMDEwMTIxNzU5NDFaFw0yMTA0\n"
+ "MzAxNzU5NDFaMHUxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazERMA8G\n"
+ "A1UEBwwITmV3IFlvcmsxDzANBgNVBAoMBkdvb2dsZTEdMBsGA1UECwwUZG9tYWlu\n"
+ "LXJlZ2lzdHJ5LXRlc3QxEDAOBgNVBAMMB2NsaWVudDEwggEiMA0GCSqGSIb3DQEB\n"
+ "AQUAA4IBDwAwggEKAoIBAQC0msirO7kXyGEC93stsNYGc02Z77Q2qfHFwaGYkUG8\n"
+ "QvOF5SWN+jwTo5Td6Jj26A26a8MLCtK45TCBuMRNcUsHhajhT19ocphO20iY3zhi\n"
+ "ycwV1id0iwME4kPd1m57BELRE9tUPOxF81/JQXdR1fwT5KRVHYRDWZhaZ5aBmlZY\n"
+ "3t/H9Ly0RBYyApkMaGs3nlb94OOug6SouUfRt02S59ja3wsE2SVF/Eui647OXP7O\n"
+ "QdYXofxuqLoNkE8EnAdl43/enGLiCIVd0G2lABibFF+gbxTtfgbg7YtfUZJdL+Mb\n"
+ "RAcAtuLXEamNQ9H63JgVF16PlQVCDz2XyI3uCfPpDDiBAgMBAAGjUzBRMB0GA1Ud\n"
+ "DgQWBBQ26bWk8qfEBjXs/xZ4m8JZyalnITAfBgNVHSMEGDAWgBQ26bWk8qfEBjXs\n"
+ "/xZ4m8JZyalnITAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAZ\n"
+ "VcsgslBKanKOieJ5ik2d9qzOMXKfBuWPRFWbkC3t9i5awhHqnGAaj6nICnnMZIyt\n"
+ "rdx5lZW5aaQyf0EP/90JAA8Xmty4A6MXmEjQAMiCOpP3A7eeS6Xglgi8IOZl4/bg\n"
+ "LonW62TUkilo5IiFt/QklFTeHIjXB+OvA8+2Quqyd+zp7v6KnhXjvaomim78DhwE\n"
+ "0PIUnjmiRpGpHfTVioTdfhPHZ2Y93Y8K7juL93sQog9aBu5m9XRJCY6wGyWPE83i\n"
+ "kmLfGzjcnaJ6kqCd9xQRFZ0JwHmGlkAQvFoeengbNUqSyjyVgsOoNkEsrWwe/JFO\n"
+ "iqBvjEhJlvRoefvkdR98\n"
+ "-----END CERTIFICATE-----\n";
/*
* python -c "import sys;print sys.argv[1].decode('hex').encode('base64').strip('\n=')" $(openssl
* x509 -fingerprint -sha256 -in client1.crt | grep -Po '(?<=Fingerprint=).*' | sed s/://g)
*/
public static final String SAMPLE_CERT3_HASH = "GM2tYFuzdpDXN0lqpUXlsvrqk8OdMayryV+4/DOFZ0M";
private CertificateSamples() {}
}
@@ -93,7 +93,7 @@ public class TestSftpServer implements FtpServer {
try (PEMParser pemParser = new PEMParser(new StringReader(key))) {
PEMKeyPair pemPair = (PEMKeyPair) pemParser.readObject();
KeyPair result = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);
logger.atInfo().log("Read key pair %s", result);
logger.atInfo().log("Read key pair successfully.");
return result;
} catch (IOException e) {
logger.atSevere().withCause(e).log("Couldn't read key pair from string.");
@@ -175,7 +175,12 @@ public abstract class CommandTestCase<C extends Command> {
/** Returns a path to a known good certificate file. */
String getCertFilename() throws IOException {
return writeToNamedTmpFile("cert.pem", CertificateSamples.SAMPLE_CERT);
return getCertFilename(CertificateSamples.SAMPLE_CERT);
}
/** Returns a path to a specified certificate file. */
String getCertFilename(String certificateFile) throws IOException {
return writeToNamedTmpFile("cert.pem", certificateFile);
}
/** Reloads the given resource from Datastore. */
@@ -19,9 +19,12 @@ import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.persistNewRegistrar;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
@@ -31,10 +34,11 @@ import static org.mockito.Mockito.when;
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Range;
import com.google.common.net.MediaType;
import google.registry.model.registrar.Registrar;
import google.registry.testing.CertificateSamples;
import google.registry.util.CertificateChecker;
import java.io.IOException;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
@@ -52,6 +56,12 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
@BeforeEach
void beforeEach() {
command.setConnection(connection);
command.certificateChecker =
new CertificateChecker(
ImmutableSortedMap.of(START_OF_TIME, 825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
30,
2048,
fakeClock);
}
@Test
@@ -354,12 +364,13 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
@Test
void testSuccess_clientCertFileFlag() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--cert_file=" + getCertFilename(),
"--cert_file=" + getCertFilename(SAMPLE_CERT3),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
@@ -371,8 +382,67 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
assertThat(registrar).isPresent();
assertThat(registrar.get().getClientCertificateHash())
.isEqualTo(CertificateSamples.SAMPLE_CERT_HASH);
assertThat(registrar.get().getClientCertificateHash()).isEqualTo(SAMPLE_CERT3_HASH);
}
@Test
void testFail_clientCertFileFlagWithViolation() throws Exception {
fakeClock.setTo(DateTime.parse("2020-10-01T00:00:00Z"));
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--cert_file=" + getCertFilename(SAMPLE_CERT),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
assertThat(registrar).isEmpty();
}
@Test
void testFail_clientCertFileFlagWithMultipleViolations() throws Exception {
fakeClock.setTo(DateTime.parse("2055-10-01T00:00:00Z"));
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--cert_file=" + getCertFilename(SAMPLE_CERT),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
assertThat(registrar).isEmpty();
}
@Test
@@ -400,12 +470,13 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
@Test
void testSuccess_failoverClientCertFileFlag() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--failover_cert_file=" + getCertFilename(),
"--failover_cert_file=" + getCertFilename(SAMPLE_CERT3),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
@@ -420,8 +491,68 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
Registrar registrar = registrarOptional.get();
assertThat(registrar.getClientCertificate()).isNull();
assertThat(registrar.getClientCertificateHash()).isNull();
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT3);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT3_HASH);
}
@Test
void testFail_failoverClientCertFileFlagWithViolations() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--failover_cert_file=" + getCertFilename(SAMPLE_CERT),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
assertThat(registrar).isEmpty();
}
@Test
void testFail_failoverClientCertFileFlagWithMultipleViolations() throws Exception {
fakeClock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--failover_cert_file=" + getCertFilename(SAMPLE_CERT),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
Optional<Registrar> registrar = Registrar.loadByClientId("clientz");
assertThat(registrar).isEmpty();
}
@Test
@@ -1049,48 +1180,6 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"clientz"));
}
@Test
void testFailure_invalidCertFileContents() {
assertThrows(
Exception.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--cert_file=" + writeToTmpFile("ABCDEF"),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
}
@Test
void testFailure_invalidFailoverCertFileContents() {
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=blobio",
"--password=some_password",
"--registrar_type=REAL",
"--iana_id=8",
"--failover_cert_file=" + writeToTmpFile("ABCDEF"),
"--passcode=01234",
"--icann_referral_email=foo@bar.test",
"--street=\"123 Fake St\"",
"--city Fakington",
"--state MA",
"--zip 00351",
"--cc US",
"clientz"));
}
@Test
void testFailure_certHashAndCertFile() {
assertThrows(
@@ -108,7 +108,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.atTime("2001-06-08T00:00:00Z")
.hasResponse("poll_response_unrenew.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-17-18-2001"))
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-23-24-2001"))
.atTime("2001-06-08T00:00:01Z")
.hasResponse("poll_ack_response_empty.xml");
@@ -129,7 +129,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.hasResponse(
"poll_response_autorenew.xml",
ImmutableMap.of(
"ID", "1-8-TLD-17-20-2003",
"ID", "1-8-TLD-23-26-2003",
"QDATE", "2003-06-01T00:02:00Z",
"DOMAIN", "example.tld",
"EXDATE", "2004-06-01T00:02:00Z"));
@@ -0,0 +1,78 @@
// 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.tools;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.tools.GenerateSqlErDiagramCommand.FLYWAY_FILE_ELEMENT_ID;
import static google.registry.tools.GenerateSqlErDiagramCommand.getLastFlywayFileName;
import com.google.common.base.Joiner;
import com.google.common.io.Resources;
import google.registry.util.ResourceUtils;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link GenerateSqlErDiagramCommand}. */
class GenerateSqlErDiagramCommandTest extends CommandTestCase<GenerateSqlErDiagramCommand> {
private static final String GOLDEN_DIAGRAM_FOLDER = "sql/er_diagram";
private static final String UPDATE_INSTRUCTIONS =
Joiner.on('\n')
.join(
"",
"-------------------------------------------------------------------------------",
"Your changes affect SQL ER diagrams. To update the checked-in version, run the"
+ " following command in the repository root:",
"./gradlew devTool --args=\"-e localhost generate_sql_er_diagram -o"
+ " ../db/src/main/resources/sql/er_diagram\"",
"");
@Test
void testSchemaGeneration() throws Exception {
runCommand("--out_dir=" + tmpDir.resolve("diagram").toString());
Path fullDiagram = tmpDir.resolve("diagram/full_er_diagram.html");
Document fullDiagramDoc = Jsoup.parse(fullDiagram.toFile(), StandardCharsets.UTF_8.name());
assertThat(fullDiagramDoc.select("svg")).isNotEmpty();
Path briefDiagram = tmpDir.resolve("diagram/full_er_diagram.html");
Document briefDiagramDoc = Jsoup.parse(briefDiagram.toFile(), StandardCharsets.UTF_8.name());
assertThat(briefDiagramDoc.select("svg")).isNotEmpty();
}
@Test
void validateErDiagramIsUpToDate() throws Exception {
String goldenFullDiagram =
ResourceUtils.readResourceUtf8(
Resources.getResource(
Paths.get(GOLDEN_DIAGRAM_FOLDER).resolve("full_er_diagram.html").toString()));
assertWithMessage(UPDATE_INSTRUCTIONS)
.that(Jsoup.parse(goldenFullDiagram).getElementById(FLYWAY_FILE_ELEMENT_ID).text())
.isEqualTo(getLastFlywayFileName());
String briefFullDiagram =
ResourceUtils.readResourceUtf8(
Resources.getResource(
Paths.get(GOLDEN_DIAGRAM_FOLDER).resolve("brief_er_diagram.html").toString()));
assertWithMessage(UPDATE_INSTRUCTIONS)
.that(Jsoup.parse(briefFullDiagram).getElementById(FLYWAY_FILE_ELEMENT_ID).text())
.isEqualTo(getLastFlywayFileName());
}
}
@@ -19,10 +19,13 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -30,20 +33,33 @@ import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.Registrar.Type;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineExtension;
import google.registry.util.CertificateChecker;
import google.registry.util.CidrAddressBlock;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link UpdateRegistrarCommand}. */
class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand> {
@BeforeEach
void beforeEach() {
command.certificateChecker =
new CertificateChecker(
ImmutableSortedMap.of(START_OF_TIME, 825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
30,
2048,
fakeClock);
}
@Test
void testSuccess_alsoUpdateInCloudSql() throws Exception {
assertThat(loadRegistrar("NewRegistrar").verifyPassword("some_password")).isFalse();
@@ -232,15 +248,94 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
@Test
void testSuccess_certFile() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getClientCertificate()).isNull();
assertThat(registrar.getClientCertificateHash()).isNull();
runCommand("--cert_file=" + getCertFilename(), "--force", "NewRegistrar");
runCommand("--cert_file=" + getCertFilename(SAMPLE_CERT3), "--force", "NewRegistrar");
registrar = loadRegistrar("NewRegistrar");
// NB: Hash was computed manually using 'openssl x509 -fingerprint -sha256 -in ...' and then
// converting the result from a hex string to non-padded base64 encoded string.
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT3);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT3_HASH);
}
@Test
void testFail_certFileWithViolation() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getClientCertificate()).isNull();
assertThat(registrar.getClientCertificateHash()).isNull();
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--cert_file=" + getCertFilename(), "--force", "NewRegistrar"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
assertThat(registrar.getClientCertificate()).isNull();
}
@Test
void testFail_certFileWithMultipleViolations() throws Exception {
fakeClock.setTo(DateTime.parse("2055-10-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getClientCertificate()).isNull();
assertThat(registrar.getClientCertificateHash()).isNull();
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--cert_file=" + getCertFilename(), "--force", "NewRegistrar"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertThat(registrar.getClientCertificate()).isNull();
}
@Test
void testFail_failoverCertFileWithViolation() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getFailoverClientCertificate()).isNull();
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommand("--failover_cert_file=" + getCertFilename(), "--force", "NewRegistrar"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
assertThat(registrar.getFailoverClientCertificate()).isNull();
}
@Test
void testFail_failoverCertFileWithMultipleViolations() throws Exception {
fakeClock.setTo(DateTime.parse("2055-10-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getFailoverClientCertificate()).isNull();
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommand("--failover_cert_file=" + getCertFilename(), "--force", "NewRegistrar"));
assertThat(thrown.getMessage())
.isEqualTo(
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertThat(registrar.getFailoverClientCertificate()).isNull();
}
@Test
void testSuccess_failoverCertFile() throws Exception {
fakeClock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Registrar registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getFailoverClientCertificate()).isNull();
runCommand("--failover_cert_file=" + getCertFilename(SAMPLE_CERT3), "--force", "NewRegistrar");
registrar = loadRegistrar("NewRegistrar");
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT3);
}
@Test
@@ -672,7 +767,7 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
IllegalArgumentException.class,
() ->
runCommand(
"--cert_file=" + getCertFilename(),
"--cert_file=" + getCertFilename(SAMPLE_CERT3),
"--cert_hash=ABCDEF",
"--force",
"NewRegistrar"));
@@ -43,6 +43,7 @@ import google.registry.util.EmailMessage;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.junit.jupiter.api.Test;
@@ -367,6 +368,18 @@ class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase {
@Test
void testUpdate_clientCertificate() {
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
doTestUpdate(
Role.OWNER,
Registrar::getClientCertificate,
CertificateSamples.SAMPLE_CERT3,
(builder, s) -> builder.setClientCertificate(s, clock.nowUtc()));
}
@Test
void testUpdate_clientCertificateWithViolationsBeforeNovemberSucceeds() {
// TODO(sarahbot): remove this test after November 1, 2020.
clock.setTo(DateTime.parse("2018-07-02T00:00:00Z"));
doTestUpdate(
Role.OWNER,
Registrar::getClientCertificate,
@@ -374,15 +387,216 @@ class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase {
(builder, s) -> builder.setClientCertificate(s, clock.nowUtc()));
}
@Test
void testUpdate_otherFieldsWhenClientCertificateWithViolationsAlreadyExistedSucceeds() {
// TODO(sarahbot): remove this test after November 1, 2020.
// The frontend will always send the entire registrar entity back for an update, so the checks
// on the certificate should only run if a new certificate is being uploaded. All other updates
// after November 1st should still succeed even if a bad certificate is stored.
// Set a bad certificate before checks on uploads are enforced
clock.setTo(DateTime.parse("2018-07-02T00:00:00Z"));
Registrar existingRegistrar = loadRegistrar(CLIENT_ID);
existingRegistrar =
existingRegistrar
.asBuilder()
.setClientCertificate(CertificateSamples.SAMPLE_CERT, clock.nowUtc())
.build();
persistResource(existingRegistrar);
// Update the other registrar fields after enforcement begins should succeed
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("url", "test.url");
args.put("phoneNumber", "+1.1234567890");
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response).containsEntry("status", "SUCCESS");
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
}
@Test
void testUpdate_clientCertificateWithViolationsAlreadyExistedSucceeds() {
// TODO(sarahbot): remove this test after November 1, 2020.
// The frontend will always send the entire registrar entity back for an update, so the checks
// on the certificate should only run if it is a new certificate
// Set a bad certificate before checks on uploads are enforced
clock.setTo(DateTime.parse("2018-07-02T00:00:00Z"));
Registrar existingRegistrar = loadRegistrar(CLIENT_ID);
existingRegistrar =
existingRegistrar
.asBuilder()
.setClientCertificate(CertificateSamples.SAMPLE_CERT, clock.nowUtc())
.build();
persistResource(existingRegistrar);
// Update with the same certificate after enforcement starts
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("clientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response).containsEntry("status", "SUCCESS");
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_clientCertificateWithViolationsFails() {
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("clientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response)
.containsExactly(
"status",
"ERROR",
"results",
ImmutableList.of(),
"message",
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_clientCertificateWithMultipleViolationsFails() {
clock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("clientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response)
.containsExactly(
"status",
"ERROR",
"results",
ImmutableList.of(),
"message",
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_failoverClientCertificate() {
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
doTestUpdate(
Role.OWNER,
Registrar::getFailoverClientCertificate,
CertificateSamples.SAMPLE_CERT,
CertificateSamples.SAMPLE_CERT3,
(builder, s) -> builder.setFailoverClientCertificate(s, clock.nowUtc()));
}
@Test
void testUpdate_failoverClientCertificateWithViolationsAlreadyExistedSucceeds() {
// TODO(sarahbot): remove this test after November 1, 2020.
// The frontend will always send the entire registrar entity back for an update, so the checks
// on the certificate should only run if it is a new certificate
// Set a bad certificate before checks on uploads are enforced
clock.setTo(DateTime.parse("2018-07-02T00:00:00Z"));
Registrar existingRegistrar = loadRegistrar(CLIENT_ID);
existingRegistrar =
existingRegistrar
.asBuilder()
.setFailoverClientCertificate(CertificateSamples.SAMPLE_CERT, clock.nowUtc())
.build();
persistResource(existingRegistrar);
// Update with the same certificate after enforcement starts
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("failoverClientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response).containsEntry("status", "SUCCESS");
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_failoverClientCertificateWithViolationsFails() {
clock.setTo(DateTime.parse("2020-11-02T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("failoverClientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response)
.containsExactly(
"status",
"ERROR",
"results",
ImmutableList.of(),
"message",
"Certificate validity period is too long; it must be less than or equal to 398"
+ " days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_failoverClientCertificateWithMultipleViolationsFails() {
clock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
Map<String, Object> args = Maps.newHashMap(loadRegistrar(CLIENT_ID).toJsonMap());
args.put("failoverClientCertificate", CertificateSamples.SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", args));
assertThat(response)
.containsExactly(
"status",
"ERROR",
"results",
ImmutableList.of(),
"message",
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
assertNoTasksEnqueued("sheet");
}
@Test
void testUpdate_allowedTlds() {
doTestUpdate(
@@ -24,6 +24,7 @@ import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.disallowRegistrarAccess;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@ import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.truth.Truth;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.RegistrarContact;
@@ -46,6 +48,7 @@ import google.registry.testing.FakeClock;
import google.registry.testing.InjectExtension;
import google.registry.ui.server.SendEmailUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.CertificateChecker;
import google.registry.util.EmailMessage;
import google.registry.util.SendEmailService;
import java.io.PrintWriter;
@@ -115,6 +118,12 @@ public abstract class RegistrarSettingsActionTestCase {
AuthResult.create(
AuthLevel.USER,
UserAuthInfo.create(new User("user@email.com", "email.com", "12345"), false));
action.certificateChecker =
new CertificateChecker(
ImmutableSortedMap.of(START_OF_TIME, 825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
30,
2048,
clock);
inject.setStaticField(Ofy.class, "clock", clock);
when(req.getMethod()).thenReturn("POST");
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
@@ -18,6 +18,8 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
@@ -27,6 +29,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.registrar.Registrar;
import java.util.Map;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
/**
@@ -38,10 +41,11 @@ class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
@Test
void testPost_updateCert_success() throws Exception {
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Registrar modified =
loadRegistrar(CLIENT_ID)
.asBuilder()
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
.setClientCertificate(SAMPLE_CERT3, clock.nowUtc())
.build();
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
@@ -67,17 +71,58 @@ class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormFieldException");
}
@Test
void testPost_updateCertWithViolations_failure() {
clock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
Map<String, Object> reqJson = loadRegistrar(CLIENT_ID).toJsonMap();
reqJson.put("clientCertificate", SAMPLE_CERT);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", reqJson));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response)
.containsEntry(
"message",
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
}
@Test
void testPost_updateFailoverCertWithViolations_failure() {
clock.setTo(DateTime.parse("2055-11-01T00:00:00Z"));
Map<String, Object> reqJson = loadRegistrar(CLIENT_ID).toJsonMap();
reqJson.put("failoverClientCertificate", SAMPLE_CERT2);
Map<String, Object> response =
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", reqJson));
assertThat(response).containsEntry("status", "ERROR");
assertThat(response)
.containsEntry(
"message",
"Certificate is expired.\nCertificate validity period is too long; it must be less"
+ " than or equal to 398 days.");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: IllegalArgumentException");
}
@Test
void testChangeCertificates() throws Exception {
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Map<String, Object> jsonMap = loadRegistrar(CLIENT_ID).toJsonMap();
jsonMap.put("clientCertificate", SAMPLE_CERT);
jsonMap.put("clientCertificate", SAMPLE_CERT3);
jsonMap.put("failoverClientCertificate", null);
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update", "id", CLIENT_ID, "args", jsonMap));
assertThat(response).containsEntry("status", "SUCCESS");
Registrar registrar = loadRegistrar(CLIENT_ID);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT3);
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT3_HASH);
assertThat(registrar.getFailoverClientCertificate()).isNull();
assertThat(registrar.getFailoverClientCertificateHash()).isNull();
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
@@ -86,14 +131,15 @@ class SecuritySettingsTest extends RegistrarSettingsActionTestCase {
@Test
void testChangeFailoverCertificate() throws Exception {
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
Map<String, Object> jsonMap = loadRegistrar(CLIENT_ID).toJsonMap();
jsonMap.put("failoverClientCertificate", SAMPLE_CERT2);
jsonMap.put("failoverClientCertificate", SAMPLE_CERT3);
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update", "id", CLIENT_ID, "args", jsonMap));
assertThat(response).containsEntry("status", "SUCCESS");
Registrar registrar = loadRegistrar(CLIENT_ID);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT3);
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT3_HASH);
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
verifyNotificationEmailsSent();
}
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-C-EXAMPLE-17-23-2001">
<msgQ count="1" id="%ID%">
<qDate>2001-01-01T00:00:00Z</qDate>
<msg>Transfer requested.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-C-EXAMPLE-17-22-2001">
<msgQ count="1" id="%ID%">
<qDate>2001-01-06T00:00:00Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>
@@ -4,7 +4,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-C-EXAMPLE-17-21-2001">
<msgQ count="1" id="%ID%">
<qDate>2001-01-06T00:00:00Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-8-TLD-17-18-2001">
<msgQ count="1" id="1-8-TLD-23-24-2001">
<qDate>2001-06-07T00:00:00Z</qDate>
<msg>Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z.</msg>
</msgQ>
@@ -523,6 +523,7 @@ class google.registry.model.poll.PollMessage$OneTime {
}
class google.registry.model.rde.RdeRevision {
@Id java.lang.String id;
google.registry.model.UpdateAutoTimestamp updateTimestamp;
int revision;
}
class google.registry.model.registrar.Registrar {
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
+12 -9
View File
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4
View File
@@ -61,3 +61,7 @@ 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
V64__transfer_history_columns.sql
V65__local_date_date_type.sql
V66__create_rde_revision.sql
V67__grace_period_history_ids.sql
@@ -0,0 +1,21 @@
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
ALTER TABLE "Domain" ADD COLUMN transfer_billing_recurrence_history_id int8;
ALTER TABLE "Domain" ADD COLUMN transfer_autorenew_poll_message_history_id int8;
ALTER TABLE "Domain" ADD COLUMN transfer_billing_event_history_id int8;
ALTER TABLE "DomainHistory" ADD COLUMN transfer_billing_recurrence_history_id int8;
ALTER TABLE "DomainHistory" ADD COLUMN transfer_autorenew_poll_message_history_id int8;
ALTER TABLE "DomainHistory" ADD COLUMN transfer_billing_event_history_id int8;
@@ -0,0 +1,15 @@
-- 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 "Spec11ThreatMatch" ALTER COLUMN "check_date" TYPE date USING check_date::date;
@@ -0,0 +1,22 @@
-- 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 "RdeRevision" (
tld TEXT NOT NULL,
mode TEXT NOT NULL,
date date NOT NULL,
update_timestamp timestamptz,
revision int4 NOT NULL,
PRIMARY KEY (tld, mode, date)
);
@@ -0,0 +1,26 @@
-- 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 "GracePeriod" ADD COLUMN billing_event_history_id int8;
ALTER TABLE "GracePeriod" ADD COLUMN billing_recurrence_history_id int8;
ALTER TABLE ONLY public."GracePeriod"
DROP CONSTRAINT fk2mys4hojm6ev2g9tmy5aq6m7g;
ALTER TABLE ONLY public."GracePeriod"
ADD CONSTRAINT fk_grace_period_domain_repo_id
FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id)
DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE "GracePeriod" ALTER COLUMN id drop default;
DROP SEQUENCE "GracePeriod_id_seq";
@@ -271,8 +271,11 @@
tld text,
transfer_billing_cancellation_id int8,
transfer_billing_recurrence_id int8,
transfer_billing_recurrence_history_id int8,
transfer_autorenew_poll_message_id int8,
transfer_autorenew_poll_message_history_id int8,
transfer_billing_event_id int8,
transfer_billing_event_history_id int8,
transfer_renew_period_unit text,
transfer_renew_period_value int4,
transfer_registration_expiration_time timestamptz,
@@ -326,8 +329,11 @@
tld text,
transfer_billing_cancellation_id int8,
transfer_billing_recurrence_id int8,
transfer_billing_recurrence_history_id int8,
transfer_autorenew_poll_message_id int8,
transfer_autorenew_poll_message_history_id int8,
transfer_billing_event_id int8,
transfer_billing_event_history_id int8,
transfer_renew_period_unit text,
transfer_renew_period_value int4,
transfer_registration_expiration_time timestamptz,
@@ -377,9 +383,11 @@
);
create table "GracePeriod" (
id bigserial not null,
id int8 not null,
billing_event_id int8,
billing_event_history_id int8,
billing_recurrence_id int8,
billing_recurrence_history_id int8,
registrar_id text not null,
domain_repo_id text not null,
expiration_time timestamptz not null,
@@ -488,6 +496,15 @@
primary key (revision_id)
);
create table "RdeRevision" (
date date not null,
mode text not null,
tld text not null,
update_timestamp timestamptz,
revision int4 not null,
primary key (date, mode, tld)
);
create table "Registrar" (
registrar_id text not null,
allowed_tlds text[],
@@ -591,7 +608,7 @@
create table "Spec11ThreatMatch" (
id bigserial not null,
check_date text not null,
check_date date not null,
domain_name text not null,
domain_repo_id text not null,
registrar_id text not null,
@@ -369,7 +369,10 @@ CREATE TABLE public."Domain" (
autorenew_end_time timestamp with time zone,
billing_recurrence_history_id bigint,
autorenew_poll_message_history_id bigint,
deletion_poll_message_history_id bigint
deletion_poll_message_history_id bigint,
transfer_billing_recurrence_history_id bigint,
transfer_autorenew_poll_message_history_id bigint,
transfer_billing_event_history_id bigint
);
@@ -439,7 +442,10 @@ CREATE TABLE public."DomainHistory" (
history_period_value integer,
billing_recurrence_history_id bigint,
autorenew_poll_message_history_id bigint,
deletion_poll_message_history_id bigint
deletion_poll_message_history_id bigint,
transfer_billing_recurrence_history_id bigint,
transfer_autorenew_poll_message_history_id bigint,
transfer_billing_event_history_id bigint
);
@@ -509,29 +515,12 @@ CREATE TABLE public."GracePeriod" (
registrar_id text NOT NULL,
domain_repo_id text NOT NULL,
expiration_time timestamp with time zone NOT NULL,
type text NOT NULL
type text NOT NULL,
billing_event_history_id bigint,
billing_recurrence_history_id bigint
);
--
-- Name: GracePeriod_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public."GracePeriod_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: GracePeriod_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public."GracePeriod_id_seq" OWNED BY public."GracePeriod".id;
--
-- Name: Host; Type: TABLE; Schema: public; Owner: -
--
@@ -676,6 +665,19 @@ CREATE SEQUENCE public."PremiumList_revision_id_seq"
ALTER SEQUENCE public."PremiumList_revision_id_seq" OWNED BY public."PremiumList".revision_id;
--
-- Name: RdeRevision; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."RdeRevision" (
tld text NOT NULL,
mode text NOT NULL,
date date NOT NULL,
update_timestamp timestamp with time zone,
revision integer NOT NULL
);
--
-- Name: Registrar; Type: TABLE; Schema: public; Owner: -
--
@@ -841,7 +843,7 @@ ALTER SEQUENCE public."ReservedList_revision_id_seq" OWNED BY public."ReservedLi
CREATE TABLE public."Spec11ThreatMatch" (
id bigint NOT NULL,
check_date text NOT NULL,
check_date date NOT NULL,
domain_name text NOT NULL,
domain_repo_id text NOT NULL,
registrar_id text NOT NULL,
@@ -958,13 +960,6 @@ ALTER TABLE ONLY public."ClaimsList" ALTER COLUMN revision_id SET DEFAULT nextva
ALTER TABLE ONLY public."DomainTransactionRecord" ALTER COLUMN id SET DEFAULT nextval('public."DomainTransactionRecord_id_seq"'::regclass);
--
-- Name: GracePeriod id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GracePeriod" ALTER COLUMN id SET DEFAULT nextval('public."GracePeriod_id_seq"'::regclass);
--
-- Name: PremiumList revision_id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -1160,6 +1155,14 @@ ALTER TABLE ONLY public."PremiumList"
ADD CONSTRAINT "PremiumList_pkey" PRIMARY KEY (revision_id);
--
-- Name: RdeRevision RdeRevision_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."RdeRevision"
ADD CONSTRAINT "RdeRevision_pkey" PRIMARY KEY (tld, mode, date);
--
-- Name: RegistrarPoc RegistrarPoc_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -1613,14 +1616,6 @@ ALTER TABLE ONLY public."RegistryLock"
ADD CONSTRAINT fk2lhcwpxlnqijr96irylrh1707 FOREIGN KEY (relock_revision_id) REFERENCES public."RegistryLock"(revision_id);
--
-- Name: GracePeriod fk2mys4hojm6ev2g9tmy5aq6m7g; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GracePeriod"
ADD CONSTRAINT fk2mys4hojm6ev2g9tmy5aq6m7g FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id);
--
-- Name: Domain fk2u3srsfbei272093m3b3xwj23; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@@ -1869,6 +1864,14 @@ ALTER TABLE ONLY public."GracePeriod"
ADD CONSTRAINT fk_grace_period_billing_recurrence_id FOREIGN KEY (billing_recurrence_id) REFERENCES public."BillingRecurrence"(billing_recurrence_id);
--
-- Name: GracePeriod fk_grace_period_domain_repo_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GracePeriod"
ADD CONSTRAINT fk_grace_period_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id) DEFERRABLE INITIALLY DEFERRED;
--
-- Name: Host fk_host_superordinate_domain; Type: FK CONSTRAINT; Schema: public; Owner: -
--
+5 -1
View File
@@ -53,7 +53,7 @@ ext {
'com.google.code.gson:gson:2.8.5',
'com.google.dagger:dagger-compiler:2.28',
'com.google.dagger:dagger:2.28',
'com.google.errorprone:error_prone_annotations:2.3.3',
'com.google.errorprone:error_prone_annotations:2.3.4',
'com.google.flogger:flogger-system-backend:0.1',
'com.google.flogger:flogger:0.1',
'com.google.guava:guava-testlib:29.0-jre',
@@ -85,6 +85,7 @@ ext {
'com.sun.xml.bind:jaxb-xjc:2.2.11',
'com.thoughtworks.qdox:qdox:1.12.1',
'dnsjava:dnsjava:2.1.7',
'guru.nidi:graphviz-java-all-j2v8:0.17.0',
'io.github.classgraph:classgraph:4.8.52',
'io.github.java-diff-utils:java-diff-utils:4.0',
'io.netty:netty-buffer:4.1.50.Final',
@@ -142,6 +143,7 @@ ext {
'org.hibernate:hibernate-hikaricp:5.4.17.Final',
'org.joda:joda-money:1.0.1',
'org.json:json:20160810',
'org.jsoup:jsoup:1.13.1',
'org.mockito:mockito-core:3.3.3',
'org.mockito:mockito-junit-jupiter:3.3.3',
'org.mortbay.jetty:jetty:6.1.26',
@@ -158,7 +160,9 @@ ext {
'org.testcontainers:testcontainers:1.14.3',
'org.yaml:snakeyaml:1.17',
'us.fatehi:schemacrawler:16.10.1',
'us.fatehi:schemacrawler-api:16.10.1',
'us.fatehi:schemacrawler-diagram:16.10.1',
'us.fatehi:schemacrawler-tools:16.10.1',
'xerces:xmlParserAPIs:2.6.2',
'xpp3:xpp3:1.1.4c'
]
@@ -1,24 +1,27 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.7.0
com.github.kevinstern:software-and-algorithms:1.0
com.github.stephenc.jcip:jcip-annotations:1.0-1
com.google.auto:auto-common:0.10
com.google.code.findbugs:jFormatString:3.0.0
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotation:2.3.3
com.google.errorprone:error_prone_annotations:2.3.3
com.google.errorprone:error_prone_check_api:2.3.3
com.google.errorprone:error_prone_core:2.3.3
com.google.errorprone:error_prone_type_annotations:2.3.3
com.google.errorprone:error_prone_annotation:2.3.4
com.google.errorprone:error_prone_annotations:2.3.4
com.google.errorprone:error_prone_check_api:2.3.4
com.google.errorprone:error_prone_core:2.3.4
com.google.errorprone:error_prone_type_annotations:2.3.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:27.0.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.1
com.google.protobuf:protobuf-java:3.4.0
com.googlecode.java-diff-utils:diffutils:1.3.0
org.checkerframework:checker-qual:2.5.3
org.checkerframework:dataflow:2.5.3
org.checkerframework:javacutil:2.5.3
org.checkerframework:checker-qual:3.0.0
org.checkerframework:dataflow:3.0.0
org.checkerframework:javacutil:3.0.0
org.codehaus.mojo:animal-sniffer-annotations:1.17
org.pcollections:pcollections:2.1.2
org.plumelib:plume-util:1.0.6
org.plumelib:reflection-util:0.0.2
org.plumelib:require-javadoc:0.1.0
@@ -6,6 +6,10 @@ aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_macosx_x86_64:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86:4.6.0
com.eclipsesource.j2v8:j2v8_win32_x86_64:4.6.0
com.fasterxml.jackson.core:jackson-annotations:2.10.2
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.10.2
@@ -130,6 +134,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -177,6 +184,7 @@ javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
junit:junit:4.12
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -198,6 +206,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -228,6 +237,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -242,6 +252,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.14.3
@@ -251,6 +263,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1
@@ -129,6 +129,9 @@ com.zaxxer:HikariCP:3.2.0
commons-codec:commons-codec:1.13
commons-logging:commons-logging:1.2
dnsjava:dnsjava:2.1.7
guru.nidi.com.kitfox:svgSalamander:1.1.3
guru.nidi:graphviz-java-all-j2v8:0.17.0
guru.nidi:graphviz-java:0.17.0
io.dropwizard.metrics:metrics-core:3.2.6
io.github.classgraph:classgraph:4.8.65
io.grpc:grpc-all:1.27.2
@@ -175,6 +178,7 @@ javax.validation:validation-api:1.0.0.GA
javax.xml.bind:jaxb-api:2.3.1
jline:jline:1.0
joda-time:joda-time:2.10.5
net.arnx:nashorn-promise:0.1.1
net.bytebuddy:byte-buddy:1.10.10
net.java.dev.jna:jna-platform:5.5.0
net.java.dev.jna:jna:5.5.0
@@ -196,6 +200,7 @@ org.apache.beam:beam-vendor-grpc-1_26_0:0.3
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.beam:beam-vendor-sdks-java-extensions-protobuf:2.23.0
org.apache.commons:commons-compress:1.20
org.apache.commons:commons-exec:1.3
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
@@ -225,6 +230,7 @@ org.jboss:jandex:2.1.3.Final
org.jetbrains:annotations:19.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
@@ -239,6 +245,8 @@ org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:jcl-over-slf4j:1.7.30
org.slf4j:jul-to-slf4j:1.7.30
org.slf4j:slf4j-api:1.7.30
org.testcontainers:database-commons:1.14.3
org.testcontainers:jdbc:1.14.3
@@ -247,6 +255,7 @@ org.testcontainers:testcontainers:1.14.3
org.threeten:threetenbp:1.4.1
org.tukaani:xz:1.8
org.w3c.css:sac:1.3
org.webjars.npm:viz.js-for-graphviz-java:2.1.3
org.xerial.snappy:snappy-java:1.1.4
org.yaml:snakeyaml:1.17
us.fatehi:schemacrawler-api:16.10.1

Some files were not shown because too many files have changed in this diff Show More