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

Compare commits

..

36 Commits

Author SHA1 Message Date
Weimin Yu 4f988d42c7 Allow Entity instantiation without AppEngineRule (#559)
* Allow Entity instantiation without AppEngineRule

Defined an extension that sets up a fake AppEngine environment
so that Datastore entities can be instantiated.

* Allow Entity instantiation without AppEngineRule

Defined an extension that sets up a fake AppEngine environment
so that Datastore entities can be instantiated.
2020-04-16 17:03:27 -04:00
Weimin Yu 9b47a6cfee Hack to call setup and teardown in JUnit5 suite (#560)
* Hack to call setup and teardown in JUnit5 suite

JUnit 5 runner does not support @BeforeAll and @AfterAll declared
in the Suite class (as opposed to the member classes). However,
staying with the JUnit 4 suite runner would prevent any member
classes from migrating to JUnit 5.

We use a hack to invoke suite-level set up and teardown from tests.
This change is safe in that if the JUnit 5 runner implementation changes
behavior, we will only see false alarms.
2020-04-16 14:46:08 -04:00
Shicong Huang 9db4d1a082 Add a listener to invoke entity callbacks (#551)
* Add a listener to invoke entity callbacks

* Resolve comments

* Add test
2020-04-16 14:30:43 -04:00
Michael Muller ec22d4d1a0 Implement VKeyConverter (#538)
* Implement VKeyConverter

Implement a SQL converter that can be used for VKey objects.

Caveats:

- This only works with string columns (there's an excellent chance that all of
  our VKeys will use SQL string columns).
- Using this dpesn't establish a foreign key constraint between the referenced
  type (the "T" in VKey<T>) and the entity itself: this needs to be
  defined manually in the schema.
2020-04-16 09:45:23 -04:00
Weimin Yu 0fcf26def0 Exclude proxy configs from the FOSS jar (#558)
* Exclude proxy configs from the FOSS jar

No sensitve data exposed.

Added a todo to modify the release process and stop
building the foss jar on the merged repo.
2020-04-15 12:21:41 -04:00
gbrodman 3d88ba4e1b Add verification that domain labels aren't multi-level domains (#553)
* Add verification that domain labels aren't multi-level domains

In addition, I did a bit of test refactoring because previously, the
CreateOrUpdateReserveListCommandTestCase test cases weren't actually
testing the proper things -- they were failing with
IllegalArgumentExceptions, but not the right ones.

* Change test name and use IDN library

* Handle numeric labels

String like "0" or "2018" are valid labels but not valid domain names

* Use IDN validation with a dummy TLD
2020-04-15 11:54:40 -04:00
Weimin Yu 580a3b6981 Disable JpaEntityCoverageCheck by default (#555)
* Disable JpaEntityCoverageCheck by default

Only members of SqlIntegrationTestSuite should enable the check,
which incurs per-test overhead.
2020-04-14 12:48:21 -04:00
gbrodman 6990d6058f Allow a --token option when checking a domain (#556)
* Allow a --token option when checking a domain
2020-04-14 10:20:27 -04:00
gbrodman dfeed63c40 Run automated NPM update (#554) 2020-04-11 11:47:25 -04:00
Lai Jiang 9eac9621cb Add a Test workaround for certain Linux distro (#552)
On Arch Linux, DumpGoldenSchemaCommandTest failed due to the follow
error:

java.lang.RuntimeException: Container.ExecResult(exitCode=1, stdout=, stderr=pg_dump: [archiver] could not open output file "/tmp/pg_dump.out": Is a directory)

However I cannot figure out why this permission error happens, as the
docker command is executed as root. Saving the pg_dump output to a
temporary file and copy it over the mapped file works, so I don't
know...
2020-04-10 12:44:36 -04:00
Weimin Yu b7efc5dd25 Migrate SqlIntegrationTestSuite members to Junit5 (#550)
* Migrate SqlIntegrationTestSuite members  to Junit5

Made InjectRule and EntityTestCase work with both JUnit4 and 5.

Note that "@RunWith(JUnit4.class)" is no longer needed on
JUnit4 test classes. Therefore, its removal from EntityTestCase
has no impact on child classes. All of them are still included in
tests.

Migrated remaining member classes in SqlIntegrationTestSuite to JUnit5.
2020-04-09 12:54:16 -04:00
Weimin Yu 1911c11623 Add Test suite support for JUnit 5 classes (#549)
* Add Test suite support for JUnit 5 classes

Added Gradle dependencies and updated lockfiles.

Updated SqlInegrationTestSuite to use new annotations.

Migrated one member class in SqlIntegrationTestSuite (CursorDaoTest)
to JUnit 5, and verified that the new Suite runner can handle a
mixture of JUnit 4 and 5 tests in one suite.

Note that Gradle tests that run TestSuites must choose JUnit 4.
Updated core/build.gradle and integration/build.gradle.
2020-04-07 21:06:49 -04:00
Weimin Yu b8df0bac24 Make AppEngineRule work with JUnit 5 (#548)
* Make AppEngineRule work with JUnit 5

Made AppEngineRule work with both JUnit4 and JUnit 5 and applied
it to PremiumListTest.

Next step is to convert SqlIntegrationTestSuite.java to JUnit5.
2020-04-07 14:59:25 -04:00
Lai Jiang 0561c7754e Upgrade to Gradle 6.3 (#546) 2020-04-06 22:14:14 -04:00
Weimin Yu 904f16c8b5 Actually run JUnit 5 tests (#545)
* Actually run JUnit 5 tests

In Gradle, JUnit 5 must be explicitly enabled with a call to
test.useJUnitPlatform().

The FilteringTest used in :core must also enable JUnit5 separately.

Fixed AppEngineRule to work with the few tests that have migrated
to JUnit5.

More work is needed with AppEngine before we can migrate tests
that actually use Cloud SQL.

For context, with @EnableRuleMigrationSupport, JUnit 5 runner calls
an external resource's before() and after() methods. TestRule.apply()
is not called, therefore any setup done their will be bypassed with
JUnit 5.
2020-04-06 13:26:38 -04:00
Weimin Yu 3a7d71e411 Upgrade CompareDbBackup for Datastore V3 (#543)
* Upgrade CompareDbBackup for Datastore V3

Upgrade the CompareDbBackup class to work with latest
Datastore backup directory structure.

Also fixed a few unrelated minor issues:
- Remaining cases of improper use of System.setOut
- Wrong import order in one class
2020-04-06 10:50:38 -04:00
Shicong Huang 1ded33ecea Resolve warnings in the Hibernate log (#542) 2020-04-03 18:04:55 -04:00
Shicong Huang bf4659f11c Auto-apply JPA converters for map type (#520)
* Add map converter

* Delete old map usertype

* Refactor bind

* Change to use map entry

* Use Map.Entry
2020-04-03 10:47:42 -04:00
Shicong Huang bac1998d6a Auto-apply JPA converters for map type (#520)
* Add map converter

* Delete old map usertype

* Refactor bind

* Change to use map entry

* Use Map.Entry
2020-04-02 16:43:08 -04:00
gbrodman 4a34369ba9 Submit a task to relock domains if desired upon verification (#529)
* Submit a task to relock domains if desired upon verification

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

* Respond to CR
2020-04-02 15:18:29 -04:00
Shicong Huang db7d49801d Supress exccesive logging message from Cloud SQL (#540)
* Supress exccesive logging message from Cloud SQL

* Upgrade package versions that were downgraded before
2020-03-31 17:57:18 -04:00
sarahcaseybot 0c52d209e5 Fix IllegalArgumentException (#536)
* Fix IllegalArgumentException

* Add more information about global locks

* Add null checks
2020-03-30 11:36:09 -04:00
gbrodman 73b98d298b Add a set of radio buttons for relock duration (#535)
* Add a set of radio buttons for relock duration
2020-03-30 11:06:32 -04:00
Michael Muller 7880aab386 Fix optional access for VKey nested keys (#539)
* Fix optional access for VKey nested keys

We should have used ofNullable() instead of of() for key creation.  Also add a
unit test.
2020-03-30 11:01:25 -04:00
Michael Muller fa9134328a Improve error information in coverage test. (#537)
* Improve error information in coverage test.

If the golden schema isn't up-to-date with the persistence model, the coverage
tests fail with an exception chain that ends in a PSQLException 'relation
"TableName" does not exist' which is kind of misleading when the problem is
that your golden schema isn't up-to-date.

Check for this error in the coverage tests and generate a more informative
error message indicating a likely root cause.
2020-03-27 14:58:01 -04:00
Michael Muller 5b452bf074 Key to VKey conversion for Nameserver (#476)
* Key to VKey conversion for Nameserver

This change illustrates the conversion of a single key in the system
(Key<HostResource> as used in the "nameservers" field of DomainBase) to a
VKey.

It currently builds, but had some curious (possibly unrelated?) test failures
that I have not fully investigated.

* Latest round of changes, all tests pass.

* Changes requested in review.

* Fix problems with null check in VKey accessors

Add maybeGet versions of getSqlKey() and getOfyKey() that return Optional
objects and make the nameserver management routines use those instead.
2020-03-26 17:13:30 -04:00
Weimin Yu f749236500 Reuse JPA EntityManagerFactory in tests (#533)
* Reuse JPA EntityManagerFactory in tests

Reuse EntityManagerFactory instance in tests if the requested schema
stays the same. Only truncate tables and reset sequences when reusing.

Note that the jdbc driver needs to be informed to expect out-of-band
schema changes.
2020-03-26 16:51:47 -04:00
gbrodman e7825fae66 Don't rely on the password field's existence for admins (#534)
* Don't rely on the password field's existence for admins

We don't have the field when it's an admin user that's logged in. A
nicer language would have caught this unfortunately.
2020-03-26 15:55:54 -04:00
gbrodman 91155d6c67 Fix up lock modal wording (#532)
* Fix up lock modal wording

When locking a domain, the "domain" variable is null so we shouldn't
display it.
2020-03-26 15:52:11 -04:00
gbrodman 2ff1026cfd Handle null GAE user IDs gracefully (for non-admins) (#531)
Unfortunately in our testing environments, we're all admins so it's easy
to miss things like this.
2020-03-26 14:29:05 -04:00
Weimin Yu f1c46b8030 Drop postgresql schema instead of database in Sql tests (#530)
* Drop schema instead of database in Sql tests

Speed up the database cleanup between tests by dropping the schema
instead of the database. The new approach is much faster.

Ad hoc measurement on my desktop shows that :core:sqlIntegrationTest
improves from 73 seconds to 48 seconds, and :core:standardTest
improves from 12m40 to 7m40.
2020-03-25 21:03:58 -04:00
gbrodman d663bf4db5 Add CSS spinner while loading locks content (#527)
* Add CSS spinner while loading locks content
2020-03-24 15:33:17 -04:00
gbrodman acf0baf048 Fix semantic merge conflict (#528) 2020-03-24 12:29:11 -04:00
gbrodman 2998b56982 Add min length to password fields (#524)
* Add min length to password fields
2020-03-24 11:16:05 -04:00
gbrodman 7b602300d8 Use the relock duration if provided in RLPA (#519)
* Use the relock duration if provided in RLPA
2020-03-24 10:33:43 -04:00
Ben McIlwain fe760d7066 Allow backwards compatibility with JUnit 4 @Rules in JUnit 5 (#526)
* Allow backwards compatibility with JUnit 4 @Rules in JUnit 5

This allows us to defer having to re-implement all of our JUnit 4 Rules as JUnit
5 extensions for now, while continuing to in-place upgrade all existing JUnit 4
test classes to JUnit 5.

As proof of concept, this upgrades PremiumListUtils (which uses AppEngineRule,
our largest and most complicated @Rule) to use the JUnit 5 test runner.

* Apply formatter to entire file
2020-03-23 14:45:54 -04:00
233 changed files with 4818 additions and 2524 deletions
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -20,10 +20,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -20,10 +20,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -21,10 +21,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -21,10 +21,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
+21
View File
@@ -177,6 +177,8 @@ dependencies {
compile deps['com.beust:jcommander']
compile deps['com.google.api-client:google-api-client']
compile deps['com.google.api-client:google-api-client-appengine']
compile deps['com.google.api-client:google-api-client-servlet']
compile deps['com.google.monitoring-client:metrics']
compile deps['com.google.monitoring-client:stackdriver']
compile deps['com.google.api-client:google-api-client-java6']
@@ -216,6 +218,8 @@ dependencies {
compile deps['com.google.oauth-client:google-oauth-client']
compile deps['com.google.oauth-client:google-oauth-client-java6']
compile deps['com.google.oauth-client:google-oauth-client-jetty']
compile deps['com.google.oauth-client:google-oauth-client-appengine']
compile deps['com.google.oauth-client:google-oauth-client-servlet']
compile deps['com.google.re2j:re2j']
compile deps['com.google.template:soy']
compile deps['com.googlecode.json-simple:json-simple']
@@ -262,6 +266,7 @@ dependencies {
testCompile deps['org.seleniumhq.selenium:selenium-chrome-driver']
testCompile deps['org.seleniumhq.selenium:selenium-java']
testCompile deps['org.seleniumhq.selenium:selenium-remote-driver']
runtimeOnly deps['org.slf4j:slf4j-jdk14']
testCompile deps['org.testcontainers:jdbc']
compile deps['org.testcontainers:postgresql']
testCompile deps['org.testcontainers:selenium']
@@ -303,6 +308,9 @@ dependencies {
testCompile deps['junit:junit']
testCompile deps['org.junit.jupiter:junit-jupiter-api']
testCompile deps['org.junit.jupiter:junit-jupiter-engine']
testCompile deps['org.junit.jupiter:junit-jupiter-migrationsupport']
testCompile deps['org.junit.platform:junit-platform-runner']
testCompile deps['org.junit.platform:junit-platform-suite-api']
testCompile deps['org.junit.vintage:junit-vintage-engine']
testCompile deps['org.mockito:mockito-core']
runtime deps['org.postgresql:postgresql']
@@ -640,6 +648,10 @@ artifacts {
*/
class FilteringTest extends Test {
FilteringTest() {
useJUnitPlatform();
}
private void applyTestFilter() {
if (project.testFilter) {
testNameIncludePatterns = project.testFilter.split(',')
@@ -727,6 +739,10 @@ task registryToolIntegrationTest {
// Dedicated test suite for schema-dependent tests.
task sqlIntegrationTest(type: FilteringTest) {
// TestSuite still requires a JUnit 4 runner, which knows how to handle JUnit 5 tests.
// Here we need to override parent's choice of JUnit 5. If changing this, remember to
// change :integration:sqlIntegrationTest too.
useJUnit()
excludeTestCases = false
tests = ['google/registry/schema/integration/SqlIntegrationTestSuite.*']
}
@@ -846,6 +862,8 @@ task standardTest(type: FilteringTest) {
includeAllTests()
exclude fragileTestPatterns
exclude outcastTestPatterns
// See SqlIntegrationTestSuite.java
exclude '**/*BeforeSuiteTest.*', '**/*AfterSuiteTest.*'
if (rootProject.findProperty("skipDockerIncompatibleTests") == "true") {
exclude dockerIncompatibleTestPatterns
@@ -878,11 +896,14 @@ createUberJar('nomulus', 'nomulus', 'google.registry.tools.RegistryTool')
// A jar with classes and resources from main sourceSet, excluding internal
// data. See comments on configurations.nomulus_test above for details.
// TODO(weiminyu): release process should build this using the public repo to eliminate the need
// for excludes.
task nomulusFossJar (type: Jar) {
archiveBaseName = 'nomulus'
archiveClassifier = 'public'
from (project.sourceSets.main.output) {
exclude 'google/registry/config/files/**'
exclude 'google/registry/proxy/config/**'
}
from (project.sourceSets.main.output) {
include 'google/registry/config/files/default-config.yaml'
+16 -15
View File
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -94,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -134,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -156,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -93,22 +94,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -133,7 +134,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
io.grpc:grpc-netty:1.17.1
@@ -154,10 +155,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -190,8 +191,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
+17 -15
View File
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -95,22 +96,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -135,7 +136,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -157,10 +158,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -194,8 +195,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -234,6 +235,7 @@ 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:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -95,22 +96,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -135,7 +136,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -157,10 +158,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -231,6 +232,7 @@ 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:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -94,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -134,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -156,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -93,22 +94,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -133,7 +134,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
io.grpc:grpc-netty:1.17.1
@@ -154,10 +155,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -191,8 +192,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -94,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -134,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -156,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -94,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -134,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -156,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
+16 -15
View File
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -94,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -134,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -156,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.0.23
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -95,22 +96,22 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -135,7 +136,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -157,10 +158,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -193,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
org.apache.commons:commons-compress:1.19
org.apache.commons:commons-lang3:3.5
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -231,6 +232,7 @@ 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:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -96,11 +97,11 @@ com.google.guava:guava-testlib:28.2-jre
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
@@ -108,11 +109,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:contrib:1.0.7
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -143,7 +144,7 @@ io.github.classgraph:classgraph:4.8.52
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -165,10 +166,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -208,8 +209,8 @@ org.apache.commons:commons-lang3:3.8.1
org.apache.commons:commons-text:1.6
org.apache.ftpserver:ftplet-api:1.0.6
org.apache.ftpserver:ftpserver-core:1.0.6
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apache.mina:mina-core:2.0.4
org.apache.sshd:sshd-core:2.0.0
org.apache.sshd:sshd-scp:2.0.0
@@ -242,12 +243,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -95,11 +96,11 @@ com.google.guava:guava-testlib:28.2-jre
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
@@ -107,11 +108,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:contrib:1.0.7
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -142,7 +143,7 @@ io.github.classgraph:classgraph:4.8.52
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
io.grpc:grpc-netty:1.17.1
@@ -163,10 +164,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -206,8 +207,8 @@ org.apache.commons:commons-lang3:3.8.1
org.apache.commons:commons-text:1.6
org.apache.ftpserver:ftplet-api:1.0.6
org.apache.ftpserver:ftpserver-core:1.0.6
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apache.mina:mina-core:2.0.4
org.apache.sshd:sshd-core:2.0.0
org.apache.sshd:sshd-scp:2.0.0
@@ -240,12 +241,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -97,11 +98,11 @@ com.google.guava:guava-testlib:28.2-jre
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
@@ -109,11 +110,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:contrib:1.0.7
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -145,7 +146,7 @@ io.github.java-diff-utils:java-diff-utils:4.0
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -167,10 +168,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -210,8 +211,8 @@ org.apache.commons:commons-lang3:3.8.1
org.apache.commons:commons-text:1.6
org.apache.ftpserver:ftplet-api:1.0.6
org.apache.ftpserver:ftpserver-core:1.0.6
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apache.mina:mina-core:2.0.4
org.apache.sshd:sshd-core:2.0.0
org.apache.sshd:sshd-scp:2.0.0
@@ -245,12 +246,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -1,13 +1,14 @@
# 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.
androidx.annotation:annotation:1.1.0
antlr:antlr:2.7.7
aopalliance:aopalliance:1.0
args4j:args4j:2.33
cglib:cglib-nodep:2.2
com.beust:jcommander:1.60
com.fasterxml.jackson.core:jackson-annotations:2.9.10
com.fasterxml.jackson.core:jackson-core:2.9.10
com.fasterxml.jackson.core:jackson-core:2.10.2
com.fasterxml.jackson.core:jackson-databind:2.9.10
com.fasterxml:classmate:1.3.4
com.github.jnr:jffi:1.2.17
@@ -18,11 +19,11 @@ com.github.jnr:jnr-ffi:2.1.9
com.github.jnr:jnr-posix:3.0.47
com.github.jnr:jnr-unixsocket:0.21
com.github.jnr:jnr-x86asm:1.0.2
com.google.api-client:google-api-client-appengine:1.29.0
com.google.api-client:google-api-client-appengine:1.30.8
com.google.api-client:google-api-client-jackson2:1.27.0
com.google.api-client:google-api-client-java6:1.27.0
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
com.google.api-client:google-api-client-servlet:1.30.8
com.google.api-client:google-api-client:1.30.8
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
@@ -97,11 +98,11 @@ com.google.guava:guava-testlib:28.2-jre
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.gwt:gwt-user:2.8.2
com.google.http-client:google-http-client-appengine:1.29.2
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client-appengine:1.34.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client:1.34.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
@@ -109,11 +110,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:contrib:1.0.7
com.google.monitoring-client:metrics:1.0.7
com.google.monitoring-client:stackdriver:1.0.7
com.google.oauth-client:google-oauth-client-appengine:1.29.0
com.google.oauth-client:google-oauth-client-appengine:1.30.5
com.google.oauth-client:google-oauth-client-java6:1.28.0
com.google.oauth-client:google-oauth-client-jetty:1.28.0
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client-servlet:1.30.5
com.google.oauth-client:google-oauth-client:1.30.5
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
com.google.protobuf:protobuf-java-util:3.6.1
com.google.protobuf:protobuf-java:3.6.1
@@ -145,7 +146,7 @@ io.github.java-diff-utils:java-diff-utils:4.0
io.grpc:grpc-all:1.17.1
io.grpc:grpc-alts:1.17.1
io.grpc:grpc-auth:1.17.1
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.grpc:grpc-core:1.17.1
io.grpc:grpc-grpclb:1.17.1
io.grpc:grpc-netty-shaded:1.17.1
@@ -167,10 +168,10 @@ io.netty:netty-handler:4.1.30.Final
io.netty:netty-resolver:4.1.30.Final
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
io.netty:netty-transport:4.1.30.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
io.opencensus:opencensus-contrib-grpc-util:0.17.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-contrib-http-util:0.24.0
it.unimi.dsi:fastutil:6.5.16
javax.activation:activation:1.1
javax.activation:javax.activation-api:1.2.0
@@ -210,8 +211,8 @@ org.apache.commons:commons-lang3:3.8.1
org.apache.commons:commons-text:1.6
org.apache.ftpserver:ftplet-api:1.0.6
org.apache.ftpserver:ftpserver-core:1.0.6
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apache.mina:mina-core:2.0.4
org.apache.sshd:sshd-core:2.0.0
org.apache.sshd:sshd-scp:2.0.0
@@ -245,12 +246,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -278,6 +283,7 @@ 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:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -30,6 +30,8 @@ import google.registry.model.EppResource;
import google.registry.model.ImmutableObject;
import google.registry.model.eppcommon.Trid;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.schema.domain.RegistryLock;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import javax.inject.Inject;
@@ -148,15 +150,35 @@ public final class AsyncTaskEnqueuer {
/** Enqueues a task to asynchronously refresh DNS for a renamed host. */
public void enqueueAsyncDnsRefresh(HostResource host, DateTime now) {
Key<HostResource> hostKey = Key.create(host);
VKey<HostResource> hostKey = host.createKey();
logger.atInfo().log("Enqueuing async DNS refresh for renamed host %s.", hostKey);
addTaskToQueueWithRetry(
asyncDnsRefreshPullQueue,
TaskOptions.Builder.withMethod(Method.PULL)
.param(PARAM_HOST_KEY, hostKey.getString())
.param(PARAM_HOST_KEY, hostKey.getOfyKey().getString())
.param(PARAM_REQUESTED_TIME, now.toString()));
}
/**
* Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked.
*
* <p>Note: the relockDuration must be present on the lock object.
*/
public void enqueueDomainRelock(RegistryLock lock) {
checkArgument(
lock.getRelockDuration().isPresent(),
"Lock with ID %s not configured for relock",
lock.getRevisionId());
addTaskToQueueWithRetry(
asyncActionsPushQueue,
TaskOptions.Builder.withUrl(RelockDomainAction.PATH)
.method(Method.POST)
.param(
RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM,
String.valueOf(lock.getRevisionId()))
.countdownMillis(lock.getRelockDuration().get().getMillis()));
}
/**
* Adds a task to a queue with retrying, to avoid aborting the entire flow over a transient issue
* enqueuing a task.
@@ -85,6 +85,7 @@ import google.registry.model.poll.PendingActionNotificationResponse.HostPendingA
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.server.Lock;
import google.registry.persistence.VKey;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@@ -284,7 +285,9 @@ public class DeleteContactsAndHostsAction implements Runnable {
if (resourceKey.getKind().equals(KIND_CONTACT)) {
return domain.getReferencedContacts().contains(resourceKey);
} else if (resourceKey.getKind().equals(KIND_HOST)) {
return domain.getNameservers().contains(resourceKey);
return domain
.getNameservers()
.contains(VKey.createOfy(HostResource.class, (Key<HostResource>) resourceKey));
} else {
throw new IllegalStateException("EPP resource key of unknown type: " + resourceKey);
}
@@ -52,6 +52,7 @@ import google.registry.mapreduce.inputs.NullInput;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.HostResource;
import google.registry.model.server.Lock;
import google.registry.persistence.VKey;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@@ -206,7 +207,9 @@ public class RefreshDnsOnHostRenameAction implements Runnable {
Key<HostResource> referencingHostKey = null;
for (DnsRefreshRequest request : refreshRequests) {
if (isActive(domain, request.lastUpdateTime())
&& domain.getNameservers().contains(request.hostKey())) {
&& domain
.getNameservers()
.contains(VKey.createOfy(HostResource.class, request.hostKey()))) {
referencingHostKey = request.hostKey();
break;
}
@@ -50,6 +50,7 @@ import javax.inject.Inject;
public class RelockDomainAction implements Runnable {
public static final String PATH = "/_dr/task/relockDomain";
public static final String OLD_UNLOCK_REVISION_ID_PARAM = "oldUnlockRevisionId";
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -59,7 +60,7 @@ public class RelockDomainAction implements Runnable {
@Inject
public RelockDomainAction(
@Parameter("oldUnlockRevisionId") long oldUnlockRevisionId,
@Parameter(OLD_UNLOCK_REVISION_ID_PARAM) long oldUnlockRevisionId,
DomainLockUtils domainLockUtils,
Response response) {
this.oldUnlockRevisionId = oldUnlockRevisionId;
@@ -80,11 +80,9 @@ public final class ResourceFlowUtils {
final Function<DomainBase, ImmutableSet<?>> getPotentialReferences) throws EppException {
// Enter a transactionless context briefly.
EppException failfastException =
tm()
.doTransactionless(
tm().doTransactionless(
() -> {
final ForeignKeyIndex<R> fki =
ForeignKeyIndex.load(resourceClass, targetId, now);
final ForeignKeyIndex<R> fki = ForeignKeyIndex.load(resourceClass, targetId, now);
if (fki == null) {
return new ResourceDoesNotExistException(resourceClass, targetId);
}
@@ -99,8 +97,7 @@ public final class ResourceFlowUtils {
.limit(FAILFAST_CHECK_COUNT)
.keys();
Predicate<DomainBase> predicate =
domain ->
getPotentialReferences.apply(domain).contains(fki.getResourceKey());
domain -> getPotentialReferences.apply(domain).contains(fki.getResourceKey());
return ofy().load().keys(keys).values().stream().anyMatch(predicate)
? new ResourceToDeleteIsReferencedException()
: null;
@@ -14,6 +14,7 @@
package google.registry.flows.domain;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.flows.FlowUtils.persistEntityChanges;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
@@ -95,6 +96,7 @@ import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.CreateData.DomainCreateData;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.host.HostResource;
import google.registry.model.index.EppResourceIndex;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.ofy.ObjectifyService;
@@ -108,6 +110,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.persistence.VKey;
import google.registry.tmch.LordnTaskUtils;
import java.util.Optional;
import javax.inject.Inject;
@@ -352,7 +355,11 @@ public class DomainCreateFlow implements TransactionalFlow {
.setRegistrant(command.getRegistrant())
.setAuthInfo(command.getAuthInfo())
.setFullyQualifiedDomainName(targetId)
.setNameservers(command.getNameservers())
.setNameservers(
(ImmutableSet<VKey<HostResource>>)
command.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.setStatusValues(statuses.build())
.setContacts(command.getContacts())
.addGracePeriod(GracePeriod.forBillingEvent(GracePeriodStatus.ADD, createBillingEvent))
@@ -14,7 +14,6 @@
package google.registry.flows.domain;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
@@ -23,6 +22,7 @@ import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -102,8 +102,9 @@ public final class DomainInfoFlow implements Flow {
flowCustomLogic.afterValidation(
AfterValidationParameters.newBuilder().setDomain(domain).build());
// Prefetch all referenced resources. Calling values() blocks until loading is done.
ofy().load()
.values(union(domain.getNameservers(), domain.getReferencedContacts())).values();
// We do nameservers separately since they've been converted to VKey.
tm().load(domain.getNameservers());
ofy().load().values(domain.getReferencedContacts()).values();
// Registrars can only see a few fields on unauthorized domains.
// This is a policy decision that is left up to us by the rfcs.
DomainInfoData.Builder infoBuilder = DomainInfoData.newBuilder()
@@ -15,6 +15,7 @@
package google.registry.flows.domain;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Sets.symmetricDifference;
import static com.google.common.collect.Sets.union;
import static google.registry.flows.FlowUtils.persistEntityChanges;
@@ -71,9 +72,11 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.host.HostResource;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.persistence.VKey;
import java.util.Optional;
import javax.inject.Inject;
import org.joda.time.DateTime;
@@ -243,8 +246,14 @@ public final class DomainUpdateFlow implements TransactionalFlow {
.setLastEppUpdateClientId(clientId)
.addStatusValues(add.getStatusValues())
.removeStatusValues(remove.getStatusValues())
.addNameservers(add.getNameservers())
.removeNameservers(remove.getNameservers())
.addNameservers(
add.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.removeNameservers(
remove.getNameservers().stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet()))
.addContacts(add.getContacts())
.removeContacts(remove.getContacts())
.setRegistrant(firstNonNull(change.getRegistrant(), domain.getRegistrant()))
@@ -14,6 +14,7 @@
package google.registry.flows.host;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.failfastForAsyncDelete;
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
@@ -81,6 +82,17 @@ public final class HostDeleteFlow implements TransactionalFlow {
@Inject EppResponse.Builder responseBuilder;
@Inject HostDeleteFlow() {}
/**
* Hack to convert DomainBase's nameserver VKey's to Ofy Key's.
*
* <p>We currently need this because {@code failfastForAsyncDelete()} checks to see if a name is
* in the ofy keys and is used for both nameservers and contacts. When we convert contacts to
* VKey's, we can remove this and do the conversion in {@code failfastForAsyncDelete()}.
*/
private static ImmutableSet<Key<HostResource>> getNameserverOfyKeys(DomainBase domain) {
return domain.getNameservers().stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
}
@Override
public final EppResponse run() throws EppException {
extensionManager.register(MetadataExtension.class);
@@ -88,7 +100,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
validateClientIsLoggedIn(clientId);
DateTime now = tm().getTransactionTime();
validateHostName(targetId);
failfastForAsyncDelete(targetId, now, HostResource.class, DomainBase::getNameservers);
failfastForAsyncDelete(targetId, now, HostResource.class, HostDeleteFlow::getNameserverOfyKeys);
HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now);
verifyNoDisallowedStatuses(existingHost, DISALLOWED_STATUSES);
if (!isSuperuser) {
@@ -42,8 +42,10 @@ import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.condition.IfNull;
import google.registry.flows.ResourceFlowUtils;
import google.registry.model.EppResource;
@@ -63,6 +65,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import google.registry.util.CollectionUtils;
import java.util.HashSet;
import java.util.Objects;
@@ -130,9 +133,16 @@ public class DomainBase extends EppResource
@Index
String tld;
/** References to hosts that are the nameservers for the domain. */
/**
* References to hosts that are the nameservers for the domain.
*
* <p>This is a legacy field: we have to preserve it because it is still persisted and indexed in
* the datastore, but all external references go through nsHostVKeys.
*/
@Index @ElementCollection @Transient Set<Key<HostResource>> nsHosts;
@Ignore @Transient Set<VKey<HostResource>> nsHostVKeys;
/**
* The union of the contacts visible via {@link #getContacts} and {@link #getRegistrant}.
*
@@ -240,6 +250,14 @@ public class DomainBase extends EppResource
*/
DateTime lastTransferTime;
@OnLoad
void load() {
nsHostVKeys =
nullToEmptyImmutableCopy(nsHosts).stream()
.map(hostKey -> VKey.createOfy(HostResource.class, hostKey))
.collect(toImmutableSet());
}
public ImmutableSet<String> getSubordinateHosts() {
return nullToEmptyImmutableCopy(subordinateHosts);
}
@@ -299,8 +317,10 @@ public class DomainBase extends EppResource
return idnTableName;
}
public ImmutableSet<Key<HostResource>> getNameservers() {
return nullToEmptyImmutableCopy(nsHosts);
public ImmutableSet<VKey<HostResource>> getNameservers() {
// Since nsHostVKeys gets initialized both from setNameservers() and the OnLoad method, this
// should always be valid.
return nullToEmptyImmutableCopy(nsHostVKeys);
}
public final String getCurrentSponsorClientId() {
@@ -482,7 +502,7 @@ public class DomainBase extends EppResource
public ImmutableSortedSet<String> loadNameserverFullyQualifiedHostNames() {
return ofy()
.load()
.keys(getNameservers())
.keys(getNameservers().stream().map(VKey::getOfyKey).collect(toImmutableSet()))
.values()
.stream()
.map(HostResource::getFullyQualifiedHostName)
@@ -542,6 +562,14 @@ public class DomainBase extends EppResource
Builder(DomainBase instance) {
super(instance);
// Convert nsHosts to nsHostVKeys.
if (instance.nsHosts != null) {
instance.nsHostVKeys =
instance.nsHosts.stream()
.map(key -> VKey.createOfy(HostResource.class, key))
.collect(toImmutableSet());
}
}
@Override
@@ -557,7 +585,7 @@ public class DomainBase extends EppResource
} else { // There are nameservers, so make sure INACTIVE isn't there.
removeStatusValue(StatusValue.INACTIVE);
}
checkArgumentNotNull(
emptyToNull(instance.fullyQualifiedDomainName), "Missing fullyQualifiedDomainName");
checkArgument(instance.allContacts.stream().anyMatch(IS_REGISTRANT), "Missing registrant");
@@ -591,30 +619,45 @@ public class DomainBase extends EppResource
return thisCastToDerived();
}
public Builder setNameservers(Key<HostResource> nameserver) {
getInstance().nsHosts = ImmutableSet.of(nameserver);
public Builder setNameservers(VKey<HostResource> nameserver) {
Optional<Key<HostResource>> nsKey = nameserver.maybeGetOfyKey();
if (nsKey.isPresent()) {
getInstance().nsHosts = ImmutableSet.of(nsKey.get());
} else {
getInstance().nsHosts = null;
}
getInstance().nsHostVKeys = ImmutableSet.of(nameserver);
return thisCastToDerived();
}
public Builder setNameservers(ImmutableSet<Key<HostResource>> nameservers) {
getInstance().nsHosts = forceEmptyToNull(nameservers);
public Builder setNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
// If we have all of the ofy keys, we can set nsHosts. Otherwise, make it null.
if (nameservers != null
&& nameservers.stream().allMatch(key -> key.maybeGetOfyKey().isPresent())) {
getInstance().nsHosts =
nameservers.stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
} else {
getInstance().nsHosts = null;
}
getInstance().nsHostVKeys = forceEmptyToNull(nameservers);
return thisCastToDerived();
}
public Builder addNameserver(Key<HostResource> nameserver) {
public Builder addNameserver(VKey<HostResource> nameserver) {
return addNameservers(ImmutableSet.of(nameserver));
}
public Builder addNameservers(ImmutableSet<Key<HostResource>> nameservers) {
public Builder addNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
return setNameservers(
ImmutableSet.copyOf(union(getInstance().getNameservers(), nameservers)));
}
public Builder removeNameserver(Key<HostResource> nameserver) {
public Builder removeNameserver(VKey<HostResource> nameserver) {
return removeNameservers(ImmutableSet.of(nameserver));
}
public Builder removeNameservers(ImmutableSet<Key<HostResource>> nameservers) {
public Builder removeNameservers(ImmutableSet<VKey<HostResource>> nameservers) {
return setNameservers(
ImmutableSet.copyOf(difference(getInstance().getNameservers(), nameservers)));
}
@@ -33,6 +33,7 @@ import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.ReportedOn;
import google.registry.model.domain.DomainBase;
import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey;
import java.net.InetAddress;
import java.util.Optional;
import java.util.Set;
@@ -117,6 +118,10 @@ public class HostResource extends EppResource implements ForeignKeyedEppResource
return fullyQualifiedHostName;
}
public VKey<HostResource> createKey() {
return VKey.createOfy(HostResource.class, Key.create(this));
}
@Deprecated
@Override
public HostResource cloneProjectedAtTime(DateTime now) {
@@ -18,10 +18,13 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.TransactionManager;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import org.joda.time.DateTime;
/** Datastore implementation of {@link TransactionManager}. */
@@ -128,9 +131,22 @@ public class DatastoreTransactionManager implements TransactionManager {
throw new UnsupportedOperationException("Not available in the Datastore transaction manager");
}
// TODO: add tests for these methods. They currently have some degree of test coverage because
// they are used when retrieving the nameservers which require these, as they are now loaded by
// VKey instead of by ofy Key. But ideally, there should be one set of TransactionManager
// interface tests that are applied to both the datastore and SQL implementations.
@Override
public <T> Optional<T> load(VKey<T> key) {
throw new UnsupportedOperationException("Not available in the Datastore transaction manager");
return Optional.of(getOfy().load().key(key.getOfyKey()).now());
}
@Override
public <T> ImmutableList<T> load(Iterable<VKey<T>> keys) {
Iterator<Key<T>> iter =
StreamSupport.stream(keys.spliterator(), false).map(key -> key.getOfyKey()).iterator();
// The lambda argument to keys() effectively converts Iterator -> Iterable.
return ImmutableList.copyOf(getOfy().load().keys(() -> iter).values());
}
@Override
@@ -36,6 +36,7 @@ import com.googlecode.objectify.impl.translate.opt.joda.MoneyStringTranslatorFac
import google.registry.config.RegistryEnvironment;
import google.registry.model.EntityClasses;
import google.registry.model.ImmutableObject;
import google.registry.model.host.HostResource;
import google.registry.model.translators.BloomFilterOfStringTranslatorFactory;
import google.registry.model.translators.CidrAddressBlockTranslatorFactory;
import google.registry.model.translators.CommitLogRevisionsTranslatorFactory;
@@ -45,6 +46,7 @@ import google.registry.model.translators.DurationTranslatorFactory;
import google.registry.model.translators.InetAddressTranslatorFactory;
import google.registry.model.translators.ReadableInstantUtcTranslatorFactory;
import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory;
import google.registry.model.translators.VKeyTranslatorFactory;
import java.util.concurrent.atomic.AtomicLong;
/**
@@ -117,17 +119,19 @@ public class ObjectifyService {
/** Register translators that allow less common types to be stored directly in Datastore. */
private static void registerTranslators() {
for (TranslatorFactory<?> translatorFactory : ImmutableList.of(
new BloomFilterOfStringTranslatorFactory(),
new CidrAddressBlockTranslatorFactory(),
new CommitLogRevisionsTranslatorFactory(),
new CreateAutoTimestampTranslatorFactory(),
new CurrencyUnitTranslatorFactory(),
new DurationTranslatorFactory(),
new InetAddressTranslatorFactory(),
new MoneyStringTranslatorFactory(),
new ReadableInstantUtcTranslatorFactory(),
new UpdateAutoTimestampTranslatorFactory())) {
for (TranslatorFactory<?> translatorFactory :
ImmutableList.of(
new BloomFilterOfStringTranslatorFactory(),
new CidrAddressBlockTranslatorFactory(),
new CommitLogRevisionsTranslatorFactory(),
new CreateAutoTimestampTranslatorFactory(),
new CurrencyUnitTranslatorFactory(),
new DurationTranslatorFactory(),
new InetAddressTranslatorFactory(),
new MoneyStringTranslatorFactory(),
new ReadableInstantUtcTranslatorFactory(),
new VKeyTranslatorFactory<HostResource>(HostResource.class),
new UpdateAutoTimestampTranslatorFactory())) {
factory().getTranslators().add(translatorFactory);
}
}
@@ -392,8 +392,6 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
*/
@Nullable
@Mapify(CurrencyMapper.class)
@org.hibernate.annotations.Type(
type = "google.registry.persistence.converter.CurrencyToBillingMapUserType")
Map<CurrencyUnit, BillingAccountEntry> billingAccountMap;
/** A billing account entry for this registrar, consisting of a currency and an account Id. */
@@ -19,6 +19,7 @@ import static com.google.common.base.Strings.emptyToNull;
import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.net.InternetDomainName;
import com.googlecode.objectify.annotation.Id;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.ImmutableObject;
@@ -83,6 +84,13 @@ public abstract class DomainLabelEntry<T extends Comparable<?>, D extends Domain
"Label '%s' must be in puny-coded, lower-case form",
getInstance().label);
checkArgumentNotNull(getInstance().getValue(), "Value must be specified");
// Verify that the label creates a valid SLD if we add a TLD to the end of it.
// We require that the label is not already a full domain name including a dot.
// Domain name validation is tricky, so let InternetDomainName handle it for us.
checkArgument(
InternetDomainName.from(getInstance().label + ".tld").parts().size() == 2,
"Label %s must not be a multi-level domain name",
getInstance().label);
return super.build();
}
}
@@ -41,8 +41,8 @@ import org.joda.time.Duration;
/**
* A lock on some shared resource.
*
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of
* null is used.
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of null
* is used.
*
* <p>This is the "barebone" lock implementation, that requires manual locking and unlocking. For
* safe calls that automatically lock and unlock, see LockHandler.
@@ -201,8 +201,12 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional;
if (tld == null) {
cloudSqlLockOptional = LockDao.load(resourceName);
} else {
cloudSqlLockOptional = LockDao.load(resourceName, tld);
}
LockDao.compare(Optional.ofNullable(lock), cloudSqlLockOptional);
});
} catch (Exception e) {
@@ -238,13 +242,23 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
google.registry.schema.server.Lock cloudSqlLock =
google.registry.schema.server.Lock.create(
resourceName,
Optional.ofNullable(tld).orElse("GLOBAL"),
requestStatusChecker.getLogId(),
now,
leaseLength);
google.registry.schema.server.Lock cloudSqlLock;
if (tld == null) {
cloudSqlLock =
google.registry.schema.server.Lock.createGlobal(
resourceName,
requestStatusChecker.getLogId(),
now,
leaseLength);
} else {
cloudSqlLock =
google.registry.schema.server.Lock.create(
resourceName,
tld,
requestStatusChecker.getLogId(),
now,
leaseLength);
}
LockDao.save(cloudSqlLock);
});
} catch (Exception e) {
@@ -274,8 +288,12 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional;
if (tld == null) {
cloudSqlLockOptional = LockDao.load(resourceName);
} else {
cloudSqlLockOptional = LockDao.load(resourceName, tld);
}
LockDao.compare(Optional.ofNullable(loadedLock), cloudSqlLockOptional);
});
} catch (Exception e) {
@@ -292,9 +310,13 @@ public class Lock extends ImmutableObject implements Serializable {
try {
jpaTm()
.transact(
() ->
LockDao.delete(
resourceName, Optional.ofNullable(tld).orElse("GLOBAL")));
() -> {
if (tld == null) {
LockDao.delete(resourceName);
} else {
LockDao.delete(resourceName, tld);
}
});
} catch (Exception e) {
logger.atSevere().withCause(e).log(
"Error deleting lock from Cloud SQL: %s", loadedLock);
@@ -0,0 +1,84 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.translators;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.googlecode.objectify.Key;
import google.registry.persistence.VKey;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Translator factory for VKey.
*
* <p>These get translated to a string containing the URL safe encoding of the objectify key
* followed by a (url-unsafe) ampersand delimiter and the SQL key.
*/
public class VKeyTranslatorFactory<T> extends AbstractSimpleTranslatorFactory<VKey, String> {
private final Class<T> refClass;
public VKeyTranslatorFactory(Class<T> refClass) {
super(VKey.class);
this.refClass = refClass;
}
@Override
public SimpleTranslator<VKey, String> createTranslator() {
return new SimpleTranslator<VKey, String>() {
@Override
public VKey loadValue(String datastoreValue) {
int pos = datastoreValue.indexOf('&');
Key ofyKey = null;
String sqlKey = null;
if (pos > 0) {
// We have an objectify key.
ofyKey = Key.create(datastoreValue.substring(0, pos));
}
if (pos < datastoreValue.length() - 1) {
// We have an SQL key.
sqlKey = decode(datastoreValue.substring(pos + 1));
}
return VKey.create(refClass, sqlKey, ofyKey);
}
@Override
public String saveValue(VKey key) {
return ((key.getOfyKey() == null) ? "" : key.getOfyKey().getString())
+ "&"
+ ((key.getSqlKey() == null) ? "" : encode(key.getSqlKey().toString()));
}
};
}
private static String encode(String val) {
try {
return URLEncoder.encode(val, UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private static String decode(String encoded) {
try {
return URLDecoder.decode(encoded, UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
@@ -87,78 +87,126 @@ import google.registry.tmch.TmchSmdrlAction;
@RequestScope
@Subcomponent(
modules = {
BackendModule.class,
BackupModule.class,
BatchModule.class,
BillingModule.class,
CloudDnsWriterModule.class,
CronModule.class,
DnsCountQueryCoordinatorModule.class,
DnsModule.class,
DnsUpdateConfigModule.class,
DnsUpdateWriterModule.class,
ExportRequestModule.class,
IcannReportingModule.class,
MapreduceModule.class,
RdeModule.class,
ReportingModule.class,
RequestModule.class,
SheetModule.class,
Spec11Module.class,
TmchModule.class,
VoidDnsWriterModule.class,
WhiteboxModule.class,
BackendModule.class,
BackupModule.class,
BatchModule.class,
BillingModule.class,
CloudDnsWriterModule.class,
CronModule.class,
DnsCountQueryCoordinatorModule.class,
DnsModule.class,
DnsUpdateConfigModule.class,
DnsUpdateWriterModule.class,
ExportRequestModule.class,
IcannReportingModule.class,
MapreduceModule.class,
RdeModule.class,
ReportingModule.class,
RequestModule.class,
SheetModule.class,
Spec11Module.class,
TmchModule.class,
VoidDnsWriterModule.class,
WhiteboxModule.class,
})
interface BackendRequestComponent {
BackupDatastoreAction backupDatastoreAction();
BigqueryPollJobAction bigqueryPollJobAction();
BrdaCopyAction brdaCopyAction();
CheckBackupAction checkBackupAction();
CommitLogCheckpointAction commitLogCheckpointAction();
CommitLogFanoutAction commitLogFanoutAction();
CopyDetailReportsAction copyDetailReportAction();
DeleteContactsAndHostsAction deleteContactsAndHostsAction();
DeleteLoadTestDataAction deleteLoadTestDataAction();
DeleteOldCommitLogsAction deleteOldCommitLogsAction();
DeleteProberDataAction deleteProberDataAction();
ExpandRecurringBillingEventsAction expandRecurringBillingEventsAction();
ExportCommitLogDiffAction exportCommitLogDiffAction();
ExportDomainListsAction exportDomainListsAction();
ExportPremiumTermsAction exportPremiumTermsAction();
ExportReservedTermsAction exportReservedTermsAction();
GenerateInvoicesAction generateInvoicesAction();
GenerateSpec11ReportAction generateSpec11ReportAction();
IcannReportingStagingAction icannReportingStagingAction();
IcannReportingUploadAction icannReportingUploadAction();
NordnUploadAction nordnUploadAction();
NordnVerifyAction nordnVerifyAction();
PublishDnsUpdatesAction publishDnsUpdatesAction();
PublishSpec11ReportAction publishSpec11ReportAction();
ReadDnsQueueAction readDnsQueueAction();
RdeReportAction rdeReportAction();
RdeStagingAction rdeStagingAction();
RdeUploadAction rdeUploadAction();
RdeReporter rdeReporter();
RefreshDnsAction refreshDnsAction();
RefreshDnsOnHostRenameAction refreshDnsOnHostRenameAction();
RelockDomainAction relockDomainAction();
ResaveAllEppResourcesAction resaveAllEppResourcesAction();
ResaveEntityAction resaveEntityAction();
SyncGroupMembersAction syncGroupMembersAction();
SyncRegistrarsSheetAction syncRegistrarsSheetAction();
TldFanoutAction tldFanoutAction();
TmchCrlAction tmchCrlAction();
TmchDnlAction tmchDnlAction();
TmchSmdrlAction tmchSmdrlAction();
UploadDatastoreBackupAction uploadDatastoreBackupAction();
UpdateRegistrarRdapBaseUrlsAction updateRegistrarRdapBaseUrlsAction();
UpdateSnapshotViewAction updateSnapshotViewAction();
PublishInvoicesAction uploadInvoicesAction();
@Subcomponent.Builder
abstract class Builder implements RequestComponentBuilder<BackendRequestComponent> {
@Override public abstract Builder requestModule(RequestModule requestModule);
@Override public abstract BackendRequestComponent build();
@Override
public abstract Builder requestModule(RequestModule requestModule);
@Override
public abstract BackendRequestComponent build();
}
@Module(subcomponents = BackendRequestComponent.class)
@@ -16,6 +16,7 @@ package google.registry.module.frontend;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.batch.BatchModule;
import google.registry.dns.DnsModule;
import google.registry.flows.EppTlsAction;
import google.registry.flows.FlowComponent;
@@ -38,6 +39,7 @@ import google.registry.ui.server.registrar.RegistryLockVerifyAction;
@RequestScope
@Subcomponent(
modules = {
BatchModule.class,
DnsModule.class,
EppTlsModule.class,
RegistrarConsoleModule.class,
@@ -0,0 +1,196 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Stream;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.MappedSuperclass;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
/**
* A listener class to invoke entity callbacks in cases where Hibernate doesn't invoke the callback
* as expected.
*
* <p>JPA defines a few annotations, e.g. {@link PostLoad}, that we can use for the application to
* react to certain events that occur inside the persistence mechanism. However, Hibernate only
* supports a few basic use cases, e.g. defining a {@link PostLoad} method directly in an {@link
* javax.persistence.Entity} class or in an {@link Embeddable} class. If the annotated method is
* defined in an {@link Embeddable} class that is a property of another {@link Embeddable} class, or
* it is defined in a parent class of the {@link Embeddable} class, Hibernate doesn't invoke it.
*
* <p>This listener is added in core/src/main/resources/META-INF/orm.xml as a default entity
* listener whose annotated methods will be invoked by Hibernate when corresponding events happen.
* For example, {@link EntityCallbacksListener#prePersist} will be invoked before the entity is
* persisted to the database, then it will recursively invoke any other {@link PrePersist} method
* that should be invoked but not handled by Hibernate due to the bug.
*
* @see <a
* href="https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#events-jpa-callbacks">JPA
* Callbacks</a>
* @see <a href="https://hibernate.atlassian.net/browse/HHH-13316">HHH-13316</a>
*/
public class EntityCallbacksListener {
@PrePersist
void prePersist(Object entity) {
EntityCallbackExecutor.create(PrePersist.class).execute(entity, entity.getClass());
}
@PreRemove
void preRemove(Object entity) {
EntityCallbackExecutor.create(PreRemove.class).execute(entity, entity.getClass());
}
@PostPersist
void postPersist(Object entity) {
EntityCallbackExecutor.create(PostPersist.class).execute(entity, entity.getClass());
}
@PostRemove
void postRemove(Object entity) {
EntityCallbackExecutor.create(PostRemove.class).execute(entity, entity.getClass());
}
@PreUpdate
void preUpdate(Object entity) {
EntityCallbackExecutor.create(PreUpdate.class).execute(entity, entity.getClass());
}
@PostUpdate
void postUpdate(Object entity) {
EntityCallbackExecutor.create(PostUpdate.class).execute(entity, entity.getClass());
}
@PostLoad
void postLoad(Object entity) {
EntityCallbackExecutor.create(PostLoad.class).execute(entity, entity.getClass());
}
private static class EntityCallbackExecutor {
Class<? extends Annotation> callbackType;
private EntityCallbackExecutor(Class<? extends Annotation> callbackType) {
this.callbackType = callbackType;
}
private static EntityCallbackExecutor create(Class<? extends Annotation> callbackType) {
return new EntityCallbackExecutor(callbackType);
}
/**
* Executes eligible callbacks in {@link Embedded} properties recursively.
*
* @param entity the Java object of the entity class
* @param entityType either the type of the entity or an ancestor type
*/
private void execute(Object entity, Class<?> entityType) {
Class<?> parentType = entityType.getSuperclass();
if (parentType != null && parentType.isAnnotationPresent(MappedSuperclass.class)) {
execute(entity, parentType);
}
findEmbeddedProperties(entity, entityType)
.forEach(
normalEmbedded -> {
// For each normal embedded property, we don't execute its callback method because
// it is handled by Hibernate. However, for the embedded property defined in the
// entity's parent class, we need to treat it as a nested embedded property and
// invoke its callback function.
if (entity.getClass().equals(entityType)) {
executeCallbackForNormalEmbeddedProperty(
normalEmbedded, normalEmbedded.getClass());
} else {
executeCallbackForNestedEmbeddedProperty(
normalEmbedded, normalEmbedded.getClass());
}
});
}
private void executeCallbackForNestedEmbeddedProperty(
Object nestedEmbeddedObject, Class<?> nestedEmbeddedType) {
Class<?> parentType = nestedEmbeddedType.getSuperclass();
if (parentType != null && parentType.isAnnotationPresent(MappedSuperclass.class)) {
executeCallbackForNestedEmbeddedProperty(nestedEmbeddedObject, parentType);
}
findEmbeddedProperties(nestedEmbeddedObject, nestedEmbeddedType)
.forEach(
embeddedProperty ->
executeCallbackForNestedEmbeddedProperty(
embeddedProperty, embeddedProperty.getClass()));
for (Method method : nestedEmbeddedType.getDeclaredMethods()) {
if (method.isAnnotationPresent(callbackType)) {
invokeMethod(method, nestedEmbeddedObject);
}
}
}
private void executeCallbackForNormalEmbeddedProperty(
Object normalEmbeddedObject, Class<?> normalEmbeddedType) {
Class<?> parentType = normalEmbeddedType.getSuperclass();
if (parentType != null && parentType.isAnnotationPresent(MappedSuperclass.class)) {
executeCallbackForNormalEmbeddedProperty(normalEmbeddedObject, parentType);
}
findEmbeddedProperties(normalEmbeddedObject, normalEmbeddedType)
.forEach(
embeddedProperty ->
executeCallbackForNestedEmbeddedProperty(
embeddedProperty, embeddedProperty.getClass()));
}
private Stream<Object> findEmbeddedProperties(Object object, Class<?> clazz) {
return Arrays.stream(clazz.getDeclaredFields())
.filter(
field ->
field.isAnnotationPresent(Embedded.class)
|| field.getType().isAnnotationPresent(Embeddable.class))
.map(field -> getFieldObject(field, object))
.filter(Objects::nonNull);
}
private static Object getFieldObject(Field field, Object object) {
field.setAccessible(true);
try {
return field.get(object);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private static void invokeMethod(Method method, Object object) {
method.setAccessible(true);
try {
method.invoke(object);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
@@ -14,6 +14,7 @@
package google.registry.persistence;
import google.registry.persistence.converter.StringCollectionDescriptor;
import google.registry.persistence.converter.StringMapDescriptor;
import java.sql.Types;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.PostgreSQL95Dialect;
@@ -26,7 +27,7 @@ public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
registerColumnType(Types.VARCHAR, "text");
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamptz");
registerColumnType(Types.TIMESTAMP, "timestamptz");
registerColumnType(Types.OTHER, "hstore");
registerColumnType(StringMapDescriptor.COLUMN_TYPE, StringMapDescriptor.COLUMN_NAME);
registerColumnType(
StringCollectionDescriptor.COLUMN_TYPE, StringCollectionDescriptor.COLUMN_DDL_NAME);
}
@@ -37,5 +38,7 @@ public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.contributeJavaTypeDescriptor(StringCollectionDescriptor.getInstance());
typeContributions.contributeSqlTypeDescriptor(StringCollectionDescriptor.getInstance());
typeContributions.contributeJavaTypeDescriptor(StringMapDescriptor.getInstance());
typeContributions.contributeSqlTypeDescriptor(StringMapDescriptor.getInstance());
}
}
@@ -14,7 +14,10 @@
package google.registry.persistence;
import static com.google.common.base.Preconditions.checkState;
import google.registry.model.ImmutableObject;
import java.util.Optional;
/**
* VKey is an abstraction that encapsulates the key concept.
@@ -25,12 +28,12 @@ import google.registry.model.ImmutableObject;
public class VKey<T> extends ImmutableObject {
// The primary key for the referenced entity.
private Object primaryKey;
private final Object primaryKey;
// The objectify key for the referenced entity.
private com.googlecode.objectify.Key<T> ofyKey;
private final com.googlecode.objectify.Key<T> ofyKey;
private Class<? extends T> kind;
private final Class<? extends T> kind;
private VKey(Class<? extends T> kind, com.googlecode.objectify.Key<T> ofyKey, Object primaryKey) {
this.kind = kind;
@@ -38,11 +41,6 @@ public class VKey<T> extends ImmutableObject {
this.primaryKey = primaryKey;
}
public static <T> VKey<T> create(
Class<? extends T> kind, com.googlecode.objectify.Key<T> ofyKey, Object primaryKey) {
return new VKey(kind, ofyKey, primaryKey);
}
public static <T> VKey<T> createSql(Class<? extends T> kind, Object primaryKey) {
return new VKey(kind, null, primaryKey);
}
@@ -52,17 +50,34 @@ public class VKey<T> extends ImmutableObject {
return new VKey(kind, ofyKey, null);
}
public static <T> VKey<T> create(
Class<? extends T> kind, Object primaryKey, com.googlecode.objectify.Key ofyKey) {
return new VKey(kind, ofyKey, primaryKey);
}
public Class<? extends T> getKind() {
return this.kind;
}
/** Returns the SQL primary key. */
public Object getSqlKey() {
checkState(primaryKey != null, "Attempting obtain a null SQL key.");
return this.primaryKey;
}
/** Returns the SQL primary key if it exists. */
public Optional<Object> maybeGetSqlKey() {
return Optional.ofNullable(this.primaryKey);
}
/** Returns the objectify key. */
public com.googlecode.objectify.Key<T> getOfyKey() {
checkState(ofyKey != null, "Attempting obtain a null Objectify key.");
return this.ofyKey;
}
/** Returns the objectify key if it exists. */
public Optional<com.googlecode.objectify.Key<T>> maybeGetOfyKey() {
return Optional.ofNullable(this.ofyKey);
}
}
@@ -0,0 +1,43 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static google.registry.model.registrar.Registrar.BillingAccountEntry;
import com.google.common.collect.Maps;
import java.util.Map;
import javax.persistence.Converter;
import org.joda.money.CurrencyUnit;
/** JPA converter for storing/retrieving {@link Map <CurrencyUnit, BillingAccountEntry>} objects. */
@Converter(autoApply = true)
public class CurrencyToBillingConverter
extends StringMapConverterBase<CurrencyUnit, BillingAccountEntry> {
@Override
Map.Entry<String, String> convertToDatabaseMapEntry(
Map.Entry<CurrencyUnit, BillingAccountEntry> entry) {
return Maps.immutableEntry(entry.getKey().getCode(), entry.getValue().getAccountId());
}
@Override
Map.Entry<CurrencyUnit, BillingAccountEntry> convertToEntityMapEntry(
Map.Entry<String, String> entry) {
CurrencyUnit currencyUnit = CurrencyUnit.of(entry.getKey());
BillingAccountEntry billingAccountEntry =
new BillingAccountEntry(currencyUnit, entry.getValue());
return Maps.immutableEntry(currencyUnit, billingAccountEntry);
}
}
@@ -1,54 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import google.registry.model.registrar.Registrar.BillingAccountEntry;
import java.util.Map;
import org.hibernate.usertype.UserType;
import org.joda.money.CurrencyUnit;
/**
* A custom {@link UserType} for storing/retrieving {@link Map<CurrencyUnit, BillingAccountEntry>}
* objects.
*/
public class CurrencyToBillingMapUserType extends MapUserType {
@Override
public Object toEntityTypeMap(Map<String, String> map) {
return map == null
? null
: map.entrySet().stream()
.collect(
toImmutableMap(
entry -> CurrencyUnit.of(entry.getKey()),
entry ->
new BillingAccountEntry(
CurrencyUnit.of(entry.getKey()), entry.getValue())));
}
@Override
public Map<String, String> toDbSupportedMap(Object map) {
return map == null
? null
: ((Map<CurrencyUnit, BillingAccountEntry>) map)
.entrySet().stream()
.collect(
toImmutableMap(
entry -> entry.getKey().getCode(),
entry -> entry.getValue().getAccountId()));
}
}
@@ -1,73 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
/**
* A custom {@link UserType} used to convert a Java {@link Map<String, String>} to/from PostgreSQL
* hstore type. Per this <a href="https://www.postgresql.org/docs/current/hstore.html">doc</a>, as
* hstore keys and values are simply text strings, the type of key and value in the Java map has to
* be {@link String} as well.
*/
public class MapUserType extends MutableUserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.OTHER};
}
@Override
public Class returnedClass() {
return Map.class;
}
@Override
public Object nullSafeGet(
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
return toEntityTypeMap((Map<String, String>) rs.getObject(names[0]));
}
@Override
public void nullSafeSet(
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
st.setObject(index, toDbSupportedMap(value));
}
/**
* Subclass can override this method to convert the {@link Map<String, String>} to a {@link Map}
* of specific type defined in the entity class.
*/
public Object toEntityTypeMap(Map<String, String> map) {
return map;
}
/**
* Subclass can override this method to convert the {@link Map} of specific type to a {@link
* Map<String, String>} that can be stored in the hstore type column.
*/
public Map<String, String> toDbSupportedMap(Object map) {
return (Map<String, String>) map;
}
}
@@ -1,63 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import java.io.Serializable;
import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
* An abstract class represents a mutable Hibernate user type which implements related methods
* defined in {@link UserType}.
*/
public abstract class MutableUserType implements UserType {
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x == null ? 0 : x.hashCode();
}
// TODO(b/147489651): Investigate how to properly implement the below methods.
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
@@ -0,0 +1,52 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import google.registry.persistence.converter.StringMapDescriptor.StringMap;
import java.util.Map;
import javax.persistence.AttributeConverter;
/**
* Base JPA converter for {@link Map} objects that are stored in a column with data type of hstore
* in the database.
*/
public abstract class StringMapConverterBase<K, V>
implements AttributeConverter<Map<K, V>, StringMap> {
abstract Map.Entry<String, String> convertToDatabaseMapEntry(Map.Entry<K, V> entry);
abstract Map.Entry<K, V> convertToEntityMapEntry(Map.Entry<String, String> entry);
@Override
public StringMap convertToDatabaseColumn(Map<K, V> attribute) {
return attribute == null
? null
: StringMap.create(
attribute.entrySet().stream()
.map(this::convertToDatabaseMapEntry)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
@Override
public Map<K, V> convertToEntityAttribute(StringMap dbData) {
return dbData == null
? null
: dbData.getMap().entrySet().stream()
.map(this::convertToEntityMapEntry)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
}
@@ -0,0 +1,177 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static google.registry.persistence.converter.StringMapDescriptor.StringMap;
import com.google.common.collect.ImmutableMap;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.BasicBinder;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* The {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor} for {@link StringMap}.
*
* <p>A {@link StringMap} object is a simple wrapper for a {@link Map <String, String>} which can be
* stored in a column with data type of hstore in the database. The {@link JavaTypeDescriptor} and
* {@link SqlTypeDescriptor} is used by JPA/Hibernate to map between the map and hstore which is the
* actual type that JDBC uses to read from and write to the database.
*
* @see <a
* href="https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-jpa-convert">JPA
* 2.1 AttributeConverters</a>
* @see <a href="https://www.postgresql.org/docs/current/hstore.html">hstore</a>
*/
public class StringMapDescriptor extends AbstractTypeDescriptor<StringMap>
implements SqlTypeDescriptor {
public static final int COLUMN_TYPE = Types.OTHER;
public static final String COLUMN_NAME = "hstore";
private static final StringMapDescriptor INSTANCE = new StringMapDescriptor();
protected StringMapDescriptor() {
super(StringMap.class);
}
public static StringMapDescriptor getInstance() {
return INSTANCE;
}
@Override
public StringMap fromString(String string) {
throw new UnsupportedOperationException(
"Constructing StringMapDescriptor from string is not allowed");
}
@Override
public <X> X unwrap(StringMap value, Class<X> type, WrapperOptions options) {
if (value == null) {
return null;
}
if (Map.class.isAssignableFrom(type)) {
return (X) value.getMap();
}
throw unknownUnwrap(type);
}
@Override
public <X> StringMap wrap(X value, WrapperOptions options) {
if (value == null) {
return null;
}
if (value instanceof Map) {
return StringMap.create((Map<String, String>) value);
}
throw unknownWrap(value.getClass());
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
return this;
}
@Override
public int getSqlType() {
return COLUMN_TYPE;
}
@Override
public boolean canBeRemapped() {
return false;
}
@Override
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder<X>(javaTypeDescriptor, this) {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
st.setObject(index, getStringMap(value));
}
@Override
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
throws SQLException {
st.setObject(name, getStringMap(value));
}
private Map<String, String> getStringMap(X value) {
if (value == null) {
return null;
}
if (value instanceof StringMap) {
return ((StringMap) value).getMap();
} else {
throw new UnsupportedOperationException(
String.format(
"Binding type %s is not supported by StringMapDescriptor",
value.getClass().getName()));
}
}
};
}
@Override
public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicExtractor<X>(javaTypeDescriptor, this) {
@Override
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(rs.getObject(name), options);
}
@Override
protected X doExtract(CallableStatement statement, int index, WrapperOptions options)
throws SQLException {
return javaTypeDescriptor.wrap(statement.getObject(index), options);
}
@Override
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
throws SQLException {
return javaTypeDescriptor.wrap(statement.getObject(name), options);
}
};
}
/** A simple wrapper class for {@link Map<String, String>}. */
public static class StringMap {
private Map<String, String> map;
private StringMap(Map<String, String> map) {
this.map = map;
}
/** Constructs an instance of {@link StringMap} from the given map. */
public static StringMap create(Map<String, String> map) {
return new StringMap(ImmutableMap.copyOf(map));
}
/** Returns the underlying {@link Map<String, String>} object. */
public Map<String, String> getMap() {
return map;
}
}
}
@@ -0,0 +1,41 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import google.registry.persistence.VKey;
import javax.annotation.Nullable;
import javax.persistence.AttributeConverter;
/**
* Converts VKey to a string column.
*/
public abstract class VKeyConverter<T> implements AttributeConverter<VKey<T>, String> {
@Override
@Nullable
public String convertToDatabaseColumn(@Nullable VKey<T> attribute) {
return attribute == null ? null : (String) attribute.getSqlKey();
}
@Override
@Nullable
public VKey<T> convertToEntityAttribute(@Nullable String dbData) {
return dbData == null ? null : VKey.createSql(getAttributeClass(), dbData);
}
/**
* Returns the class of the attribute.
*/
protected abstract Class<T> getAttributeClass();
}
@@ -15,6 +15,7 @@
package google.registry.persistence.transaction;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static java.util.stream.Collectors.joining;
@@ -26,8 +27,10 @@ import com.google.common.flogger.FluentLogger;
import google.registry.persistence.VKey;
import google.registry.util.Clock;
import java.lang.reflect.Field;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
@@ -235,6 +238,23 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
return Optional.ofNullable(getEntityManager().find(key.getKind(), key.getSqlKey()));
}
@Override
public <T> ImmutableList<T> load(Iterable<VKey<T>> keys) {
checkArgumentNotNull(keys, "keys must be specified");
assertInTransaction();
return StreamSupport.stream(keys.spliterator(), false)
.map(
key -> {
T entity = getEntityManager().find(key.getKind(), key.getSqlKey());
if (entity == null) {
throw new NoSuchElementException(
key.getKind().getName() + " with key " + key.getSqlKey() + " not found.");
}
return entity;
})
.collect(toImmutableList());
}
@Override
public <T> ImmutableList<T> loadAll(Class<T> clazz) {
checkArgumentNotNull(clazz, "clazz must be specified");
@@ -110,6 +110,13 @@ public interface TransactionManager {
/** Loads the entity by its id, returns empty if the entity doesn't exist. */
<T> Optional<T> load(VKey<T> key);
/**
* Leads the set of entities by their key id.
*
* @throws NoSuchElementException if any of the keys are not found.
*/
<T> ImmutableList<T> load(Iterable<VKey<T>> keys);
/** Loads all entities of the given type, returns empty if there is no such entity. */
<T> ImmutableList<T> loadAll(Class<T> clazz);
@@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static google.registry.model.EppResourceUtils.isLinked;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.rdap.RdapIcannStandardInformation.CONTACT_REDACTED_VALUE;
import static google.registry.util.CollectionUtils.union;
@@ -341,8 +342,8 @@ public class RdapJsonFormatter {
// Kick off the database loads of the nameservers that we will need, so it can load
// asynchronously while we load and process the contacts.
Map<Key<HostResource>, HostResource> loadedHosts =
ofy().load().keys(domainBase.getNameservers());
ImmutableSet<HostResource> loadedHosts =
ImmutableSet.copyOf(tm().load(domainBase.getNameservers()));
// Load the registrant and other contacts and add them to the data.
Map<Key<ContactResource>, ContactResource> loadedContacts =
ofy().load().keys(domainBase.getReferencedContacts());
@@ -378,8 +379,7 @@ public class RdapJsonFormatter {
}
// Add the nameservers to the data; the load was kicked off above for efficiency.
// RDAP Response Profile 2.9: we MUST have the nameservers
for (HostResource hostResource :
HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
for (HostResource hostResource : HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts)) {
builder.nameserversBuilder().add(createRdapNameserver(hostResource, OutputDataType.INTERNAL));
}
@@ -14,6 +14,7 @@
package google.registry.schema.tld;
import google.registry.model.ImmutableObject;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
@@ -26,7 +27,7 @@ import javax.persistence.Id;
* <p>These are not persisted directly, but rather, using {@link PremiumList#getLabelsToPrices()}.
*/
@Entity
public class PremiumEntry implements Serializable {
public class PremiumEntry extends ImmutableObject implements Serializable {
@Id
@Column(nullable = false)
@@ -14,6 +14,8 @@
package google.registry.tools;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.Multimap;
@@ -39,6 +41,11 @@ final class CheckDomainCommand extends NonMutatingEppToolCommand {
required = true)
private List<String> mainParameters;
@Parameter(
names = {"-t", "--token"},
description = "Allocation token to use in the command, if desired")
private String allocationToken;
@Inject
@Config("registryAdminClientId")
String registryAdminClientId;
@@ -53,7 +60,11 @@ final class CheckDomainCommand extends NonMutatingEppToolCommand {
Multimap<String, String> domainNameMap = validateAndGroupDomainNamesByTld(mainParameters);
for (Collection<String> values : domainNameMap.asMap().values()) {
setSoyTemplate(DomainCheckSoyInfo.getInstance(), DomainCheckSoyInfo.DOMAINCHECK);
addSoyRecord(clientId, new SoyMapData("domainNames", values));
SoyMapData soyMapData = new SoyMapData("domainNames", values);
if (!isNullOrEmpty(allocationToken)) {
soyMapData.put("allocationToken", allocationToken);
}
addSoyRecord(clientId, soyMapData);
}
}
}
@@ -18,9 +18,20 @@ 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;
/** Compare two database backups. */
/**
* Compares two Datastore backups in V3 format on local file system. This is for use in tests and
* experiments with small data sizes.
*
* <p>This utility only supports the current Datastore backup format (version 3). A backup is a
* two-level directory hierarchy with data files in level-db format (output-*) and Datastore
* metadata files (*.export_metadata).
*/
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);
public static void main(String[] args) {
if (args.length != 2) {
@@ -29,9 +40,13 @@ class CompareDbBackups {
}
ImmutableSet<ComparableEntity> entities1 =
new RecordAccumulator().readDirectory(new File(args[0])).getComparableEntitySet();
new RecordAccumulator()
.readDirectory(new File(args[0]), DATA_FILE_MATCHER)
.getComparableEntitySet();
ImmutableSet<ComparableEntity> entities2 =
new RecordAccumulator().readDirectory(new File(args[1])).getComparableEntitySet();
new RecordAccumulator()
.readDirectory(new File(args[1]), DATA_FILE_MATCHER)
.getComparableEntitySet();
// Calculate the entities added and removed.
SetView<ComparableEntity> added = Sets.difference(entities2, entities1);
@@ -54,6 +69,10 @@ class CompareDbBackups {
System.out.println(entity);
}
}
if (added.isEmpty() && removed.isEmpty()) {
System.out.printf("\nBoth sets have the same %d entities.\n", entities1.size());
}
}
/** Print out multi-line text in a pretty ASCII header frame. */
@@ -24,6 +24,7 @@ import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STAT
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.googlecode.objectify.Key;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainBase;
@@ -37,6 +38,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Utility functions for validating and applying {@link RegistryLock}s.
@@ -50,10 +52,14 @@ public final class DomainLockUtils {
private static final int VERIFICATION_CODE_LENGTH = 32;
private final StringGenerator stringGenerator;
private final AsyncTaskEnqueuer asyncTaskEnqueuer;
@Inject
public DomainLockUtils(@Named("base58StringGenerator") StringGenerator stringGenerator) {
public DomainLockUtils(
@Named("base58StringGenerator") StringGenerator stringGenerator,
AsyncTaskEnqueuer asyncTaskEnqueuer) {
this.stringGenerator = stringGenerator;
this.asyncTaskEnqueuer = asyncTaskEnqueuer;
}
/**
@@ -76,12 +82,12 @@ public final class DomainLockUtils {
* <p>The unlock will not be applied until {@link #verifyAndApplyUnlock} is called.
*/
public RegistryLock saveNewRegistryUnlockRequest(
String domainName, String registrarId, boolean isAdmin) {
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
return jpaTm()
.transact(
() ->
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin).build()));
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration).build()));
}
/** Verifies and applies the lock request previously requested by a user. */
@@ -114,35 +120,41 @@ public final class DomainLockUtils {
/** Verifies and applies the unlock request previously requested by a user. */
public RegistryLock verifyAndApplyUnlock(String verificationCode, boolean isAdmin) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock lock = getByVerificationCode(verificationCode);
checkArgument(
!lock.getUnlockCompletionTimestamp().isPresent(),
"Domain %s is already unlocked",
lock.getDomainName());
RegistryLock lock =
jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock previousLock = getByVerificationCode(verificationCode);
checkArgument(
!previousLock.getUnlockCompletionTimestamp().isPresent(),
"Domain %s is already unlocked",
previousLock.getDomainName());
checkArgument(
!lock.isUnlockRequestExpired(now),
"The pending unlock has expired; please try again");
checkArgument(
!previousLock.isUnlockRequestExpired(now),
"The pending unlock has expired; please try again");
checkArgument(
isAdmin || !lock.isSuperuser(), "Non-admin user cannot complete admin unlock");
checkArgument(
isAdmin || !previousLock.isSuperuser(),
"Non-admin user cannot complete admin unlock");
RegistryLock newLock =
RegistryLockDao.save(lock.asBuilder().setUnlockCompletionTimestamp(now).build());
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
return newLock;
});
RegistryLock newLock =
RegistryLockDao.save(
previousLock.asBuilder().setUnlockCompletionTimestamp(now).build());
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
return newLock;
});
// Submit relock outside of the transaction to make sure that it fully succeeded
submitRelockIfNecessary(lock);
return lock;
}
/**
* Creates and applies a lock in one step -- this should only be used for admin actions, e.g.
* Nomulus tool commands or relocks.
* Creates and applies a lock in one step.
*
* <p>Note: in the case of relocks, isAdmin is determined by the previous lock.
* <p>This should only be used for admin actions, e.g. Nomulus tool commands or relocks.
* Note: in the case of relocks, isAdmin is determined by the previous lock.
*/
public RegistryLock administrativelyApplyLock(
String domainName, String registrarId, @Nullable String registrarPocId, boolean isAdmin) {
@@ -162,23 +174,34 @@ public final class DomainLockUtils {
}
/**
* Creates and applies an unlock in one step -- this should only be used for admin actions, e.g.
* Nomulus tool commands.
* Creates and applies an unlock in one step.
*
* <p>This should only be used for admin actions, e.g. Nomulus tool commands.
*/
public RegistryLock administrativelyApplyUnlock(
String domainName, String registrarId, boolean isAdmin) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
return result;
});
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
RegistryLock lock =
jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
return result;
});
// Submit relock outside of the transaction to make sure that it fully succeeded
submitRelockIfNecessary(lock);
return lock;
}
private void submitRelockIfNecessary(RegistryLock lock) {
if (lock.getRelockDuration().isPresent()) {
asyncTaskEnqueuer.enqueueDomainRelock(lock);
}
}
private void setAsRelock(RegistryLock newLock) {
@@ -217,7 +240,7 @@ public final class DomainLockUtils {
}
private RegistryLock.Builder createUnlockBuilder(
String domainName, String registrarId, boolean isAdmin) {
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
DateTime now = jpaTm().getTransactionTime();
DomainBase domainBase = getDomain(domainName, now);
Optional<RegistryLock> lockOptional =
@@ -258,6 +281,7 @@ public final class DomainLockUtils {
!lock.isSuperuser(), "Non-admin user cannot unlock admin-locked domain %s", domainName);
newLockBuilder = lock.asBuilder();
}
relockDuration.ifPresent(newLockBuilder::setRelockDuration);
return newLockBuilder
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
.isSuperuser(isAdmin)
@@ -20,17 +20,18 @@ import com.google.storage.onestore.v3.OnestoreEntity.EntityProto;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.function.Predicate;
/** Utility class that accumulates Entity records from level db files. */
/** Accumulates Entity records from level db files under a directory hierarchy. */
class RecordAccumulator {
private final LevelDbLogReader reader = new LevelDbLogReader();
/** Recursively reads all records in the directory. */
public final RecordAccumulator readDirectory(File dir) {
public final RecordAccumulator readDirectory(File dir, Predicate<File> fileMatcher) {
for (File child : dir.listFiles()) {
if (child.isDirectory()) {
readDirectory(child);
} else if (child.isFile()) {
readDirectory(child, fileMatcher);
} else if (fileMatcher.test(child)) {
try {
reader.readFrom(new FileInputStream(child));
} catch (IOException e) {
@@ -16,6 +16,7 @@ package google.registry.tools;
import dagger.BindsInstance;
import dagger.Component;
import google.registry.batch.BatchModule;
import google.registry.bigquery.BigqueryModule;
import google.registry.config.CredentialModule.LocalCredentialJson;
import google.registry.config.RegistryConfig.ConfigModule;
@@ -54,6 +55,7 @@ import javax.inject.Singleton;
modules = {
AppEngineAdminApiModule.class,
AuthModule.class,
BatchModule.class,
BigqueryModule.class,
ConfigModule.class,
CloudDnsWriterModule.class,
@@ -19,7 +19,7 @@ import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.Sets.difference;
import static google.registry.model.EppResourceUtils.checkResourcesExist;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
import static org.joda.time.DateTimeZone.UTC;
@@ -149,7 +149,7 @@ final class UniformRapidSuspensionCommand extends MutatingEppToolCommand {
private ImmutableSortedSet<String> getExistingNameservers(DomainBase domain) {
ImmutableSortedSet.Builder<String> nameservers = ImmutableSortedSet.naturalOrder();
for (HostResource host : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource host : tm().load(domain.getNameservers())) {
nameservers.add(host.getForeignKey());
}
return nameservers.build();
@@ -22,6 +22,7 @@ import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.StatusValue;
import java.util.Optional;
import org.joda.time.DateTime;
/**
@@ -53,6 +54,6 @@ public class UnlockDomainCommand extends LockOrUnlockDomainCommand {
@Override
protected void createAndApplyRequest(String domain) {
domainLockUtils.administrativelyApplyUnlock(domain, clientId, true);
domainLockUtils.administrativelyApplyUnlock(domain, clientId, true, Optional.empty());
}
}
@@ -2,4 +2,6 @@ handlers = java.util.logging.ConsoleHandler
.level = INFO
com.google.wrappers.base.GoogleInit.level = WARNING
com.google.monitoring.metrics.MetricRegistryImpl.level = WARNING
com.google.cloud.sql.level = WARNING
com.zaxxer.hikari.level = WARNING
org.hibernate.level = WARNING
@@ -20,7 +20,7 @@ import static com.google.common.collect.Iterators.filter;
import static com.google.common.io.BaseEncoding.base16;
import static google.registry.mapreduce.inputs.EppResourceInputs.createEntityInput;
import static google.registry.model.EppResourceUtils.loadAtPointInTime;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.POST;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.joda.time.DateTimeZone.UTC;
@@ -214,7 +214,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
private void emitForSubordinateHosts(DomainBase domain) {
ImmutableSet<String> subordinateHosts = domain.getSubordinateHosts();
if (!subordinateHosts.isEmpty()) {
for (HostResource unprojectedHost : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource unprojectedHost : tm().load(domain.getNameservers())) {
HostResource host = loadAtPointInTime(unprojectedHost, exportTime).now();
// A null means the host was deleted (or not created) at this time.
if ((host != null) && subordinateHosts.contains(host.getFullyQualifiedHostName())) {
@@ -283,7 +283,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
Duration dnsDefaultDsTtl) {
StringBuilder result = new StringBuilder();
String domainLabel = stripTld(domain.getFullyQualifiedDomainName(), domain.getTld());
for (HostResource nameserver : ofy().load().keys(domain.getNameservers()).values()) {
for (HostResource nameserver : tm().load(domain.getNameservers())) {
result.append(String.format(
NS_FORMAT,
domainLabel,
@@ -29,6 +29,7 @@ import com.google.re2j.Pattern;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.ui.forms.FormException;
import google.registry.ui.forms.FormField;
import google.registry.ui.forms.FormFieldException;
import google.registry.ui.forms.FormFields;
@@ -405,6 +406,10 @@ public final class RegistrarFormFields {
.ifPresent(
password -> {
if (!Strings.isNullOrEmpty(password)) {
if (password.length() < 8) {
throw new FormException(
"Registry lock password must be at least 8 characters long");
}
builder.setRegistryLockPassword(password);
}
});
@@ -43,6 +43,7 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
import google.registry.schema.domain.RegistryLock;
import google.registry.security.JsonResponseHelper;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import org.joda.time.DateTime;
@@ -119,7 +120,8 @@ public final class RegistryLockGetAction implements JsonGetAction {
static Optional<RegistrarContact> getContactMatchingLogin(User user, Registrar registrar) {
ImmutableList<RegistrarContact> matchingContacts =
registrar.getContacts().stream()
.filter(contact -> contact.getGaeUserId().equals(user.getUserId()))
.filter(contact -> contact.getGaeUserId() != null)
.filter(contact -> Objects.equals(contact.getGaeUserId(), user.getUserId()))
.collect(toImmutableList());
if (matchingContacts.size() > 1) {
ImmutableList<String> matchingEmails =
@@ -56,6 +56,7 @@ import javax.inject.Inject;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.apache.http.client.utils.URIBuilder;
import org.joda.time.Duration;
/**
* UI action that allows for creating registry locks. Locks / unlocks must be verified separately
@@ -141,7 +142,8 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
: domainLockUtils.saveNewRegistryUnlockRequest(
postInput.fullyQualifiedDomainName,
postInput.clientId,
registrarAccessor.isAdmin());
registrarAccessor.isAdmin(),
Optional.ofNullable(postInput.relockDurationMillis).map(Duration::new));
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
});
String action = postInput.isLock ? "lock" : "unlock";
@@ -218,5 +220,6 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
private String fullyQualifiedDomainName;
private Boolean isLock;
private String password;
private Long relockDurationMillis;
}
}
@@ -45,3 +45,41 @@
.lock-confirm-modal button {
margin-left: 10px
}
/** Following section taken from https://loading.io/css, under CC0 licensing. */
.lds-ring {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 64px;
height: 64px;
margin: 8px;
border: 8px solid #000000;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #000000 transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/** End of material taken from https://loading.io/css. */
@@ -121,7 +121,10 @@ registry.registrar.RegistryLock.prototype.showModal_ = function(targetElement, d
if (domain == null) {
goog.dom.getRequiredElement('domain-lock-input-value').focus();
} else {
goog.dom.getRequiredElement('domain-lock-password').focus();
var passwordElem = goog.dom.getElement('domain-lock-password');
if (passwordElem != null) {
passwordElem.focus();
}
}
// delete the modal when the user clicks the cancel button
goog.events.listen(
@@ -162,7 +165,9 @@ registry.registrar.RegistryLock.prototype.showModal_ = function(targetElement, d
*/
registry.registrar.RegistryLock.prototype.lockOrUnlockDomain_ = function(isLock, e) {
var domain = goog.dom.getRequiredElement('domain-lock-input-value').value;
var password = goog.dom.getRequiredElement('domain-lock-password').value;
var passwordElem = goog.dom.getElement('domain-lock-password');
var password = passwordElem == null ? null : passwordElem.value;
var relockDuration = this.getRelockDurationFromModal_()
goog.net.XhrIo.send('/registry-lock-post',
e => this.fillLocksPage_(e),
'POST',
@@ -170,13 +175,30 @@ registry.registrar.RegistryLock.prototype.lockOrUnlockDomain_ = function(isLock,
'clientId': this.clientId,
'fullyQualifiedDomainName': domain,
'isLock': isLock,
'password': password
'password': password,
'relockDurationMillis': relockDuration
}), {
'X-CSRF-Token': this.xsrfToken,
'Content-Type': 'application/json; charset=UTF-8'
});
}
/**
* Returns the duration after which we will re-lock a locked domain. Will return null if we
* are locking a domain, or if the user selects the "Never" option
* @private
*/
registry.registrar.RegistryLock.prototype.getRelockDurationFromModal_ = function() {
var inputElements = goog.dom.getElementsByTagNameAndClass("input", "relock-duration-input");
for (var i = 0; i < inputElements.length; i++) {
var elem = inputElements[i];
if (elem.checked && elem.value !== "0") {
return elem.value;
}
}
return null;
}
/**
* Click handler for unlocking domains (button click).
* @private
+8 -6
View File
@@ -4,15 +4,17 @@
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<embeddable class="org.joda.money.Money" access="FIELD">
<attributes>
<embedded name="money" access="FIELD"/>
</attributes>
</embeddable>
<embeddable class="org.joda.money.Money" access="FIELD" />
<embeddable class="org.joda.money.BigMoney" access="FIELD">
<attributes>
<basic name="amount" access="FIELD"/>
<basic name="currency" access="FIELD"/>
</attributes>
</embeddable>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="google.registry.persistence.EntityCallbacksListener" />
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
@@ -36,6 +36,7 @@
<class>google.registry.persistence.converter.BloomFilterConverter</class>
<class>google.registry.persistence.converter.CidrAddressBlockListConverter</class>
<class>google.registry.persistence.converter.CreateAutoTimestampConverter</class>
<class>google.registry.persistence.converter.CurrencyToBillingConverter</class>
<class>google.registry.persistence.converter.CurrencyUnitConverter</class>
<class>google.registry.persistence.converter.DateTimeConverter</class>
<class>google.registry.persistence.converter.DurationConverter</class>
@@ -19,6 +19,7 @@
*/
{template .domaincheck stricthtml="false"}
{@param domainNames: list<string>}
{@param? allocationToken: string|null}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
@@ -39,6 +40,12 @@
</fee:domain>
{/for}
</fee:check>
{if isNonnull($allocationToken)}
<allocationToken:allocationToken
xmlns:allocationToken="urn:ietf:params:xml:ns:allocationToken-1.0">
{$allocationToken}
</allocationToken:allocationToken>
{/if}
</extension>
<clTRID>RegistryTool</clTRID>
</command>
@@ -89,7 +89,7 @@
disabled
{/if}
{if $isPassword}
type="password"
type="password" minlength="8"
{/if}>
</td>
</tr>
@@ -18,7 +18,15 @@
{template .settings}
<h1>Registry lock</h1>
<br>
<div id="locks-content"></div>
<div id="locks-content">
// CSS-ified loading spinner
<div class="{css('lds-ring')}">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
{/template}
{template .locksContent}
@@ -110,8 +118,9 @@
{@param? domain: string|null}
<div id="lock-confirm-modal" class="{css('lock-confirm-modal')}">
<div class="modal-content">
<p>Are you sure you want to {if not $isLock}un{/if}lock the domain {$domain}? We will send
an email to the email address on file to confirm the {if not $isLock}un{/if}lock.</p>
<p>Are you sure you want to {if $isLock}lock a domain{else}unlock the domain {$domain}{/if}?
We will send an email to the email address on file to confirm the {if not $isLock}un{/if}
lock.</p>
<label for="domain-to-lock">Domain: </label>
<input id="domain-lock-input-value"
{if isNonnull($domain)}
@@ -123,6 +132,24 @@
<input type="password" id="domain-lock-password">
<br>
{/if}
{if not $isLock}
<div>
<br>
<p>Automatically re-lock the domain after:</p>
<input type="radio" name="relock-duration" id="one-hour-duration" value="3600000"
class="relock-duration-input">
<label for="one-hour-duration">1 hour</label><br>
<input type="radio" name="relock-duration" id="six-hour-duration" value="21600000"
class="relock-duration-input" checked>
<label for="six-hour-duration">6 hours</label><br>
<input type="radio" name="relock-duration" id="twenty-four-hour-duration" value="86400000"
class="relock-duration-input">
<label for="twenty-four-hour-duration">24 hours</label><br>
<input type="radio" name="relock-duration" id="never-relock-duration" value="0"
class="relock-duration-input">
<label for="never-relock-duration">Never</label><br>
</div>
{/if}
<div id="modal-error-message" hidden class="{css('kd-errormessage')}"></div>
<div class="{css('buttons-div')}">
<button id="domain-lock-cancel" class="{css('kd-button')}">Cancel</button>
@@ -36,6 +36,9 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
// The mount point in the container.
private static final String CONTAINER_MOUNT_POINT = "/tmp/pg_dump.out";
// Temporary workaround to fix permission issues on certain Linux distro (e. g. Arch Linux).
private static final String CONTAINER_MOUNT_POINT_TMP = "/tmp/pg_dump.tmp";
@Parameter(
names = {"--output", "-o"},
description = "Output file",
@@ -61,6 +64,11 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
result = postgresContainer.execInContainer(
"cp", CONTAINER_MOUNT_POINT_TMP, CONTAINER_MOUNT_POINT);
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
}
@Override
@@ -79,7 +87,7 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
"-U",
username,
"-f",
CONTAINER_MOUNT_POINT,
CONTAINER_MOUNT_POINT_TMP,
"--schema-only",
"--no-owner",
"--no-privileges",
@@ -15,6 +15,7 @@
package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
@@ -23,18 +24,21 @@ import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.testing.TestLogHandlerUtils.assertLogMessage;
import static org.joda.time.Duration.standardDays;
import static org.joda.time.Duration.standardHours;
import static org.joda.time.Duration.standardSeconds;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.flogger.LoggerConfig;
import com.googlecode.objectify.Key;
import google.registry.model.contact.ContactResource;
import google.registry.schema.domain.RegistryLock;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
@@ -46,6 +50,7 @@ import google.registry.util.CapturingLogHandler;
import google.registry.util.Retrier;
import java.util.logging.Level;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -77,14 +82,18 @@ public class AsyncTaskEnqueuerTest extends ShardableTestCase {
public void setUp() {
LoggerConfig.getConfig(AsyncTaskEnqueuer.class).addHandler(logHandler);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
standardSeconds(90),
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
asyncTaskEnqueuer = createForTesting(appEngineServiceUtils, clock, standardSeconds(90));
}
public static AsyncTaskEnqueuer createForTesting(
AppEngineServiceUtils appEngineServiceUtils, FakeClock clock, Duration asyncDeleteDelay) {
return new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
asyncDeleteDelay,
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
}
@Test
@@ -137,4 +146,56 @@ public class AsyncTaskEnqueuerTest extends ShardableTestCase {
assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS);
assertLogMessage(logHandler, Level.INFO, "Ignoring async re-save");
}
@Test
public void testEnqueueRelock() {
RegistryLock lock =
saveRegistryLock(
new RegistryLock.Builder()
.setLockCompletionTimestamp(clock.nowUtc())
.setUnlockRequestTimestamp(clock.nowUtc())
.setUnlockCompletionTimestamp(clock.nowUtc())
.isSuperuser(false)
.setDomainName("example.tld")
.setRepoId("repoId")
.setRelockDuration(standardHours(6))
.setRegistrarId("TheRegistrar")
.setRegistrarPocId("someone@example.com")
.setVerificationCode("hi")
.build());
asyncTaskEnqueuer.enqueueDomainRelock(lock);
assertTasksEnqueued(
QUEUE_ASYNC_ACTIONS,
new TaskMatcher()
.url(RelockDomainAction.PATH)
.method("POST")
.param(
RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM,
String.valueOf(lock.getRevisionId()))
.etaDelta(
standardHours(6).minus(standardSeconds(30)),
standardHours(6).plus(standardSeconds(30))));
}
@Test
public void testFailure_enqueueRelock_noDuration() {
RegistryLock lockWithoutDuration =
saveRegistryLock(
new RegistryLock.Builder()
.isSuperuser(false)
.setDomainName("example.tld")
.setRepoId("repoId")
.setRegistrarId("TheRegistrar")
.setRegistrarPocId("someone@example.com")
.setVerificationCode("hi")
.build());
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> asyncTaskEnqueuer.enqueueDomainRelock(lockWithoutDuration)))
.hasMessageThat()
.isEqualTo(
String.format(
"Lock with ID %s not configured for relock", lockWithoutDuration.getRevisionId()));
}
}
@@ -18,9 +18,7 @@ import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.batch.AsyncTaskMetrics.OperationResult.STALE;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
@@ -151,13 +149,8 @@ public class DeleteContactsAndHostsActionTest
public void setup() {
inject.setStaticField(Ofy.class, "clock", clock);
enqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
mock(AppEngineServiceUtils.class),
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO);
AsyncTaskMetrics asyncTaskMetricsMock = mock(AsyncTaskMetrics.class);
action = new DeleteContactsAndHostsAction();
action.asyncTaskMetrics = asyncTaskMetricsMock;
@@ -614,7 +607,7 @@ public class DeleteContactsAndHostsActionTest
.hasDeletionTime(END_OF_TIME);
DomainBase domain =
loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
assertThat(domain.getNameservers()).contains(Key.create(hostAfter));
assertThat(domain.getNameservers()).contains(hostAfter.createKey());
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(hostAfter, HOST_DELETE_FAILURE);
assertPollMessageFor(
historyEntry,
@@ -684,7 +677,7 @@ public class DeleteContactsAndHostsActionTest
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.setDeletionTime(clock.nowUtc().minusDays(5))
.build());
enqueuer.enqueueAsyncDelete(
@@ -943,7 +936,7 @@ public class DeleteContactsAndHostsActionTest
return persistResource(
newDomainBase(domainName, contact)
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
}
@@ -17,8 +17,6 @@ package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.batch.AsyncTaskMetrics.OperationType.DNS_REFRESH;
import static google.registry.model.ofy.ObjectifyService.ofy;
@@ -86,13 +84,8 @@ public class RefreshDnsOnHostRenameActionTest
public void setup() {
createTld("tld");
enqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
mock(AppEngineServiceUtils.class),
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO);
AsyncTaskMetrics asyncTaskMetricsMock = mock(AsyncTaskMetrics.class);
action = new RefreshDnsOnHostRenameAction();
action.asyncTaskMetrics = asyncTaskMetricsMock;
@@ -28,6 +28,7 @@ import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCod
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableSet;
import google.registry.model.domain.DomainBase;
@@ -39,7 +40,10 @@ import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.UserInfo;
import google.registry.tools.DomainLockUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Optional;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -57,7 +61,10 @@ public class RelockDomainActionTest {
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock();
private final DomainLockUtils domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO));
@Rule
public final AppEngineRule appEngineRule =
@@ -79,7 +86,9 @@ public class RelockDomainActionTest {
oldLock = domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, CLIENT_ID, POC_ID, false);
assertThat(reloadDomain(domain).getStatusValues())
.containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES);
oldLock = domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, CLIENT_ID, false);
oldLock =
domainLockUtils.administrativelyApplyUnlock(
DOMAIN_NAME, CLIENT_ID, false, Optional.empty());
assertThat(reloadDomain(domain).getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
action = createAction(oldLock.getRevisionId());
}
@@ -14,14 +14,11 @@
package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
import static google.registry.batch.AsyncTaskEnqueuer.PATH_RESAVE_ENTITY;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.newDomainBase;
@@ -47,12 +44,10 @@ import google.registry.model.ofy.Ofy;
import google.registry.request.Response;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
import google.registry.testing.InjectRule;
import google.registry.testing.ShardableTestCase;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Before;
@@ -85,13 +80,7 @@ public class ResaveEntityActionTest extends ShardableTestCase {
inject.setStaticField(Ofy.class, "clock", clock);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(appEngineServiceUtils, clock, Duration.ZERO);
createTld("tld");
}
@@ -38,12 +38,12 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.net.InetAddresses;
import com.google.common.util.concurrent.RateLimiter;
import com.googlecode.objectify.Key;
import google.registry.dns.writer.clouddns.CloudDnsWriter.ZoneStateException;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineRule;
import google.registry.util.Retrier;
import google.registry.util.SystemClock;
@@ -292,9 +292,9 @@ public class CloudDnsWriterTest {
dsDataBuilder.add(DelegationSignerData.create(i, 3, 1, base16().decode("1234567890ABCDEF")));
}
ImmutableSet.Builder<Key<HostResource>> hostResourceRefBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostResourceRefBuilder = new ImmutableSet.Builder<>();
for (HostResource nameserver : nameservers) {
hostResourceRefBuilder.add(Key.create(nameserver));
hostResourceRefBuilder.add(nameserver.createKey());
}
return newDomainBase(domainName)
@@ -36,7 +36,6 @@ import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
@@ -106,7 +105,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1), Key.create(host2)))
.setNameservers(ImmutableSet.of(host1.createKey(), host2.createKey()))
.build();
persistResource(domain);
@@ -127,7 +126,7 @@ public class DnsUpdateWriterTest {
DomainBase domain1 =
persistActiveDomain("example1.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build();
persistResource(domain1);
@@ -135,7 +134,7 @@ public class DnsUpdateWriterTest {
DomainBase domain2 =
persistActiveDomain("example2.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build();
persistResource(domain2);
@@ -151,7 +150,7 @@ public class DnsUpdateWriterTest {
DomainBase domain1 =
persistActiveDomain("example1.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build();
persistResource(domain1);
@@ -159,7 +158,7 @@ public class DnsUpdateWriterTest {
DomainBase domain2 =
persistActiveDomain("example2.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build();
persistResource(domain2);
@@ -182,7 +181,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.setDsData(
ImmutableSet.of(
DelegationSignerData.create(1, 3, 1, base16().decode("0123456789ABCDEF"))))
@@ -207,7 +206,7 @@ public class DnsUpdateWriterTest {
persistActiveDomain("example.tld")
.asBuilder()
.addStatusValue(StatusValue.SERVER_HOLD)
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build();
persistResource(domain);
@@ -251,7 +250,7 @@ public class DnsUpdateWriterTest {
newDomainBase("example.tld")
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameserver(Key.create(host))
.addNameserver(host.createKey())
.build());
writer.publishHost("ns1.example.tld");
@@ -290,7 +289,7 @@ public class DnsUpdateWriterTest {
persistResource(
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.com"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.com").createKey()))
.build());
writer.publishHost("ns1.example.tld");
@@ -324,7 +323,7 @@ public class DnsUpdateWriterTest {
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameservers(
ImmutableSet.of(Key.create(externalNameserver), Key.create(inBailiwickNameserver)))
ImmutableSet.of(externalNameserver.createKey(), inBailiwickNameserver.createKey()))
.build());
writer.publishDomain("example.tld");
@@ -359,7 +358,7 @@ public class DnsUpdateWriterTest {
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addSubordinateHost("foo.example.tld")
.addNameserver(Key.create(inBailiwickNameserver))
.addNameserver(inBailiwickNameserver.createKey())
.build());
writer.publishDomain("example.tld");
@@ -383,7 +382,7 @@ public class DnsUpdateWriterTest {
DomainBase domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build();
persistResource(domain);
when(mockResolver.send(any(Message.class))).thenReturn(messageWithResponseCode(Rcode.SERVFAIL));
@@ -14,10 +14,7 @@
package google.registry.flows;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static org.joda.time.Duration.standardSeconds;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -26,6 +23,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.config.RegistryConfig.ConfigModule.TmchCaMode;
import google.registry.dns.DnsQueue;
@@ -42,10 +40,8 @@ import google.registry.tmch.TmchCertificateAuthority;
import google.registry.tmch.TmchXmlSignature;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Clock;
import google.registry.util.Retrier;
import google.registry.util.Sleeper;
import javax.inject.Singleton;
import org.joda.time.Duration;
/** Dagger component for running EPP tests. */
@Singleton
@@ -84,20 +80,12 @@ interface EppTestComponent {
}
public static FakesAndMocksModule create(
FakeClock clock,
EppMetric.Builder eppMetricBuilder,
TmchXmlSignature tmchXmlSignature) {
FakeClock clock, EppMetric.Builder eppMetricBuilder, TmchXmlSignature tmchXmlSignature) {
FakesAndMocksModule instance = new FakesAndMocksModule();
AppEngineServiceUtils appEngineServiceUtils = mock(AppEngineServiceUtils.class);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
instance.asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.standardSeconds(90),
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(appEngineServiceUtils, clock, standardSeconds(90));
instance.clock = clock;
instance.domainFlowTmchUtils = new DomainFlowTmchUtils(tmchXmlSignature);
instance.sleeper = new FakeSleeper(clock);
@@ -693,7 +693,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
loadByForeignKey(DomainBase.class, getUniqueIdFromCommand(), clock.nowUtc())
.get()
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
// Persist another domain that's already been deleted and references this contact and host.
persistResource(
@@ -701,7 +701,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
.asBuilder()
.setRegistrant(
Key.create(loadByForeignKey(ContactResource.class, "sh8013", clock.nowUtc()).get()))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.setDeletionTime(START_OF_TIME)
.build());
clock.advanceOneMilli();
@@ -118,7 +118,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
DesignatedContact.create(Type.ADMIN, Key.create(contact)),
DesignatedContact.create(Type.TECH, Key.create(contact))))
.setNameservers(
inactive ? null : ImmutableSet.of(Key.create(host1), Key.create(host2)))
inactive ? null : ImmutableSet.of(host1.createKey(), host2.createKey()))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR")))
.build());
// Set the superordinate domain of ns1.example.com to example.com. In reality, this would have
@@ -294,7 +294,7 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
ImmutableSet.of(
DelegationSignerData.create(
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC"))))
.setNameservers(ImmutableSet.of(Key.create(host1), Key.create(host3)))
.setNameservers(ImmutableSet.of(host1.createKey(), host3.createKey()))
.build());
doSuccessfulTest("domain_info_response_dsdata.xml", false);
}
@@ -843,7 +843,9 @@ public class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Dom
Key.getKind(ContactResource.class),
Key.getKind(HostResource.class)))))
.count();
assertThat(numReadsWithContactsOrHosts).isEqualTo(1);
// Nameserver keys now get persisted twice (because they are stored in nsHostsVKeys), so we
// check for two loads instead of 1.
assertThat(numReadsWithContactsOrHosts).isEqualTo(2);
}
@Test
@@ -88,6 +88,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import org.joda.money.Money;
import org.junit.Before;
import org.junit.Test;
@@ -138,7 +139,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
DesignatedContact.create(Type.ADMIN, Key.create(mak21Contact)),
DesignatedContact.create(Type.BILLING, Key.create(mak21Contact))))
.setRegistrant(Key.create(mak21Contact))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
historyEntryDomainCreate =
persistResource(
@@ -161,7 +162,7 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
ImmutableSet.of(
DesignatedContact.create(Type.TECH, Key.create(sh8013Contact)),
DesignatedContact.create(Type.ADMIN, Key.create(unusedContact))))
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
historyEntryDomainCreate =
persistResource(
@@ -255,14 +256,14 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
}
private void modifyDomainToHave13Nameservers() throws Exception {
ImmutableSet.Builder<Key<HostResource>> nameservers = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nameservers = new ImmutableSet.Builder<>();
for (int i = 1; i < 15; i++) {
if (i != 2) { // Skip 2 since that's the one that the tests will add.
nameservers.add(
Key.create(
loadByForeignKey(
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
.get()));
loadByForeignKey(
HostResource.class, String.format("ns%d.example.foo", i), clock.nowUtc())
.get()
.createKey());
}
}
persistResource(
@@ -285,11 +286,11 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
persistDomain();
setEppInput("domain_update_max_everything.xml");
// Create 26 hosts and 8 contacts. Start the domain with half of them.
ImmutableSet.Builder<Key<HostResource>> nameservers = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nameservers = new ImmutableSet.Builder<>();
for (int i = 0; i < 26; i++) {
HostResource host = persistActiveHost(String.format("max_test_%d.example.tld", i));
if (i < 13) {
nameservers.add(Key.create(host));
nameservers.add(host.createKey());
}
}
ImmutableList.Builder<DesignatedContact> contactsBuilder = new ImmutableList.Builder<>();
@@ -376,15 +377,15 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.addSubordinateHost("ns2.example.tld")
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get())))
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc())
.get()
.createKey()))
.build());
clock.advanceOneMilli();
assertTransactionalFlow(true);
runFlowAssertResponse(loadFile("generic_success_response.xml"));
domain = reloadResourceByForeignKey();
assertThat(domain.getNameservers()).containsExactly(Key.create(addedHost));
assertThat(domain.getNameservers()).containsExactly(addedHost.createKey());
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.tld", "ns2.example.tld");
HostResource existingHost =
loadByForeignKey(HostResource.class, "ns1.example.tld", clock.nowUtc()).get();
@@ -1058,9 +1059,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.asBuilder()
.setNameservers(
ImmutableSet.of(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get())))
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get()
.createKey()))
.build());
EppException thrown = assertThrows(AddRemoveSameValueException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@@ -1198,13 +1199,15 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.doesNotContain(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey());
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey());
}
@Test
@@ -1275,8 +1278,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
reloadResourceByForeignKey()
.asBuilder()
.addNameserver(
Key.create(
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc()).get()))
loadByForeignKey(HostResource.class, "ns2.example.foo", clock.nowUtc())
.get()
.createKey())
.build());
persistResource(
Registry.get("tld")
@@ -1286,8 +1290,9 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
.build());
assertThat(reloadResourceByForeignKey().getNameservers())
.contains(
Key.create(
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc()).get()));
loadByForeignKey(HostResource.class, "ns1.example.foo", clock.nowUtc())
.get()
.createKey());
clock.advanceOneMilli();
runFlow();
assertThat(reloadResourceByForeignKey().getNameservers())
@@ -284,7 +284,7 @@ public class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Hos
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(persistActiveHost("ns1.example.tld"))))
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createKey()))
.build());
EppException thrown = assertThrows(ResourceToDeleteIsReferencedException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
@@ -92,7 +92,7 @@ public class HostInfoFlowTest extends ResourceFlowTestCase<HostInfoFlow, HostRes
persistResource(
newDomainBase("example.foobar")
.asBuilder()
.addNameserver(Key.create(persistHostResource()))
.addNameserver(persistHostResource().createKey())
.build());
assertTransactionalFlow(false);
// Check that the persisted host info was returned.
@@ -195,7 +195,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
newDomainBase("test.xn--q9jyb4c")
.asBuilder()
.setDeletionTime(END_OF_TIME)
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
HostResource renamedHost = doSuccessfulTest();
assertThat(renamedHost.isSubordinate()).isTrue();
@@ -42,22 +42,33 @@ import java.util.Set;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Base class of all unit tests for entities which are persisted to Datastore via Objectify. */
@RunWith(JUnit4.class)
public abstract class EntityTestCase {
protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC));
@Rule
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
@Rule @RegisterExtension public final AppEngineRule appEngine;
@Rule public InjectRule inject = new InjectRule();
@Rule @RegisterExtension public InjectRule inject = new InjectRule();
protected EntityTestCase() {
this(false);
}
protected EntityTestCase(boolean enableJpaEntityCheck) {
appEngine =
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(enableJpaEntityCheck)
.withClock(fakeClock)
.build();
}
@Before
@BeforeEach
public void injectClock() {
inject.setStaticField(Ofy.class, "clock", fakeClock);
}
@@ -17,31 +17,45 @@ package google.registry.model.domain;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock;
import javax.persistence.EntityManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Verify that we can store/retrieve DomainBase objects from a SQL database. */
@RunWith(JUnit4.class)
public class DomainBaseSqlTest extends EntityTestCase {
public class DomainBaseSqlTest {
protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC));
@RegisterExtension
@Order(value = 1)
DatastoreEntityExtension datastoreEntityExtension = new DatastoreEntityExtension();
@RegisterExtension
JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
DomainBase domain;
Key<ContactResource> contactKey;
Key<ContactResource> contact2Key;
@Before
@BeforeEach
public void setUp() {
contactKey = Key.create(ContactResource.class, "contact_id1");
contact2Key = Key.create(ContactResource.class, "contact_id2");
@@ -54,6 +54,7 @@ import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.Before;
@@ -65,19 +66,20 @@ public class DomainBaseTest extends EntityTestCase {
private DomainBase domain;
private Key<BillingEvent.OneTime> oneTimeBillKey;
private Key<BillingEvent.Recurring> recurringBillKey;
private Key<DomainBase> domainKey;
@Before
public void setUp() {
createTld("com");
Key<DomainBase> domainKey = Key.create(null, DomainBase.class, "4-COM");
Key<HostResource> hostKey =
Key.create(
persistResource(
domainKey = Key.create(null, DomainBase.class, "4-COM");
VKey<HostResource> hostKey =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns1.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("1-COM")
.build()));
.build())
.createKey();
Key<ContactResource> contact1Key =
Key.create(
persistResource(
@@ -219,7 +221,7 @@ public class DomainBaseTest extends EntityTestCase {
assertThat(
newDomainBase("example.com")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(newHostResource("foo.example.tld"))))
.setNameservers(ImmutableSet.of(newHostResource("foo.example.tld").createKey()))
.build()
.nsHosts)
.isNotNull();
@@ -266,8 +268,8 @@ public class DomainBaseTest extends EntityTestCase {
@Test
public void testImplicitStatusValues() {
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(newHostResource("foo.example.tld")));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(newHostResource("foo.example.tld").createKey());
StatusValue[] statuses = {StatusValue.OK};
// OK is implicit if there's no other statuses but there are nameservers.
assertAboutDomains()
@@ -769,4 +771,60 @@ public class DomainBaseTest extends EntityTestCase {
assertThat(getOnlyElement(clone.getGracePeriods()).getType())
.isEqualTo(GracePeriodStatus.TRANSFER);
}
private static ImmutableSet<Key<HostResource>> getOfyNameservers(DomainBase domain) {
return domain.getNameservers().stream().map(key -> key.getOfyKey()).collect(toImmutableSet());
}
@Test
public void testNameservers_nsHostsOfyKeys() {
assertThat(domain.nsHosts).isEqualTo(getOfyNameservers(domain));
// Test the setNameserver that functions on a function.
VKey<HostResource> host1Key =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns2.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("2-COM")
.build())
.createKey();
DomainBase dom = new DomainBase.Builder(domain).setNameservers(host1Key).build();
assertThat(dom.getNameservers()).isEqualTo(ImmutableSet.of(host1Key));
assertThat(getOfyNameservers(dom)).isEqualTo(ImmutableSet.of(host1Key.getOfyKey()));
// Test that setting to a single host of null throws an NPE.
assertThrows(
NullPointerException.class,
() -> new DomainBase.Builder(domain).setNameservers((VKey<HostResource>) null));
// Test that setting to a set of values works.
VKey<HostResource> host2Key =
persistResource(
new HostResource.Builder()
.setFullyQualifiedHostName("ns3.example.com")
.setSuperordinateDomain(domainKey)
.setRepoId("3-COM")
.build())
.createKey();
dom =
new DomainBase.Builder(domain).setNameservers(ImmutableSet.of(host1Key, host2Key)).build();
assertThat(dom.getNameservers()).isEqualTo(ImmutableSet.of(host1Key, host2Key));
assertThat(getOfyNameservers(dom))
.isEqualTo(ImmutableSet.of(host1Key.getOfyKey(), host2Key.getOfyKey()));
// Set of values, passing null.
dom =
new DomainBase.Builder(domain)
.setNameservers((ImmutableSet<VKey<HostResource>>) null)
.build();
assertThat(dom.nsHostVKeys).isNull();
assertThat(dom.nsHosts).isNull();
// Empty set of values gets translated to null.
dom = new DomainBase.Builder(domain).setNameservers(ImmutableSet.of()).build();
assertThat(dom.nsHostVKeys).isNull();
assertThat(dom.nsHosts).isNull();
}
}
@@ -31,20 +31,21 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import java.util.Optional;
import org.joda.time.Duration;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link RegistryLockDao}. */
@RunWith(JUnit4.class)
public final class RegistryLockDaoTest {
private final FakeClock fakeClock = new FakeClock();
@Rule
@RegisterExtension
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(true)
.withClock(fakeClock)
.build();
@Test
public void testSaveAndLoad_success() {
@@ -29,21 +29,18 @@ import google.registry.model.registry.label.PremiumList.PremiumListEntry;
import google.registry.model.registry.label.PremiumList.PremiumListRevision;
import google.registry.testing.AppEngineRule;
import org.joda.money.Money;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link PremiumList}. */
@RunWith(JUnit4.class)
public class PremiumListTest {
@Rule
@RegisterExtension
public final AppEngineRule appEngine = AppEngineRule.builder().withDatastoreAndCloudSql().build();
@Before
public void before() {
@BeforeEach
void before() {
// createTld() overwrites the premium list, so call it first.
createTld("tld");
PremiumList pl =
@@ -57,20 +54,20 @@ public class PremiumListTest {
}
@Test
public void testSave_badSyntax() {
void testSave_badSyntax() {
assertThrows(
IllegalArgumentException.class,
() -> persistPremiumList("gtld1", "lol,nonsense USD,e,e # yup"));
}
@Test
public void testSave_invalidCurrencySymbol() {
void testSave_invalidCurrencySymbol() {
assertThrows(
IllegalArgumentException.class, () -> persistReservedList("gtld1", "lol,XBTC 200"));
}
@Test
public void testProbablePremiumLabels() {
void testProbablePremiumLabels() {
PremiumList pl = PremiumList.getUncached("tld").get();
PremiumListRevision revision = ofy().load().key(pl.getRevisionKey()).now();
assertThat(revision.getProbablePremiumLabels().mightContain("notpremium")).isFalse();
@@ -82,7 +79,7 @@ public class PremiumListTest {
}
@Test
public void testParse_cannotIncludeDuplicateLabels() {
void testParse_cannotIncludeDuplicateLabels() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
@@ -103,7 +100,7 @@ public class PremiumListTest {
}
@Test
public void testValidation_labelMustBeLowercase() {
void testValidation_labelMustBeLowercase() {
Exception e =
assertThrows(
IllegalArgumentException.class,
@@ -116,7 +113,7 @@ public class PremiumListTest {
}
@Test
public void testValidation_labelMustBePunyCoded() {
void testValidation_labelMustBePunyCoded() {
Exception e =
assertThrows(
IllegalArgumentException.class,
@@ -0,0 +1,302 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import com.google.common.collect.ImmutableSet;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.lang.reflect.Method;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import javax.persistence.Transient;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link EntityCallbacksListener}. */
@RunWith(JUnit4.class)
public class EntityCallbacksListenerTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
@Test
public void verifyAllCallbacks_executedExpectedTimes() {
TestEntity testPersist = new TestEntity();
jpaTm().transact(() -> jpaTm().saveNew(testPersist));
checkAll(testPersist, 1, 0, 0, 0);
TestEntity testUpdate = new TestEntity();
TestEntity updated =
jpaTm()
.transact(
() -> {
TestEntity merged = jpaTm().getEntityManager().merge(testUpdate);
merged.foo++;
jpaTm().getEntityManager().flush();
return merged;
});
// Note that when we get the merged entity, its @PostLoad callbacks are also invoked
checkAll(updated, 0, 1, 0, 1);
TestEntity testLoad =
jpaTm().transact(() -> jpaTm().load(VKey.createSql(TestEntity.class, "id"))).get();
checkAll(testLoad, 0, 0, 0, 1);
TestEntity testRemove =
jpaTm()
.transact(
() -> {
TestEntity removed = jpaTm().load(VKey.createSql(TestEntity.class, "id")).get();
jpaTm().getEntityManager().remove(removed);
return removed;
});
checkAll(testRemove, 0, 0, 1, 1);
}
@Test
public void verifyAllManagedEntities_haveNoMethodWithEmbedded() {
ImmutableSet<Class> violations =
PersistenceXmlUtility.getManagedClasses().stream()
.filter(clazz -> clazz.isAnnotationPresent(Entity.class))
.filter(EntityCallbacksListenerTest::hasMethodAnnotatedWithEmbedded)
.collect(toImmutableSet());
assertWithMessage(
"Found entity classes having methods annotated with @Embedded. EntityCallbacksListener"
+ " only supports annotating fields with @Embedded.")
.that(violations)
.isEmpty();
}
@Test
public void verifyHasMethodAnnotatedWithEmbedded_work() {
assertThat(hasMethodAnnotatedWithEmbedded(ViolationEntity.class)).isTrue();
}
private static boolean hasMethodAnnotatedWithEmbedded(Class<?> entityType) {
boolean result = false;
Class<?> parentType = entityType.getSuperclass();
if (parentType != null && parentType.isAnnotationPresent(MappedSuperclass.class)) {
result = hasMethodAnnotatedWithEmbedded(parentType);
}
for (Method method : entityType.getDeclaredMethods()) {
if (method.isAnnotationPresent(Embedded.class)) {
result = true;
break;
}
}
return result;
}
private static void checkAll(
TestEntity testEntity,
int expectedPersist,
int expectedUpdate,
int expectedRemove,
int expectedLoad) {
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPostPersist)
.isEqualTo(expectedPersist);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPrePersist)
.isEqualTo(expectedPersist);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPreUpdate)
.isEqualTo(expectedUpdate);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPostUpdate)
.isEqualTo(expectedUpdate);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPreRemove)
.isEqualTo(expectedRemove);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPostRemove)
.isEqualTo(expectedRemove);
assertThat(testEntity.entityPostLoad).isEqualTo(expectedLoad);
assertThat(testEntity.entityEmbedded.entityEmbeddedPostLoad).isEqualTo(expectedLoad);
assertThat(testEntity.entityEmbedded.entityEmbeddedNested.entityEmbeddedNestedPostLoad)
.isEqualTo(expectedLoad);
assertThat(testEntity.entityEmbedded.entityEmbeddedParentPostLoad).isEqualTo(expectedLoad);
assertThat(testEntity.parentPostLoad).isEqualTo(expectedLoad);
assertThat(testEntity.parentEmbedded.parentEmbeddedPostLoad).isEqualTo(expectedLoad);
assertThat(testEntity.parentEmbedded.parentEmbeddedNested.parentEmbeddedNestedPostLoad)
.isEqualTo(expectedLoad);
assertThat(testEntity.parentEmbedded.parentEmbeddedParentPostLoad).isEqualTo(expectedLoad);
}
@Entity(name = "TestEntity")
private static class TestEntity extends ParentEntity {
@Id String name = "id";
int foo = 0;
@Transient int entityPostLoad = 0;
@Embedded EntityEmbedded entityEmbedded = new EntityEmbedded();
@PostLoad
void entityPostLoad() {
entityPostLoad++;
}
}
@Embeddable
private static class EntityEmbedded extends EntityEmbeddedParent {
@Embedded EntityEmbeddedNested entityEmbeddedNested = new EntityEmbeddedNested();
@Transient int entityEmbeddedPostLoad = 0;
String entityEmbedded = "placeholder";
@PostLoad
void entityEmbeddedPrePersist() {
entityEmbeddedPostLoad++;
}
}
@MappedSuperclass
private static class EntityEmbeddedParent {
@Transient int entityEmbeddedParentPostLoad = 0;
String entityEmbeddedParent = "placeholder";
@PostLoad
void entityEmbeddedParentPostLoad() {
entityEmbeddedParentPostLoad++;
}
}
@Embeddable
private static class EntityEmbeddedNested {
@Transient int entityEmbeddedNestedPrePersist = 0;
@Transient int entityEmbeddedNestedPreRemove = 0;
@Transient int entityEmbeddedNestedPostPersist = 0;
@Transient int entityEmbeddedNestedPostRemove = 0;
@Transient int entityEmbeddedNestedPreUpdate = 0;
@Transient int entityEmbeddedNestedPostUpdate = 0;
@Transient int entityEmbeddedNestedPostLoad = 0;
String entityEmbeddedNested = "placeholder";
@PrePersist
void entityEmbeddedNestedPrePersist() {
entityEmbeddedNestedPrePersist++;
}
@PreRemove
void entityEmbeddedNestedPreRemove() {
entityEmbeddedNestedPreRemove++;
}
@PostPersist
void entityEmbeddedNestedPostPersist() {
entityEmbeddedNestedPostPersist++;
}
@PostRemove
void entityEmbeddedNestedPostRemove() {
entityEmbeddedNestedPostRemove++;
}
@PreUpdate
void entityEmbeddedNestedPreUpdate() {
entityEmbeddedNestedPreUpdate++;
}
@PostUpdate
void entityEmbeddedNestedPostUpdate() {
entityEmbeddedNestedPostUpdate++;
}
@PostLoad
void entityEmbeddedNestedPostLoad() {
entityEmbeddedNestedPostLoad++;
}
}
@MappedSuperclass
private static class ParentEntity {
@Embedded ParentEmbedded parentEmbedded = new ParentEmbedded();
@Transient int parentPostLoad = 0;
String parentEntity = "placeholder";
@PostLoad
void parentPostLoad() {
parentPostLoad++;
}
}
@Embeddable
private static class ParentEmbedded extends ParentEmbeddedParent {
@Transient int parentEmbeddedPostLoad = 0;
String parentEmbedded = "placeholder";
@Embedded ParentEmbeddedNested parentEmbeddedNested = new ParentEmbeddedNested();
@PostLoad
void parentEmbeddedPostLoad() {
parentEmbeddedPostLoad++;
}
}
@Embeddable
private static class ParentEmbeddedNested {
@Transient int parentEmbeddedNestedPostLoad = 0;
String parentEmbeddedNested = "placeholder";
@PostLoad
void parentEmbeddedNestedPostLoad() {
parentEmbeddedNestedPostLoad++;
}
}
@MappedSuperclass
private static class ParentEmbeddedParent {
@Transient int parentEmbeddedParentPostLoad = 0;
String parentEmbeddedParent = "placeholder";
@PostLoad
void parentEmbeddedParentPostLoad() {
parentEmbeddedParentPostLoad++;
}
}
@Entity
private static class ViolationEntity {
@Embedded
EntityEmbedded getEntityEmbedded() {
return new EntityEmbedded();
}
}
}
@@ -0,0 +1,45 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import static com.google.common.truth.Truth.assertThat;
import com.googlecode.objectify.Key;
import google.registry.testing.AppEngineRule;
import google.registry.testing.TestObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class VKeyTest {
@Rule
public final AppEngineRule appEngineRule =
AppEngineRule.builder().withDatastoreAndCloudSql().build();
public VKeyTest() {}
@Test
public void testOptionalAccessors() {
VKey<TestObject> key = VKey.create(TestObject.class, null, null);
assertThat(key.maybeGetSqlKey().isPresent()).isFalse();
assertThat(key.maybeGetOfyKey().isPresent()).isFalse();
Key<TestObject> ofyKey = Key.create(TestObject.create("foo"));
assertThat(VKey.createOfy(TestObject.class, ofyKey).maybeGetOfyKey().get()).isEqualTo(ofyKey);
assertThat(VKey.createSql(TestObject.class, "foo").maybeGetSqlKey().get()).isEqualTo("foo");
}
}
@@ -32,7 +32,7 @@ import org.junit.runners.JUnit4;
/** Unit tests for {@link CidrAddressBlockListConverter}. */
@RunWith(JUnit4.class)
public class CidrAddressBlockListUserTypeTest {
public class CidrAddressBlockListConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
@@ -25,16 +25,15 @@ import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Type;
import org.joda.money.CurrencyUnit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link CurrencyToBillingMapUserType}. */
/** Unit tests for {@link CurrencyToBillingConverter}. */
@RunWith(JUnit4.class)
public class CurrencyToBillingMapUserTypeTest {
public class CurrencyToBillingConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
@@ -62,7 +61,6 @@ public class CurrencyToBillingMapUserTypeTest {
@Id String name = "id";
@Type(type = "google.registry.persistence.converter.CurrencyToBillingMapUserType")
Map<CurrencyUnit, BillingAccountEntry> currencyToBilling;
private TestEntity() {}
@@ -19,54 +19,56 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.util.Map;
import javax.persistence.Converter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NoResultException;
import org.hibernate.annotations.Type;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link MapUserType}. */
/** Unit tests for {@link StringMapConverterBase}. */
@RunWith(JUnit4.class)
public class MapUserTypeTest {
// Reusing production script sql/flyway/V14__load_extension_for_hstore.sql, which loads the
// hstore extension but nothing else.
public class StringMapConverterBaseTest {
@Rule
public final JpaUnitTestRule jpaRule =
public final JpaTestRules.JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
.withInitScript("sql/flyway/V14__load_extension_for_hstore.sql")
.withEntityClass(TestEntity.class)
.withEntityClass(TestStringMapConverter.class, TestEntity.class)
.buildUnitTestRule();
private static final ImmutableMap<Key, Value> MAP =
ImmutableMap.of(
new Key("key1"), new Value("value1"),
new Key("key2"), new Value("value2"),
new Key("key3"), new Value("value3"));
@Test
public void roundTripConversion_returnsSameMap() {
Map<String, String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
TestEntity testEntity = new TestEntity(map);
TestEntity testEntity = new TestEntity(MAP);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).containsExactly("key1", "value1", "key2", "value2");
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
}
@Test
public void testMerge_succeeds() {
Map<String, String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
TestEntity testEntity = new TestEntity(map);
public void testUpdateColumn_succeeds() {
TestEntity testEntity = new TestEntity(MAP);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
persisted.map = ImmutableMap.of("key3", "value3");
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
persisted.map = ImmutableMap.of(new Key("key4"), new Value("value4"));
jpaTm().transact(() -> jpaTm().getEntityManager().merge(persisted));
TestEntity updated =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(updated.map).containsExactly("key3", "value3");
assertThat(updated.map).containsExactly(new Key("key4"), new Value("value4"));
}
@Test
@@ -79,7 +81,7 @@ public class MapUserTypeTest {
}
@Test
public void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
public void testEmptyMap_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableMap.of());
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
@@ -88,7 +90,7 @@ public class MapUserTypeTest {
}
@Test
public void testNativeQuery_succeeds() throws Exception {
public void testNativeQuery_succeeds() {
executeNativeQuery(
"INSERT INTO \"TestEntity\" (name, map) VALUES ('id', 'key1=>value1, key2=>value2')");
@@ -126,17 +128,46 @@ public class MapUserTypeTest {
.transact(() -> jpaTm().getEntityManager().createNativeQuery(sql).executeUpdate());
}
private static class Key extends ImmutableObject {
private String key;
private Key(String key) {
this.key = key;
}
}
private static class Value extends ImmutableObject {
private String value;
private Value(String value) {
this.value = value;
}
}
@Converter(autoApply = true)
private static class TestStringMapConverter extends StringMapConverterBase<Key, Value> {
@Override
Map.Entry<String, String> convertToDatabaseMapEntry(Map.Entry<Key, Value> entry) {
return Maps.immutableEntry(entry.getKey().key, entry.getValue().value);
}
@Override
Map.Entry<Key, Value> convertToEntityMapEntry(Map.Entry<String, String> entry) {
return Maps.immutableEntry(new Key(entry.getKey()), new Value(entry.getValue()));
}
}
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
private static class TestEntity extends ImmutableObject {
@Id String name = "id";
@Type(type = "google.registry.persistence.converter.MapUserType")
Map<String, String> map;
Map<Key, Value> map;
private TestEntity() {}
private TestEntity(Map<String, String> map) {
private TestEntity(Map<Key, Value> map) {
this.map = map;
}
}

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