1
0
mirror of https://github.com/google/nomulus synced 2026-07-11 02:22:30 +00:00

Compare commits

...

22 Commits

Author SHA1 Message Date
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
gbrodman ad06f265a5 Flat-map registry lock emails to avoid unclean errors in bad situations (#525)
* Flat map to avoid unclean errors in bad situations

Also properly reflect that for admins, we will use their user email

* Make MS's GAE user ID a public static field
2020-03-23 11:45:49 -04:00
Shicong Huang fa9400ebc5 Set postgres package back to runtime dependency (#522) 2020-03-20 15:43:30 -04:00
gbrodman 519a85af85 Add a registryLockEmailAddress field to RegistrarConctact objects (#523)
* Add a registryLockEmailAddress field to RegistrarConctact objects

Because we need to manage the login email, it should be on an account
that we manage. However, for registry lock, we would want to send the
verification emails to a separate email address that the user can use.

As a result, we will use a second field for a user-accessible registry
lock email address. This must be set on the contact when enabling
registry lock for this contact.

* Responses to CR

* derp
2020-03-20 14:12:00 -04:00
sarahcaseybot b2df127dc4 Add lock dual read (#517)
* Add lock dual read

* small changes
2020-03-20 14:11:00 -04:00
gbrodman b21042bda9 Fix the test server (#521)
* Fix the test server

This rule isn't necessary any more since we merged the SQL-starting rule
into the AppEngineRule logic. Furthermore, it actually causes the test
server to crash because we try to drop-and-create the DB twice, the
second time while the first instance is still connected.
2020-03-19 11:05:51 -04:00
Lai Jiang 36378f6b10 Upgrade to Gradle 6.2.2 (#518) 2020-03-18 21:38:37 -04:00
Shicong Huang d01f1f7604 Make jpaTm for nomulus tool use local credential (#515)
* Make jpaTm for nomulus tool use local credential

* Remove unused methods in RegistryToolEnvironment

* Fix order of annotations

* Remove unused method in PersistenceComponent

* Move the creation of credential to the module

* Move creadential creation to AuthModule

* Add a TODO
2020-03-17 20:16:42 -04:00
gbrodman e9610636e4 Add a relockDuration to the RegistryLock SQL object (#514)
* Add a relockDuration to the RegistryLock SQL object

This is the length of time after an unlock that we will re-lock the
domain in question.

* Sort by domain name for stability

Note: this is likely not the best solution for the UI but we can iterate
on this.

* Add nullable

* Add a converter for Duration
2020-03-16 17:44:25 -04:00
gbrodman d09fc7ee05 Match logged-in GAE user ID with registrar POC user ID (#511)
* Match logged-in GAE user ID with registrar POC user ID

The reasoning for this is thus:
We wish to have the users log in using Google-managed addresses--this is
so that we can manage enforcement of things like 2FA, as well as generic
account management. However, we wish for the registry-lock confirmation
emails to go to their standard non-Google email addresses--e.g.
johndoe@theregistrar.com, rather than johndoe@registry.google.

As a result, for registry lock, we will enable it on
the johndoe@registry.google account, but we will alter the email address
of the corresponding Registrar POC account to contain
johndoe@theregistrar.com. By doing this, the user will still be logging
in using the @registry.google account but we'll match to their actual
contact email.

* fix up comments and messages

* Error if >1 matching contact

* include email addresses

* set default optional

* fix tests
2020-03-16 11:38:05 -04:00
Shicong Huang 0545375eba Change cloud sql SDK to compile level dependency (#516) 2020-03-16 10:24:19 -04:00
153 changed files with 2729 additions and 1491 deletions
+2
View File
@@ -197,6 +197,7 @@ dependencies {
compile deps['com.google.appengine:appengine-remote-api']
compile deps['com.google.auth:google-auth-library-credentials']
compile deps['com.google.auth:google-auth-library-oauth2-http']
compile deps['com.google.cloud.sql:jdbc-socket-factory-core']
runtimeOnly deps['com.google.cloud.sql:postgres-socket-factory']
compile deps['com.google.code.gson:gson']
compile deps['com.google.auto.value:auto-value-annotations']
@@ -302,6 +303,7 @@ 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.vintage:junit-vintage-engine']
testCompile deps['org.mockito:mockito-core']
runtime deps['org.postgresql:postgresql']
+30 -19
View File
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -84,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
@@ -124,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
@@ -146,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
@@ -183,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
@@ -212,11 +223,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -83,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
@@ -123,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
@@ -144,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
@@ -180,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
@@ -207,11 +218,11 @@ org.jvnet.staxex:stax-ex:1.8
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
+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
@@ -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
@@ -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
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -84,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
@@ -124,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
@@ -146,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
@@ -183,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
@@ -212,11 +223,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -83,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
@@ -123,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
@@ -144,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
@@ -181,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
@@ -210,11 +221,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -84,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
@@ -124,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
@@ -146,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
@@ -183,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
@@ -212,11 +223,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.postgresql:postgresql:42.2.6
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -84,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
@@ -124,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
@@ -146,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
@@ -183,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
@@ -212,11 +223,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.postgresql:postgresql:42.2.6
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
+30 -19
View File
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -65,6 +75,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -84,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
@@ -124,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
@@ -146,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
@@ -183,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
@@ -212,11 +223,11 @@ org.mockito:mockito-core:1.9.5
org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:1.2
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.postgresql:postgresql:42.2.6
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
@@ -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
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -66,6 +76,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -86,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
@@ -98,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
@@ -133,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
@@ -155,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
@@ -198,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
@@ -234,6 +245,7 @@ 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.jupiter:junit-jupiter-migrationsupport: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
@@ -244,11 +256,11 @@ org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
@@ -1,20 +1,29 @@
# 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.google.api-client:google-api-client-appengine:1.29.0
com.github.jnr:jffi:1.2.17
com.github.jnr:jnr-a64asm:1.0.0
com.github.jnr:jnr-constants:0.9.11
com.github.jnr:jnr-enxio:0.19
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.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
@@ -50,6 +59,7 @@ com.google.apis:google-api-services-groupssettings:v1-rev60-1.22.0
com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0
com.google.apis:google-api-services-pubsub:v1-rev20181105-1.27.0
com.google.apis:google-api-services-sheets:v4-rev483-1.22.0
com.google.apis:google-api-services-sqladmin:v1beta4-rev56-1.23.0
com.google.apis:google-api-services-storage:v1-rev20181109-1.27.0
com.google.appengine.tools:appengine-gcs-client:0.6
com.google.appengine.tools:appengine-mapreduce:0.9
@@ -66,6 +76,7 @@ com.google.cloud.bigdataoss:gcsio:1.9.16
com.google.cloud.bigdataoss:util:1.9.16
com.google.cloud.bigtable:bigtable-client-core:1.8.0
com.google.cloud.datastore:datastore-v1-proto-client:1.6.0
com.google.cloud.sql:jdbc-socket-factory-core:1.0.12
com.google.cloud:google-cloud-bigquerystorage:0.79.0-alpha
com.google.cloud:google-cloud-bigtable-admin:0.73.0-alpha
com.google.cloud:google-cloud-bigtable:0.73.0-alpha
@@ -85,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
@@ -97,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
@@ -132,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
@@ -153,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
@@ -196,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
@@ -232,6 +243,7 @@ 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.jupiter:junit-jupiter-migrationsupport: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
@@ -242,11 +254,11 @@ org.mortbay.jetty:jetty-util:6.1.26
org.mortbay.jetty:jetty:6.1.26
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
org.ow2.asm:asm-analysis:6.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:6.0
org.ow2.asm:asm-tree:6.0
org.ow2.asm:asm-util:6.0
org.ow2.asm:asm:6.0
org.ow2.asm:asm-tree:7.0
org.ow2.asm:asm-util:7.0
org.ow2.asm:asm:7.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
@@ -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
@@ -247,6 +248,7 @@ 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.jupiter:junit-jupiter-migrationsupport: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
@@ -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
@@ -247,6 +248,7 @@ 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.jupiter:junit-jupiter-migrationsupport: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
@@ -30,6 +30,7 @@ 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.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import javax.inject.Inject;
@@ -148,12 +149,12 @@ 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()));
}
@@ -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;
}
@@ -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);
}
}
@@ -44,7 +44,9 @@ import google.registry.model.Jsonifiable;
import google.registry.model.annotations.ReportedOn;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -112,6 +114,9 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
@Column(nullable = false)
String emailAddress;
/** External email address of this contact used for registry lock confirmations. */
String registryLockEmailAddress;
/** The voice number of the contact. */
String phoneNumber;
@@ -212,6 +217,10 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
return emailAddress;
}
public Optional<String> getRegistryLockEmailAddress() {
return Optional.ofNullable(registryLockEmailAddress);
}
public String getPhoneNumber() {
return phoneNumber;
}
@@ -318,6 +327,7 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
return new JsonMapBuilder()
.put("name", name)
.put("emailAddress", emailAddress)
.put("registryLockEmailAddress", registryLockEmailAddress)
.put("phoneNumber", phoneNumber)
.put("faxNumber", faxNumber)
.put("types", getTypes().stream().map(Object::toString).collect(joining(",")))
@@ -352,6 +362,14 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
public RegistrarContact build() {
checkNotNull(getInstance().parent, "Registrar parent cannot be null");
checkValidEmail(getInstance().emailAddress);
// Check allowedToSetRegistryLockPassword here because if we want to allow the user to set
// a registry lock password, we must also set up the correct registry lock email concurrently
// or beforehand.
if (getInstance().allowedToSetRegistryLockPassword) {
checkArgument(
!isNullOrEmpty(getInstance().registryLockEmailAddress),
"Registry lock email must not be null if allowing registry lock access");
}
return cloneEmptyToNull(super.build());
}
@@ -365,6 +383,11 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
return this;
}
public Builder setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
getInstance().registryLockEmailAddress = registryLockEmailAddress;
return this;
}
public Builder setPhoneNumber(String phoneNumber) {
getInstance().phoneNumber = phoneNumber;
return this;
@@ -52,8 +52,10 @@ public final class RegistryLockDao {
jpaTm()
.getEntityManager()
.createQuery(
"SELECT lock FROM RegistryLock lock WHERE lock.registrarId = :registrarId"
+ " AND lock.unlockCompletionTimestamp IS NULL",
"SELECT lock FROM RegistryLock lock"
+ " WHERE lock.registrarId = :registrarId"
+ " AND lock.unlockCompletionTimestamp IS NULL"
+ " ORDER BY lock.domainName ASC",
RegistryLock.class)
.setParameter("registrarId", registrarId)
.getResultList());
@@ -78,6 +78,18 @@ public class Lock extends ImmutableObject implements Serializable {
/** When the lock can be considered implicitly released. */
DateTime expirationTime;
public String getRequestLogId() {
return requestLogId;
}
public DateTime getExpirationTime() {
return expirationTime;
}
public DateTime getAcquiredTime() {
return acquiredTime;
}
/** When was the lock acquired. Used for logging. */
DateTime acquiredTime;
@@ -89,10 +101,10 @@ public class Lock extends ImmutableObject implements Serializable {
String tld;
/**
* Create a new {@link Lock} for the given resource name in the specified tld (which can be
* null for cross-tld locks).
* Create a new {@link Lock} for the given resource name in the specified tld (which can be null
* for cross-tld locks).
*/
private static Lock create(
public static Lock create(
String resourceName,
@Nullable String tld,
String requestLogId,
@@ -185,6 +197,18 @@ public class Lock extends ImmutableObject implements Serializable {
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
Lock lock = ofy().load().type(Lock.class).id(lockId).now();
try {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
LockDao.compare(Optional.ofNullable(lock), cloudSqlLockOptional);
});
} catch (Exception e) {
logger.atSevere().withCause(e).log(
"Issue loading and comparing lock from Cloud SQL");
}
if (lock != null) {
logger.atInfo().log(
"Loaded existing lock: %s for request: %s", lock.lockId, lock.requestLogId);
@@ -221,12 +245,7 @@ public class Lock extends ImmutableObject implements Serializable {
requestStatusChecker.getLogId(),
now,
leaseLength);
// cloudSqlLock should not already exist in Cloud SQL, but call delete
// just in case
// TODO: Remove this delete once dual read is added
LockDao.delete(
resourceName, Optional.ofNullable(tld).orElse("GLOBAL"));
LockDao.saveNew(cloudSqlLock);
LockDao.save(cloudSqlLock);
});
} catch (Exception e) {
logger.atSevere().withCause(e).log(
@@ -251,6 +270,18 @@ public class Lock extends ImmutableObject implements Serializable {
// this can happen if release() is called around the expiration time and the lock
// expires underneath us.
Lock loadedLock = ofy().load().type(Lock.class).id(lockId).now();
try {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
LockDao.compare(Optional.ofNullable(loadedLock), cloudSqlLockOptional);
});
} catch (Exception e) {
logger.atSevere().withCause(e).log(
"Issue loading and comparing lock from Cloud SQL");
}
if (Lock.this.equals(loadedLock)) {
// Use noBackupOfy() so that we don't create a commit log entry for deleting the
// lock.
@@ -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)
@@ -19,7 +19,6 @@ import google.registry.config.CredentialModule;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.keyring.kms.KmsModule;
import google.registry.persistence.PersistenceModule.AppEngineJpaTm;
import google.registry.persistence.PersistenceModule.NomulusToolJpaTm;
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.util.UtilsModule;
import javax.inject.Singleton;
@@ -39,7 +38,4 @@ public interface PersistenceComponent {
@AppEngineJpaTm
JpaTransactionManager appEngineJpaTransactionManager();
@NomulusToolJpaTm
JpaTransactionManager nomulusToolJpaTransactionManager();
}
@@ -22,6 +22,7 @@ import static google.registry.config.RegistryConfig.getHibernateHikariMaximumPoo
import static google.registry.config.RegistryConfig.getHibernateHikariMinimumIdle;
import static google.registry.config.RegistryConfig.getHibernateLogSqlQueries;
import com.google.api.client.auth.oauth2.Credential;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
@@ -29,8 +30,10 @@ import dagger.Module;
import dagger.Provides;
import google.registry.config.RegistryConfig.Config;
import google.registry.keyring.kms.KmsKeyring;
import google.registry.persistence.transaction.CloudSqlCredentialSupplier;
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.persistence.transaction.JpaTransactionManagerImpl;
import google.registry.tools.AuthModule.CloudSqlClientCredential;
import google.registry.util.Clock;
import java.lang.annotation.Documented;
import java.util.HashMap;
@@ -118,7 +121,9 @@ public class PersistenceModule {
@Config("toolsCloudSqlUsername") String username,
KmsKeyring kmsKeyring,
@PartialCloudSqlConfigs ImmutableMap<String, String> cloudSqlConfigs,
@CloudSqlClientCredential Credential credential,
Clock clock) {
CloudSqlCredentialSupplier.setupCredentialSupplier(credential);
HashMap<String, String> overrides = Maps.newHashMap(cloudSqlConfigs);
overrides.put(Environment.USER, username);
overrides.put(Environment.PASS, kmsKeyring.getToolsCloudSqlPassword());
@@ -158,7 +163,7 @@ public class PersistenceModule {
/** Dagger qualifier for {@link JpaTransactionManager} used for Nomulus tool. */
@Qualifier
@Documented
@interface NomulusToolJpaTm {}
public @interface NomulusToolJpaTm {}
/** Dagger qualifier for the partial Cloud SQL configs. */
@Qualifier
@@ -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;
@@ -52,17 +55,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.of(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.of(this.ofyKey);
}
}
@@ -0,0 +1,37 @@
// 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 javax.annotation.Nullable;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.joda.time.Duration;
/** JPA converter to for storing/retrieving {@link org.joda.time.DateTime} objects. */
@Converter(autoApply = true)
public class DurationConverter implements AttributeConverter<Duration, Long> {
@Override
@Nullable
public Long convertToDatabaseColumn(@Nullable Duration duration) {
return duration == null ? null : duration.getMillis();
}
@Override
@Nullable
public Duration convertToEntityAttribute(@Nullable Long dbData) {
return dbData == null ? null : new Duration(dbData);
}
}
@@ -0,0 +1,35 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.transaction;
import com.google.api.client.auth.oauth2.Credential;
import com.google.cloud.sql.CredentialFactory;
/** Supplier class to provide {@link Credential} for Cloud SQL library. */
public class CloudSqlCredentialSupplier implements CredentialFactory {
private static Credential credential;
/** Initialize the supplier with given credential json and scopes. */
public static void setupCredentialSupplier(Credential credential) {
System.setProperty(
CredentialFactory.CREDENTIAL_FACTORY_PROPERTY, CloudSqlCredentialSupplier.class.getName());
CloudSqlCredentialSupplier.credential = credential;
}
@Override
public Credential create() {
return credential;
}
}
@@ -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);
@@ -16,11 +16,9 @@ package google.registry.persistence.transaction;
import com.google.appengine.api.utils.SystemProperty;
import com.google.appengine.api.utils.SystemProperty.Environment.Value;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Suppliers;
import google.registry.model.ofy.DatastoreTransactionManager;
import google.registry.persistence.DaggerPersistenceComponent;
import google.registry.tools.RegistryToolEnvironment;
import google.registry.util.NonFinalForTesting;
import java.util.function.Supplier;
@@ -38,11 +36,10 @@ public class TransactionManagerFactory {
private TransactionManagerFactory() {}
private static JpaTransactionManager createJpaTransactionManager() {
// If we are running a nomulus command, jpaTm will be injected in RegistryCli.java
// by calling setJpaTm().
if (isInAppEngine()) {
return DaggerPersistenceComponent.create().appEngineJpaTransactionManager();
} else if (RegistryToolEnvironment.isInRegistryTool()
&& RegistryToolEnvironment.isJpaTmEnabled()) {
return DaggerPersistenceComponent.create().nomulusToolJpaTransactionManager();
} else {
return DummyJpaTransactionManager.create();
}
@@ -78,8 +75,8 @@ public class TransactionManagerFactory {
return jpaTm.get();
}
@VisibleForTesting
static void setJpaTmForTesting(JpaTransactionManager newJpaTm) {
/** Sets the return of {@link #jpaTm()} to the given instance of {@link JpaTransactionManager}. */
public static void setJpaTm(JpaTransactionManager newJpaTm) {
jpaTm = Suppliers.ofInstance(newJpaTm);
}
}
@@ -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));
}
@@ -26,6 +26,7 @@ import google.registry.model.UpdateAutoTimestamp;
import google.registry.util.DateTimeUtils;
import java.time.ZonedDateTime;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -37,6 +38,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.joda.time.DateTime;
import org.joda.time.Duration;
/**
* Represents a registry lock/unlock object, meaning that the domain is locked on the registry
@@ -131,6 +133,9 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
@JoinColumn(name = "relockRevisionId", referencedColumnName = "revisionId")
private RegistryLock relock;
/** The duration after which we will re-lock this domain after it is unlocked. */
private Duration relockDuration;
/** Time that this entity was last updated. */
private UpdateAutoTimestamp lastUpdateTimestamp;
@@ -197,6 +202,11 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
return relock;
}
/** The duration after which we will re-lock this domain after it is unlocked. */
public Optional<Duration> getRelockDuration() {
return Optional.ofNullable(relockDuration);
}
public boolean isLocked() {
return lockCompletionTimestamp != null && unlockCompletionTimestamp == null;
}
@@ -289,5 +299,10 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
getInstance().relock = relock;
return this;
}
public Builder setRelockDuration(@Nullable Duration relockDuration) {
getInstance().relockDuration = relockDuration;
return this;
}
}
}
@@ -18,18 +18,22 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.schema.server.Lock.GLOBAL;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.flogger.FluentLogger;
import google.registry.schema.server.Lock.LockId;
import google.registry.util.DateTimeUtils;
import java.util.Optional;
/** Data access object class for {@link Lock}. */
public class LockDao {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
/** Saves the {@link Lock} object to Cloud SQL. */
public static void saveNew(Lock lock) {
public static void save(Lock lock) {
jpaTm()
.transact(
() -> {
jpaTm().getEntityManager().persist(lock);
jpaTm().getEntityManager().merge(lock);
});
}
@@ -76,4 +80,57 @@ public class LockDao {
public static void delete(String resourceName) {
delete(resourceName, GLOBAL);
}
/**
* Compares a {@link google.registry.model.server.Lock} object with a {@link Lock} object, logging
* a warning if there are any differences.
*/
public static void compare(
Optional<google.registry.model.server.Lock> datastoreLockOptional,
Optional<Lock> cloudSqlLockOptional) {
if (!datastoreLockOptional.isPresent()) {
cloudSqlLockOptional.ifPresent(
value ->
logger.atWarning().log(
String.format(
"Cloud SQL lock for %s with tld %s should be null",
value.resourceName, value.tld)));
return;
}
google.registry.schema.server.Lock cloudSqlLock;
google.registry.model.server.Lock datastoreLock = datastoreLockOptional.get();
if (cloudSqlLockOptional.isPresent()) {
cloudSqlLock = cloudSqlLockOptional.get();
if (!datastoreLock.getRequestLogId().equals(cloudSqlLock.requestLogId)) {
logger.atWarning().log(
String.format(
"Datastore lock requestLogId of %s does not equal Cloud SQL lock requestLogId of"
+ " %s",
datastoreLock.getRequestLogId(), cloudSqlLock.requestLogId));
}
if (!datastoreLock
.getAcquiredTime()
.equals(DateTimeUtils.toJodaDateTime(cloudSqlLock.acquiredTime))) {
logger.atWarning().log(
String.format(
"Datastore lock acquiredTime of %s does not equal Cloud SQL lock acquiredTime of"
+ " %s",
datastoreLock.getAcquiredTime(),
DateTimeUtils.toJodaDateTime(cloudSqlLock.acquiredTime)));
}
if (!datastoreLock
.getExpirationTime()
.equals(DateTimeUtils.toJodaDateTime(cloudSqlLock.expirationTime))) {
logger.atWarning().log(
String.format(
"Datastore lock expirationTime of %s does not equal Cloud SQL lock expirationTime"
+ " of %s",
datastoreLock.getExpirationTime(),
DateTimeUtils.toJodaDateTime(cloudSqlLock.expirationTime)));
}
} else {
logger.atWarning().log(
String.format("Datastore lock: %s was not found in Cloud SQL", datastoreLock));
}
}
}
@@ -20,6 +20,7 @@ import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.Details;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.AbstractDataStoreFactory;
@@ -42,6 +43,7 @@ import google.registry.util.GoogleCredentialsBundle;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -92,6 +94,26 @@ public class AuthModule {
}
}
// TODO(b/138195359): Deprecate this credential once Cloud SQL socket library uses the new auth
// library.
@Provides
@CloudSqlClientCredential
public static Credential providesLocalCredentialForCloudSqlClient(
@LocalCredentialJson String credentialJson,
@Config("localCredentialOauthScopes") ImmutableList<String> credentialScopes) {
try {
GoogleCredential credential =
GoogleCredential.fromStream(new ByteArrayInputStream(credentialJson.getBytes(UTF_8)));
if (credential.createScopedRequired()) {
credential = credential.createScoped(credentialScopes);
}
return credential;
} catch (IOException e) {
throw new UncheckedIOException(
"Error occurred while creating a GoogleCredential for Cloud SQL client", e);
}
}
@Provides
public static GoogleAuthorizationCodeFlow provideAuthorizationCodeFlow(
JsonFactory jsonFactory,
@@ -184,6 +206,11 @@ public class AuthModule {
@Retention(RetentionPolicy.RUNTIME)
private @interface StoredCredential {}
/** Dagger qualifier for {@link Credential} used by the Cloud SQL client in the nomulus tool. */
@Qualifier
@Documented
public @interface CloudSqlClientCredential {}
/** Dagger qualifier for the credential qualifier consisting of client and scopes. */
@Qualifier
@Documented
@@ -37,6 +37,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.
@@ -76,12 +77,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. */
@@ -166,14 +167,14 @@ public final class DomainLockUtils {
* Nomulus tool commands.
*/
public RegistryLock administrativelyApplyUnlock(
String domainName, String registrarId, boolean isAdmin) {
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin)
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
@@ -217,7 +218,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 +259,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)
@@ -78,11 +78,15 @@ final class RegistrarContactCommand extends MutatingCommand {
private List<String> contactTypeNames;
@Nullable
@Parameter(
names = "--email",
description = "Contact email address.")
@Parameter(names = "--email", description = "Contact email address.")
String email;
@Nullable
@Parameter(
names = "--registry_lock_email",
description = "Email address used for registry lock confirmation emails")
String registryLockEmail;
@Nullable
@Parameter(
names = "--phone",
@@ -247,6 +251,9 @@ final class RegistrarContactCommand extends MutatingCommand {
builder.setParent(registrar);
builder.setName(name);
builder.setEmailAddress(email);
if (!isNullOrEmpty(registryLockEmail)) {
builder.setRegistryLockEmailAddress(registryLockEmail);
}
if (phone != null) {
builder.setPhoneNumber(phone.orElse(null));
}
@@ -277,14 +284,14 @@ final class RegistrarContactCommand extends MutatingCommand {
private RegistrarContact updateContact(RegistrarContact contact, Registrar registrar) {
checkNotNull(registrar);
checkNotNull(email, "--email is required when --mode=UPDATE");
RegistrarContact.Builder builder = contact.asBuilder();
builder.setParent(registrar);
checkArgument(!isNullOrEmpty(email), "--email is required when --mode=UPDATE");
RegistrarContact.Builder builder =
contact.asBuilder().setEmailAddress(email).setParent(registrar);
if (!isNullOrEmpty(name)) {
builder.setName(name);
}
if (!isNullOrEmpty(email)) {
builder.setEmailAddress(email);
if (!isNullOrEmpty(registryLockEmail)) {
builder.setRegistryLockEmailAddress(registryLockEmail);
}
if (phone != null) {
builder.setPhoneNumber(phone.orElse(null));
@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import google.registry.config.RegistryConfig;
import google.registry.model.ofy.ObjectifyService;
import google.registry.persistence.transaction.TransactionManagerFactory;
import google.registry.tools.AuthModule.LoginRequiredException;
import google.registry.tools.params.ParameterFactory;
import java.io.ByteArrayInputStream;
@@ -237,7 +238,7 @@ final class RegistryCli implements AutoCloseable, CommandRunner {
// Enable Cloud SQL for command that needs remote API as they will very likely use
// Cloud SQL after the database migration. Note that the DB password is stored in Datastore
// and it is already initialized above.
RegistryToolEnvironment.enableJpaTm();
TransactionManagerFactory.setJpaTm(component.nomulusToolJpaTransactionManager());
}
command.run();
@@ -27,6 +27,9 @@ import google.registry.keyring.KeyringModule;
import google.registry.keyring.api.DummyKeyringModule;
import google.registry.keyring.api.KeyModule;
import google.registry.keyring.kms.KmsModule;
import google.registry.persistence.PersistenceModule;
import google.registry.persistence.PersistenceModule.NomulusToolJpaTm;
import google.registry.persistence.transaction.JpaTransactionManager;
import google.registry.rde.RdeModule;
import google.registry.request.Modules.DatastoreServiceModule;
import google.registry.request.Modules.Jackson2Module;
@@ -63,6 +66,7 @@ import javax.inject.Singleton;
KeyringModule.class,
KmsModule.class,
LocalCredentialModule.class,
PersistenceModule.class,
RdeModule.class,
RequestFactoryModule.class,
URLFetchServiceModule.class,
@@ -70,7 +74,7 @@ import javax.inject.Singleton;
UserServiceModule.class,
UtilsModule.class,
VoidDnsWriterModule.class,
WhoisModule.class,
WhoisModule.class
})
interface RegistryToolComponent {
void inject(AckPollMessagesCommand command);
@@ -117,6 +121,9 @@ interface RegistryToolComponent {
@LocalCredentialJson
String googleCredentialJson();
@NomulusToolJpaTm
JpaTransactionManager nomulusToolJpaTransactionManager();
@Component.Builder
interface Builder {
@BindsInstance
@@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.config.RegistryEnvironment;
import google.registry.config.SystemPropertySetter;
import google.registry.persistence.transaction.TransactionManagerFactory;
/** Enum of production environments, used for the {@code --environment} flag. */
public enum RegistryToolEnvironment {
@@ -40,7 +39,6 @@ public enum RegistryToolEnvironment {
private static final ImmutableList<String> FLAGS = ImmutableList.of("-e", "--environment");
private static RegistryToolEnvironment instance;
private static boolean isJpaTmEnabled = false;
private final RegistryEnvironment actualEnvironment;
private final ImmutableMap<String, String> extraProperties;
@@ -100,26 +98,6 @@ public enum RegistryToolEnvironment {
}
}
/** Returns true if the RegistryToolEnvironment is set up. */
public static boolean isInRegistryTool() {
return instance != null;
}
/**
* Sets the flag to indicate that the running command needs JpaTransactionManager to be enabled.
*/
public static void enableJpaTm() {
isJpaTmEnabled = true;
}
/**
* Returns true if the JpaTransactionManager is enabled. Note that JpaTm is actually enabled in
* {@link TransactionManagerFactory} by reading this flag.
*/
public static boolean isJpaTmEnabled() {
return isJpaTmEnabled;
}
/** Extracts value from command-line arguments associated with any {@code flags}. */
private static String getFlagValue(String[] args, Iterable<String> flags) {
for (String flag : flags) {
@@ -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());
}
}
@@ -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;
@@ -184,6 +185,11 @@ public final class RegistrarFormFields {
.required()
.build();
public static final FormField<String, String> REGISTRY_LOCK_EMAIL_ADDRESS_FIELD =
FormFields.EMAIL
.asBuilderNamed("registryLockEmailAddress")
.build();
public static final FormField<Boolean, Boolean> CONTACT_VISIBLE_IN_WHOIS_AS_ADMIN_FIELD =
FormField.named("visibleInWhoisAsAdmin", Boolean.class)
.build();
@@ -377,6 +383,8 @@ public final class RegistrarFormFields {
RegistrarContact.Builder builder, Map<String, ?> args) {
builder.setName(CONTACT_NAME_FIELD.extractUntyped(args).orElse(null));
builder.setEmailAddress(CONTACT_EMAIL_ADDRESS_FIELD.extractUntyped(args).orElse(null));
builder.setRegistryLockEmailAddress(
REGISTRY_LOCK_EMAIL_ADDRESS_FIELD.extractUntyped(args).orElse(null));
builder.setVisibleInWhoisAsAdmin(
CONTACT_VISIBLE_IN_WHOIS_AS_ADMIN_FIELD.extractUntyped(args).orElse(false));
builder.setVisibleInWhoisAsTech(
@@ -398,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);
}
});
@@ -41,9 +41,9 @@ import google.registry.request.auth.Auth;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
import google.registry.request.auth.UserAuthInfo;
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;
@@ -117,41 +117,65 @@ public final class RegistryLockGetAction implements JsonGetAction {
}
}
private ImmutableMap<String, ?> getLockedDomainsMap(String clientId)
throws RegistrarAccessDeniedException {
// Note: admins always have access to the locks page
checkArgument(authResult.userAuthInfo().isPresent(), "User auth info must be present");
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
boolean isAdmin = registrarAccessor.isAdmin();
Registrar registrar = getRegistrarAndVerifyLockAccess(clientId, isAdmin);
User user = userAuthInfo.user();
boolean isRegistryLockAllowed =
isAdmin
|| registrar.getContacts().stream()
.filter(contact -> contact.getEmailAddress().equals(user.getEmail()))
.findFirst()
.map(RegistrarContact::isRegistryLockAllowed)
.orElse(false);
return ImmutableMap.of(
LOCK_ENABLED_FOR_CONTACT_PARAM,
isRegistryLockAllowed,
EMAIL_PARAM,
user.getEmail(),
PARAM_CLIENT_ID,
registrar.getClientId(),
LOCKS_PARAM,
getLockedDomains(clientId, isAdmin));
static Optional<RegistrarContact> getContactMatchingLogin(User user, Registrar registrar) {
ImmutableList<RegistrarContact> matchingContacts =
registrar.getContacts().stream()
.filter(contact -> contact.getGaeUserId() != null)
.filter(contact -> Objects.equals(contact.getGaeUserId(), user.getUserId()))
.collect(toImmutableList());
if (matchingContacts.size() > 1) {
ImmutableList<String> matchingEmails =
matchingContacts.stream()
.map(RegistrarContact::getEmailAddress)
.collect(toImmutableList());
throw new IllegalArgumentException(
String.format(
"User ID %s had multiple matching contacts with email addresses %s",
user.getUserId(), matchingEmails));
}
return matchingContacts.stream().findFirst();
}
private Registrar getRegistrarAndVerifyLockAccess(String clientId, boolean isAdmin)
static Registrar getRegistrarAndVerifyLockAccess(
AuthenticatedRegistrarAccessor registrarAccessor, String clientId, boolean isAdmin)
throws RegistrarAccessDeniedException {
Registrar registrar = registrarAccessor.getRegistrar(clientId);
checkArgument(
isAdmin || registrar.isRegistryLockAllowed(),
"Registry lock not allowed for this registrar");
"Registry lock not allowed for registrar %s",
clientId);
return registrar;
}
private ImmutableMap<String, ?> getLockedDomainsMap(String clientId)
throws RegistrarAccessDeniedException {
// Note: admins always have access to the locks page
checkArgument(authResult.userAuthInfo().isPresent(), "User auth info must be present");
boolean isAdmin = registrarAccessor.isAdmin();
Registrar registrar = getRegistrarAndVerifyLockAccess(registrarAccessor, clientId, isAdmin);
User user = authResult.userAuthInfo().get().user();
Optional<RegistrarContact> contactOptional = getContactMatchingLogin(user, registrar);
boolean isRegistryLockAllowed =
isAdmin || contactOptional.map(RegistrarContact::isRegistryLockAllowed).orElse(false);
// Use the contact's registry lock email if it's present, else use the login email (for admins)
String relevantEmail =
isAdmin
? user.getEmail()
// if the contact isn't present, we shouldn't display the email anyway so empty is fine
: contactOptional.flatMap(RegistrarContact::getRegistryLockEmailAddress).orElse("");
return ImmutableMap.of(
LOCK_ENABLED_FOR_CONTACT_PARAM,
isRegistryLockAllowed,
EMAIL_PARAM,
relevantEmail,
PARAM_CLIENT_ID,
registrar.getClientId(),
LOCKS_PARAM,
getLockedDomains(clientId, isAdmin));
}
private ImmutableList<ImmutableMap<String, ?>> getLockedDomains(
String clientId, boolean isAdmin) {
return jpaTm()
@@ -20,8 +20,11 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static google.registry.security.JsonResponseHelper.Status.ERROR;
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
import static google.registry.ui.server.registrar.RegistrarConsoleModule.PARAM_CLIENT_ID;
import static google.registry.ui.server.registrar.RegistryLockGetAction.getContactMatchingLogin;
import static google.registry.ui.server.registrar.RegistryLockGetAction.getRegistrarAndVerifyLockAccess;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.appengine.api.users.User;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
@@ -53,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
@@ -124,11 +128,7 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
.userAuthInfo()
.orElseThrow(() -> new ForbiddenException("User is not logged in"));
boolean isAdmin = userAuthInfo.isUserAdmin();
String userEmail = userAuthInfo.user().getEmail();
if (!isAdmin) {
verifyRegistryLockPassword(postInput, userEmail);
}
String userEmail = verifyPasswordAndGetEmail(userAuthInfo, postInput);
jpaTm()
.transact(
() -> {
@@ -138,9 +138,12 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
postInput.fullyQualifiedDomainName,
postInput.clientId,
userEmail,
isAdmin)
registrarAccessor.isAdmin())
: domainLockUtils.saveNewRegistryUnlockRequest(
postInput.fullyQualifiedDomainName, postInput.clientId, isAdmin);
postInput.fullyQualifiedDomainName,
postInput.clientId,
registrarAccessor.isAdmin(),
Optional.ofNullable(postInput.relockDurationMillis).map(Duration::new));
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
});
String action = postInput.isLock ? "lock" : "unlock";
@@ -180,25 +183,35 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
}
}
private void verifyRegistryLockPassword(RegistryLockPostInput postInput, String userEmail)
private String verifyPasswordAndGetEmail(
UserAuthInfo userAuthInfo, RegistryLockPostInput postInput)
throws RegistrarAccessDeniedException {
// Verify that the user can access the registrar and that the user has
// registry lock enabled and provided a correct password
Registrar registrar = registrarAccessor.getRegistrar(postInput.clientId);
checkArgument(
registrar.isRegistryLockAllowed(), "Registry lock not allowed for this registrar");
checkArgument(!Strings.isNullOrEmpty(postInput.password), "Missing key for password");
User user = userAuthInfo.user();
if (registrarAccessor.isAdmin()) {
return user.getEmail();
}
// Verify that the user can access the registrar, that the user has
// registry lock enabled, and that the user providjed a correct password
Registrar registrar =
getRegistrarAndVerifyLockAccess(registrarAccessor, postInput.clientId, false);
RegistrarContact registrarContact =
registrar.getContacts().stream()
.filter(contact -> contact.getEmailAddress().equals(userEmail))
.findFirst()
getContactMatchingLogin(user, registrar)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format("Unknown user email %s", userEmail)));
String.format(
"Cannot match user %s to registrar contact", user.getUserId())));
checkArgument(
registrarContact.verifyRegistryLockPassword(postInput.password),
"Incorrect registry lock password for contact");
return registrarContact
.getRegistryLockEmailAddress()
.orElseThrow(
() ->
new IllegalStateException(
String.format(
"Contact %s had no registry lock email address",
registrarContact.getEmailAddress())));
}
/** Value class that represents the expected input body from the UI request. */
@@ -207,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,8 @@ 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;
goog.net.XhrIo.send('/registry-lock-post',
e => this.fillLocksPage_(e),
'POST',
@@ -38,6 +38,7 @@
<class>google.registry.persistence.converter.CreateAutoTimestampConverter</class>
<class>google.registry.persistence.converter.CurrencyUnitConverter</class>
<class>google.registry.persistence.converter.DateTimeConverter</class>
<class>google.registry.persistence.converter.DurationConverter</class>
<class>google.registry.persistence.converter.RegistrarPocSetConverter</class>
<class>google.registry.persistence.converter.StatusValueSetConverter</class>
<class>google.registry.persistence.converter.StringListConverter</class>
@@ -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)}
@@ -614,7 +614,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 +684,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 +943,7 @@ public class DeleteContactsAndHostsActionTest
return persistResource(
newDomainBase(domainName, contact)
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
}
@@ -40,6 +40,7 @@ import google.registry.testing.FakeResponse;
import google.registry.testing.UserInfo;
import google.registry.tools.DomainLockUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -79,7 +80,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());
}
@@ -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));
@@ -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();
@@ -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();
}
}
@@ -30,6 +30,7 @@ import google.registry.schema.domain.RegistryLock;
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;
@@ -88,12 +89,14 @@ public final class RegistryLockDaoTest {
.setLockCompletionTimestamp(fakeClock.nowUtc())
.setUnlockRequestTimestamp(fakeClock.nowUtc())
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
.setRelockDuration(Duration.standardHours(6))
.build());
RegistryLock fromDatabase = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
assertThat(fromDatabase.getUnlockRequestTimestamp()).isEqualTo(Optional.of(fakeClock.nowUtc()));
assertThat(fromDatabase.getUnlockCompletionTimestamp())
.isEqualTo(Optional.of(fakeClock.nowUtc()));
assertThat(fromDatabase.isLocked()).isFalse();
assertThat(fromDatabase.getRelockDuration().get()).isEqualTo(Duration.standardHours(6));
}
@Test
@@ -29,21 +29,20 @@ 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.migrationsupport.rules.EnableRuleMigrationSupport;
/** Unit tests for {@link PremiumList}. */
@RunWith(JUnit4.class)
@EnableRuleMigrationSupport
public class PremiumListTest {
@Rule
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 +56,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 +81,7 @@ public class PremiumListTest {
}
@Test
public void testParse_cannotIncludeDuplicateLabels() {
void testParse_cannotIncludeDuplicateLabels() {
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
@@ -103,7 +102,7 @@ public class PremiumListTest {
}
@Test
public void testValidation_labelMustBeLowercase() {
void testValidation_labelMustBeLowercase() {
Exception e =
assertThrows(
IllegalArgumentException.class,
@@ -116,7 +115,7 @@ public class PremiumListTest {
}
@Test
public void testValidation_labelMustBePunyCoded() {
void testValidation_labelMustBePunyCoded() {
Exception e =
assertThrows(
IllegalArgumentException.class,
@@ -11,6 +11,7 @@
// 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.truth.Truth.assertThat;
@@ -0,0 +1,80 @@
// 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.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.math.BigInteger;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.Duration;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link DurationConverter}. */
@RunWith(JUnit4.class)
public class DurationConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
private final DurationConverter converter = new DurationConverter();
@Test
public void testNulls() {
assertThat(converter.convertToDatabaseColumn(null)).isNull();
assertThat(converter.convertToEntityAttribute(null)).isNull();
}
@Test
public void testRoundTrip() {
TestEntity entity = new TestEntity(Duration.standardDays(6));
jpaTm().transact(() -> jpaTm().getEntityManager().persist(entity));
assertThat(
jpaTm()
.transact(
() ->
jpaTm()
.getEntityManager()
.createNativeQuery(
"SELECT duration FROM \"TestEntity\" WHERE name = 'id'")
.getResultList()))
.containsExactly(BigInteger.valueOf(Duration.standardDays(6).getMillis()));
TestEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.duration).isEqualTo(Duration.standardDays(6));
}
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
public static class TestEntity extends ImmutableObject {
@Id String name = "id";
Duration duration;
public TestEntity() {}
TestEntity(Duration duration) {
this.duration = duration;
}
}
}
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import google.registry.persistence.PersistenceXmlUtility;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -96,18 +97,34 @@ public class JpaEntityCoverage extends ExternalResource {
* @return true if an instance of {@code entityType} is found in the database and can be read
*/
private static boolean isPersisted(Class entityType) {
List result =
jpaTm()
.transact(
() ->
jpaTm()
.getEntityManager()
.createQuery(
String.format("SELECT e FROM %s e", getJpaEntityName(entityType)),
entityType)
.setMaxResults(1)
.getResultList());
return !result.isEmpty() && entityType.isInstance(result.get(0));
try {
List result =
jpaTm()
.transact(
() ->
jpaTm()
.getEntityManager()
.createQuery(
String.format("SELECT e FROM %s e", getJpaEntityName(entityType)),
entityType)
.setMaxResults(1)
.getResultList());
return !result.isEmpty() && entityType.isInstance(result.get(0));
} catch (RuntimeException e) {
// See if this was caused by a "relation does not exist" error.
Throwable cause = e;
while ((cause = cause.getCause()) != null) {
if (cause instanceof SQLException
&& cause.getMessage().matches("(?s).*relation .* does not exist.*")) {
throw new RuntimeException(
"SQLException occurred. If you've updated the set of entities, make sure you've "
+ "also updated the golden schema. See db/README.md for details.",
e);
}
}
throw e;
}
}
private static String getJpaEntityName(Class entityType) {
@@ -14,13 +14,16 @@
package google.registry.persistence.transaction;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.testcontainers.containers.PostgreSQLContainer.POSTGRESQL_PORT;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Streams;
import com.google.common.io.Resources;
import google.registry.persistence.HibernateSchemaExporter;
import google.registry.persistence.NomulusPostgreSql;
@@ -40,6 +43,8 @@ import java.sql.Statement;
import java.util.HashMap;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.EntityManagerFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
@@ -62,7 +67,6 @@ import org.testcontainers.containers.PostgreSQLContainer;
abstract class JpaTransactionManagerRule extends ExternalResource {
private static final String DB_CLEANUP_SQL_PATH =
"google/registry/persistence/transaction/cleanup_database.sql";
private static final String MANAGEMENT_DB_NAME = "management";
private static final String POSTGRES_DB_NAME = "postgres";
// The type of JDBC connections started by the tests. This string value
// is documented in PSQL's official user guide.
@@ -78,8 +82,15 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
private static final HibernateSchemaExporter exporter =
HibernateSchemaExporter.create(
database.getJdbcUrl(), database.getUsername(), database.getPassword());
private EntityManagerFactory emf;
// The EntityManagerFactory for the current schema in the test db. This instance may be
// reused between test methods if the requested schema remains the same.
private static EntityManagerFactory emf;
// Hash of the ORM entity names in the current schema in the test db.
private static int emfEntityHash;
private JpaTransactionManager cachedTm;
// Hash of the ORM entity names requested by this rule instance.
private int entityHash;
protected JpaTransactionManagerRule(
Clock clock,
@@ -90,26 +101,45 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
this.initScriptPath = initScriptPath;
this.extraEntityClasses = extraEntityClasses;
this.userProperties = userProperties;
this.entityHash = getOrmEntityHash(initScriptPath, extraEntityClasses);
}
private static JdbcDatabaseContainer create() {
PostgreSQLContainer container =
new PostgreSQLContainer(NomulusPostgreSql.getDockerTag())
.withDatabaseName(MANAGEMENT_DB_NAME);
.withDatabaseName(POSTGRES_DB_NAME);
container.start();
return container;
}
@Override
public void before() throws Exception {
executeSql(MANAGEMENT_DB_NAME, readSqlInClassPath(DB_CLEANUP_SQL_PATH));
initScriptPath.ifPresent(path -> executeSql(POSTGRES_DB_NAME, readSqlInClassPath(path)));
private static int getOrmEntityHash(
Optional<String> initScriptPath, ImmutableList<Class> extraEntityClasses) {
return Streams.concat(
Stream.of(initScriptPath.orElse("")),
extraEntityClasses.stream().map(Class::getCanonicalName))
.sorted()
.collect(Collectors.toList())
.hashCode();
}
/**
* Drops and recreates the 'public' schema and all tables, then creates a new {@link
* EntityManagerFactory} and save it in {@link #emf}.
*/
private void recreateSchema() throws Exception {
if (emf != null) {
emf.close();
emf = null;
emfEntityHash = 0;
assertReasonableNumDbConnections();
}
executeSql(readSqlInClassPath(DB_CLEANUP_SQL_PATH));
initScriptPath.ifPresent(path -> executeSql(readSqlInClassPath(path)));
if (!extraEntityClasses.isEmpty()) {
File tempSqlFile = File.createTempFile("tempSqlFile", ".sql");
tempSqlFile.deleteOnExit();
exporter.export(extraEntityClasses, tempSqlFile);
executeSql(
POSTGRES_DB_NAME,
new String(Files.readAllBytes(tempSqlFile.toPath()), StandardCharsets.UTF_8));
}
@@ -126,25 +156,50 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
assertReasonableNumDbConnections();
emf =
createEntityManagerFactory(
getJdbcUrlFor(POSTGRES_DB_NAME),
getJdbcUrl(),
database.getUsername(),
database.getPassword(),
properties,
extraEntityClasses);
emfEntityHash = entityHash;
}
@Override
public void before() throws Exception {
if (entityHash == emfEntityHash) {
checkState(emf != null, "Missing EntityManagerFactory.");
resetTablesAndSequences();
} else {
recreateSchema();
}
JpaTransactionManagerImpl txnManager = new JpaTransactionManagerImpl(emf, clock);
cachedTm = TransactionManagerFactory.jpaTm();
TransactionManagerFactory.setJpaTmForTesting(txnManager);
TransactionManagerFactory.setJpaTm(txnManager);
}
@Override
public void after() {
TransactionManagerFactory.setJpaTmForTesting(cachedTm);
if (emf != null) {
emf.close();
emf = null;
}
TransactionManagerFactory.setJpaTm(cachedTm);
cachedTm = null;
assertReasonableNumDbConnections();
}
private void resetTablesAndSequences() {
try (Connection conn = createConnection();
Statement statement = conn.createStatement()) {
ResultSet rs =
statement.executeQuery(
"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';");
ImmutableList.Builder<String> tableNames = new ImmutableList.Builder<>();
while (rs.next()) {
tableNames.add('"' + rs.getString(1) + '"');
}
String sql =
String.format(
"TRUNCATE %s RESTART IDENTITY CASCADE", Joiner.on(',').join(tableNames.build()));
executeSql(sql);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
@@ -156,8 +211,7 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
* is less than 5 to reduce flakiness.
*/
private void assertReasonableNumDbConnections() {
// Use the 'management' db to connect so that this connection needs not to be accounted for.
try (Connection conn = createConnection(MANAGEMENT_DB_NAME);
try (Connection conn = createConnection();
Statement statement = conn.createStatement()) {
// Note: Since we use the admin user (returned by container's getUserName() method)
// in tests, we need to filter connections by database name and/or backend type to filter out
@@ -186,8 +240,8 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
}
}
private void executeSql(String dbName, String sqlScript) {
try (Connection conn = createConnection(dbName);
private static void executeSql(String sqlScript) {
try (Connection conn = createConnection();
Statement statement = conn.createStatement()) {
statement.execute(sqlScript);
} catch (Exception e) {
@@ -195,24 +249,24 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
}
}
private static String getJdbcUrlFor(String dbName) {
private static String getJdbcUrl() {
// Disable Postgres driver use of java.util.logging to reduce noise at startup time
return "jdbc:postgresql://"
+ database.getContainerIpAddress()
+ ":"
+ database.getMappedPort(POSTGRESQL_PORT)
+ "/"
+ dbName
+ POSTGRES_DB_NAME
+ "?loggerLevel=OFF";
}
private static Connection createConnection(String dbName) {
private static Connection createConnection() {
final Properties info = new Properties();
info.put("user", database.getUsername());
info.put("password", database.getPassword());
final Driver jdbcDriverInstance = database.getJdbcDriverInstance();
try {
return jdbcDriverInstance.connect(getJdbcUrlFor(dbName), info);
return jdbcDriverInstance.connect(getJdbcUrl(), info);
} catch (SQLException e) {
throw new RuntimeException(e);
}
@@ -229,6 +283,8 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
properties.put(Environment.URL, jdbcUrl);
properties.put(Environment.USER, username);
properties.put(Environment.PASS, password);
// Tell Postgresql JDBC driver to expect out-of-band schema change.
properties.put("hibernate.hikari.dataSource.autosave", "conservative");
ParsedPersistenceXmlDescriptor descriptor =
PersistenceXmlUtility.getParsedPersistenceXmlDescriptor();
@@ -45,6 +45,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.rdap.RdapMetrics.EndpointType;
import google.registry.rdap.RdapMetrics.SearchType;
import google.registry.rdap.RdapMetrics.WildcardType;
@@ -409,7 +410,7 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
private void createManyDomainsAndHosts(
int numActiveDomains, int numTotalDomainsPerActiveDomain, int numHosts) {
ImmutableSet.Builder<Key<HostResource>> hostKeysBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostKeysBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<String> subordinateHostnamesBuilder = new ImmutableSet.Builder<>();
String mainDomainName = String.format("domain%d.lol", numTotalDomainsPerActiveDomain);
for (int i = numHosts; i >= 1; i--) {
@@ -417,9 +418,9 @@ public class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDom
subordinateHostnamesBuilder.add(hostName);
HostResource host = makeAndPersistHostResource(
hostName, String.format("5.5.%d.%d", 5 + i / 250, i % 250), clock.nowUtc().minusYears(1));
hostKeysBuilder.add(Key.create(host));
hostKeysBuilder.add(host.createKey());
}
ImmutableSet<Key<HostResource>> hostKeys = hostKeysBuilder.build();
ImmutableSet<VKey<HostResource>> hostKeys = hostKeysBuilder.build();
// Create all the domains at once, then persist them in parallel, for increased efficiency.
ImmutableList.Builder<DomainBase> domainsBuilder = new ImmutableList.Builder<>();
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {
@@ -80,8 +80,8 @@ import org.junit.runners.JUnit4;
/**
* Unit tests for {@link DomainBaseToXjcConverter}.
*
* <p>This tests the mapping between {@link DomainBase} and {@link XjcRdeDomain} as well as
* some exceptional conditions.
* <p>This tests the mapping between {@link DomainBase} and {@link XjcRdeDomain} as well as some
* exceptional conditions.
*/
@RunWith(JUnit4.class)
public class DomainBaseToXjcConverterTest {
@@ -99,14 +99,12 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testConvertThick() {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
assertThat(bean.getClID()).isEqualTo("GetTheeBack");
assertThat(
bean.getContacts()
.stream()
bean.getContacts().stream()
.map(input -> String.format("%s %s", input.getType().toString(), input.getValue())))
.containsExactly("ADMIN 5372808-IRL", "TECH 5372808-TRL");
@@ -182,8 +180,7 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testConvertThin() {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
assertThat(bean.getRegistrant()).isNull();
assertThat(bean.getContacts()).isEmpty();
assertThat(bean.getSecDNS()).isNull();
@@ -191,15 +188,13 @@ public class DomainBaseToXjcConverterTest {
@Test
public void testMarshalThick() throws Exception {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.FULL);
wrapDeposit(bean).marshal(new ByteArrayOutputStream(), UTF_8);
}
@Test
public void testMarshalThin() throws Exception {
XjcRdeDomain bean =
DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
XjcRdeDomain bean = DomainBaseToXjcConverter.convertDomain(makeDomainBase(clock), RdeMode.THIN);
wrapDeposit(bean).marshal(new ByteArrayOutputStream(), UTF_8);
}
@@ -225,17 +220,18 @@ public class DomainBaseToXjcConverterTest {
newDomainBase("example.xn--q9jyb4c").asBuilder().setRepoId("2-Q9JYB4C").build();
HistoryEntry historyEntry =
persistResource(new HistoryEntry.Builder().setParent(domain).build());
BillingEvent.OneTime billingEvent = persistResource(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
BillingEvent.OneTime billingEvent =
persistResource(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1910-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
domain =
domain
.asBuilder()
@@ -272,11 +268,10 @@ public class DomainBaseToXjcConverterTest {
.setLastEppUpdateTime(DateTime.parse("1920-01-01T00:00:00Z"))
.setNameservers(
ImmutableSet.of(
Key.create(
makeHostResource(clock, "3-Q9JYB4C", "bird.or.devil.みんな", "1.2.3.4")),
Key.create(
makeHostResource(
clock, "4-Q9JYB4C", "ns2.cat.みんな", "bad:f00d:cafe::15:beef"))))
makeHostResource(clock, "3-Q9JYB4C", "bird.or.devil.みんな", "1.2.3.4")
.createKey(),
makeHostResource(clock, "4-Q9JYB4C", "ns2.cat.みんな", "bad:f00d:cafe::15:beef")
.createKey()))
.setRegistrant(
Key.create(
makeContactResource(
@@ -383,27 +378,24 @@ public class DomainBaseToXjcConverterTest {
.setPersistedCurrentSponsorClientId("GetTheeBack")
.setCreationClientId("GetTheeBack")
.setCreationTimeForTest(END_OF_TIME)
.setInternationalizedPostalInfo(new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("SINNERS INCORPORATED")
.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("SINNERS INCORPORATED")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.build())
.build())
.build())
.setRepoId(repoId)
.setVoiceNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660420")
.build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660421")
.build())
new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660420").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660421").build())
.build());
}
@@ -58,27 +58,30 @@ import org.joda.time.DateTime;
final class RdeFixtures {
static DomainBase makeDomainBase(FakeClock clock, String tld) {
DomainBase domain = new DomainBase.Builder()
.setFullyQualifiedDomainName("example." + tld)
.setRepoId(generateNewDomainRoid(tld))
.setRegistrant(Key.create(
makeContactResource(clock,
"5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")))
.build();
DomainBase domain =
new DomainBase.Builder()
.setFullyQualifiedDomainName("example." + tld)
.setRepoId(generateNewDomainRoid(tld))
.setRegistrant(
Key.create(
makeContactResource(
clock, "5372808-ERL", "(◕‿◕) nevermore", "prophet@evil.みんな")))
.build();
HistoryEntry historyEntry =
persistResource(new HistoryEntry.Builder().setParent(domain).build());
clock.advanceOneMilli();
BillingEvent.OneTime billingEvent = persistResourceWithCommitLog(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
BillingEvent.OneTime billingEvent =
persistResourceWithCommitLog(
new BillingEvent.OneTime.Builder()
.setReason(Reason.CREATE)
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
.setCost(Money.of(USD, 26))
.setPeriodYears(2)
.setEventTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setBillingTime(DateTime.parse("1990-01-01T00:00:00Z"))
.setParent(historyEntry)
.build());
domain =
domain
.asBuilder()
@@ -114,8 +117,8 @@ final class RdeFixtures {
.setIdnTableName("extended_latin")
.setNameservers(
ImmutableSet.of(
Key.create(makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4")),
Key.create(makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef"))))
makeHostResource(clock, "bird.or.devil.みんな", "1.2.3.4").createKey(),
makeHostResource(clock, "ns2.cat.みんな", "bad:f00d:cafe::15:beef").createKey()))
.setRegistrationExpirationTime(DateTime.parse("1994-01-01T00:00:00Z"))
.setGracePeriods(
ImmutableSet.of(
@@ -220,26 +223,23 @@ final class RdeFixtures {
.setPersistedCurrentSponsorClientId("GetTheeBack")
.setCreationClientId("GetTheeBack")
.setCreationTimeForTest(clock.nowUtc())
.setInternationalizedPostalInfo(new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("DOGE INCORPORATED")
.setAddress(new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
.setOrg("DOGE INCORPORATED")
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Example Boulevard"))
.setCity("KOKOMO")
.setState("BM")
.setZip("31337")
.setCountryCode("US")
.build())
.build())
.build())
.setVoiceNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.5558675309")
.build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.5558675310")
.build())
new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675309").build())
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.5558675310").build())
.build());
}
@@ -35,7 +35,6 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType;
import com.googlecode.objectify.Key;
import google.registry.model.domain.DomainBase;
import google.registry.model.host.HostResource;
import google.registry.reporting.spec11.soy.Spec11EmailSoyInfo;
@@ -375,7 +374,9 @@ public class Spec11EmailUtilsTest {
private static DomainBase persistDomainWithHost(String domainName, HostResource host) {
return persistResource(
newDomainBase(domainName).asBuilder().setNameservers(ImmutableSet.of(Key.create(host)))
newDomainBase(domainName)
.asBuilder()
.setNameservers(ImmutableSet.of(host.createKey()))
.build());
}
}
@@ -15,13 +15,15 @@
package google.registry.schema.server;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import com.google.common.testing.TestLogHandler;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
import google.registry.testing.FakeClock;
import java.util.Optional;
import javax.persistence.RollbackException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.joda.time.Duration;
import org.junit.Rule;
import org.junit.Test;
@@ -33,6 +35,8 @@ import org.junit.runners.JUnit4;
public class LockDaoTest {
private final FakeClock fakeClock = new FakeClock();
private final TestLogHandler logHandler = new TestLogHandler();
private final Logger loggerToIntercept = Logger.getLogger(LockDao.class.getCanonicalName());
@Rule
public final JpaIntegrationWithCoverageRule jpaRule =
@@ -42,29 +46,28 @@ public class LockDaoTest {
public void save_worksSuccessfully() {
Lock lock =
Lock.create("testResource", "tld", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource", "tld");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
assertThat(returnedLock.get().requestLogId).isEqualTo(lock.requestLogId);
}
@Test
public void save_failsWhenLockAlreadyExists() {
public void save_succeedsWhenLockAlreadyExists() {
Lock lock =
Lock.create("testResource", "tld", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Lock lock2 =
Lock.create("testResource", "tld", "testLogId2", fakeClock.nowUtc(), Duration.millis(4));
RollbackException thrown = assertThrows(RollbackException.class, () -> LockDao.saveNew(lock2));
assertThat(thrown.getCause().getCause().getCause().getMessage())
.contains("duplicate key value violates unique constraint");
LockDao.save(lock2);
assertThat(LockDao.load("testResource", "tld").get().requestLogId).isEqualTo("testLogId2");
}
@Test
public void save_worksSuccesfullyGlobalLock() {
Lock lock =
Lock.createGlobal("testResource", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
assertThat(returnedLock.get().requestLogId).isEqualTo(lock.requestLogId);
@@ -74,7 +77,7 @@ public class LockDaoTest {
public void load_worksSuccessfully() {
Lock lock =
Lock.create("testResource", "tld", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource", "tld");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
assertThat(returnedLock.get().requestLogId).isEqualTo(lock.requestLogId);
@@ -84,7 +87,7 @@ public class LockDaoTest {
public void load_worksSuccessfullyGlobalLock() {
Lock lock =
Lock.createGlobal("testResource", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
assertThat(returnedLock.get().requestLogId).isEqualTo(lock.requestLogId);
@@ -100,7 +103,7 @@ public class LockDaoTest {
public void delete_worksSuccesfully() {
Lock lock =
Lock.create("testResource", "tld", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource", "tld");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
LockDao.delete("testResource", "tld");
@@ -112,7 +115,7 @@ public class LockDaoTest {
public void delete_worksSuccessfullyGlobalLock() {
Lock lock =
Lock.createGlobal("testResource", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.saveNew(lock);
LockDao.save(lock);
Optional<Lock> returnedLock = LockDao.load("testResource");
assertThat(returnedLock.get().expirationTime).isEqualTo(lock.expirationTime);
LockDao.delete("testResource");
@@ -124,4 +127,63 @@ public class LockDaoTest {
public void delete_succeedsLockDoesntExist() {
LockDao.delete("testResource");
}
@Test
public void compare_logsWarningWhenCloudSqlLockMissing() {
loggerToIntercept.addHandler(logHandler);
google.registry.model.server.Lock datastoreLock =
google.registry.model.server.Lock.create(
"resourceName", "tld", "id", fakeClock.nowUtc(), Duration.millis(2));
LockDao.compare(Optional.of(datastoreLock), Optional.empty());
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
String.format("Datastore lock: %s was not found in Cloud SQL", datastoreLock));
}
@Test
public void compare_logsWarningWhenCloudSqlLockExistsWhenItShouldNot() {
loggerToIntercept.addHandler(logHandler);
Lock lock =
Lock.createGlobal("testResource", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
LockDao.compare(Optional.ofNullable(null), Optional.of(lock));
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
String.format("Cloud SQL lock for testResource with tld GLOBAL should be null"));
}
@Test
public void compare_logsWarningWhenLocksDontMatch() {
loggerToIntercept.addHandler(logHandler);
Lock cloudSqlLock =
Lock.create("testResource", "tld", "testLogId", fakeClock.nowUtc(), Duration.millis(2));
google.registry.model.server.Lock datastoreLock =
google.registry.model.server.Lock.create(
"testResource", "tld", "wrong", fakeClock.nowUtc().minusDays(1), Duration.millis(3));
LockDao.compare(Optional.of(datastoreLock), Optional.of(cloudSqlLock));
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
String.format(
"Datastore lock requestLogId of wrong does not equal Cloud SQL lock requestLogId"
+ " of testLogId"));
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
String.format(
"Datastore lock acquiredTime of 1969-12-31T00:00:00.000Z does not equal Cloud SQL"
+ " lock acquiredTime of 1970-01-01T00:00:00.000Z"));
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
Level.WARNING,
String.format(
"Datastore lock expirationTime of 1969-12-31T00:00:00.003Z does not equal Cloud"
+ " SQL lock expirationTime of 1970-01-01T00:00:00.002Z"));
}
}
@@ -123,28 +123,34 @@ public enum Fixture {
.build());
persistResource(
newDomainBase("love.xn--q9jyb4c", justine).asBuilder()
.setContacts(ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(ImmutableSet.of(
Key.create(persistActiveHost("ns1.love.xn--q9jyb4c")),
Key.create(persistActiveHost("ns2.love.xn--q9jyb4c"))))
newDomainBase("love.xn--q9jyb4c", justine)
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.love.xn--q9jyb4c").createKey(),
persistActiveHost("ns2.love.xn--q9jyb4c").createKey()))
.build());
persistResource(
newDomainBase("moogle.example", justine).asBuilder()
.setContacts(ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(ImmutableSet.of(
Key.create(persistActiveHost("ns1.linode.com")),
Key.create(persistActiveHost("ns2.linode.com")),
Key.create(persistActiveHost("ns3.linode.com")),
Key.create(persistActiveHost("ns4.linode.com")),
Key.create(persistActiveHost("ns5.linode.com"))))
newDomainBase("moogle.example", justine)
.asBuilder()
.setContacts(
ImmutableSet.of(
DesignatedContact.create(ADMIN, Key.create(robert)),
DesignatedContact.create(BILLING, Key.create(google)),
DesignatedContact.create(TECH, Key.create(justine))))
.setNameservers(
ImmutableSet.of(
persistActiveHost("ns1.linode.com").createKey(),
persistActiveHost("ns2.linode.com").createKey(),
persistActiveHost("ns3.linode.com").createKey(),
persistActiveHost("ns4.linode.com").createKey(),
persistActiveHost("ns5.linode.com").createKey()))
.build());
persistResource(
@@ -19,7 +19,6 @@ import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.net.HostAndPort;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.testing.AppEngineRule;
import google.registry.testing.UserInfo;
import google.registry.tools.params.HostAndPortParameter;
@@ -63,7 +62,7 @@ public final class RegistryTestServerMain {
@Parameter(
names = "--login_user_id",
description = "GAE User ID for App Engine Local User Service.")
private String loginUserId = AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
private String loginUserId = AppEngineRule.MARLA_SINGER_GAE_USER_ID;
@Parameter(
names = "--login_is_admin",
@@ -156,23 +155,18 @@ public final class RegistryTestServerMain {
}
};
Statement withAppEngine =
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.withUrlFetch()
.withTaskQueue()
.withLocalModules()
.withUserService(
loginIsAdmin
? UserInfo.createAdmin(loginEmail, loginUserId)
: UserInfo.create(loginEmail, loginUserId))
.build()
.apply(runner, Description.EMPTY);
System.out.printf("%sLoading SQL fixtures and AppEngineRule...%s\n", BLUE, RESET);
new JpaTestRules.Builder()
.buildIntegrationTestRule()
.apply(withAppEngine, Description.EMPTY)
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.withUrlFetch()
.withTaskQueue()
.withLocalModules()
.withUserService(
loginIsAdmin
? UserInfo.createAdmin(loginEmail, loginUserId)
: UserInfo.create(loginEmail, loginUserId))
.build()
.apply(runner, Description.EMPTY)
.evaluate();
}
@@ -71,6 +71,7 @@ public final class AppEngineRule extends ExternalResource {
public static final String NEW_REGISTRAR_GAE_USER_ID = "666";
public static final String THE_REGISTRAR_GAE_USER_ID = "31337";
public static final String MARLA_SINGER_GAE_USER_ID = "12345";
/**
* The GAE testing library requires queue.xml to be a file, not a resource in a jar, so we read it
@@ -223,7 +224,6 @@ public final class AppEngineRule extends ExternalResource {
.setEmailAddress("janedoe@theregistrar.com")
.setPhoneNumber("+1.1234567890")
.setTypes(ImmutableSet.of(RegistrarContact.Type.ADMIN))
.setGaeUserId(NEW_REGISTRAR_GAE_USER_ID)
.build();
}
@@ -247,9 +247,10 @@ public final class AppEngineRule extends ExternalResource {
.setParent(makeRegistrar2())
.setName("Marla Singer")
.setEmailAddress("Marla.Singer@crr.com")
.setRegistryLockEmailAddress("Marla.Singer.RegistryLock@crr.com")
.setPhoneNumber("+1.2128675309")
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
.setGaeUserId(THE_REGISTRAR_GAE_USER_ID)
.setGaeUserId(MARLA_SINGER_GAE_USER_ID)
.setAllowedToSetRegistryLockPassword(true)
.setRegistryLockPassword("hi")
.build();
@@ -138,7 +138,7 @@ public class DatastoreHelper {
public static DomainBase newDomainBase(String domainName, HostResource host) {
return newDomainBase(domainName)
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host)))
.setNameservers(ImmutableSet.of(host.createKey()))
.build();
}
@@ -40,6 +40,7 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.util.Idn;
import java.net.InetAddress;
import java.util.List;
@@ -374,12 +375,12 @@ public final class FullFieldsTestEntityHelper {
builder.setContacts(contactsBuilder.build());
}
if ((ns1 != null) || (ns2 != null)) {
ImmutableSet.Builder<Key<HostResource>> nsBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> nsBuilder = new ImmutableSet.Builder<>();
if (ns1 != null) {
nsBuilder.add(Key.create(ns1));
nsBuilder.add(ns1.createKey());
}
if (ns2 != null) {
nsBuilder.add(Key.create(ns2));
nsBuilder.add(ns2.createKey());
}
builder.setNameservers(nsBuilder.build());
}
@@ -42,6 +42,7 @@ import google.registry.testing.DeterministicStringGenerator;
import google.registry.testing.FakeClock;
import google.registry.testing.UserInfo;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.joda.time.Duration;
@@ -91,7 +92,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_createUnlock() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock lock =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
}
@@ -99,7 +101,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_createUnlock_adminUnlockingAdmin() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", null, true);
RegistryLock lock =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
assertThat(lock.getUnlockCompletionTimestamp().isPresent()).isFalse();
}
@@ -116,10 +119,12 @@ public final class DomainLockUtilsTest {
@Test
public void testSuccess_createUnlock_previousUnlockRequestExpired() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
clock.advanceBy(Duration.standardDays(1));
RegistryLock unlockRequest =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlockRequest.getVerificationCode(), false);
assertThat(reloadDomain().getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
}
@@ -136,7 +141,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_applyUnlockDomain() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock unlock =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false);
verifyProperlyUnlockedDomain(false);
}
@@ -155,7 +161,8 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true);
RegistryLock unlock =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), true);
verifyProperlyUnlockedDomain(true);
}
@@ -178,7 +185,8 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.administrativelyApplyUnlock(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
verifyProperlyUnlockedDomain(false);
}
@@ -187,7 +195,8 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true);
domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", true);
domainLockUtils.administrativelyApplyUnlock(
DOMAIN_NAME, "TheRegistrar", true, Optional.empty());
verifyProperlyUnlockedDomain(true);
}
@@ -195,7 +204,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_regularLock_relockSet() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock oldLock =
domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.administrativelyApplyUnlock(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
RegistryLock newLock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
newLock = domainLockUtils.verifyAndApplyLock(newLock.getVerificationCode(), false);
@@ -208,7 +218,8 @@ public final class DomainLockUtilsTest {
public void testSuccess_administrativelyLock_relockSet() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock oldLock =
domainLockUtils.administrativelyApplyUnlock(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.administrativelyApplyUnlock(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
RegistryLock newLock =
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
assertThat(
@@ -216,19 +227,29 @@ public final class DomainLockUtilsTest {
.isEqualTo(newLock.getRevisionId());
}
@Test
public void testSuccess_createUnlock_relockDuration() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock lock =
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.of(Duration.standardDays(1)));
assertThat(lock.getRelockDuration()).isEqualTo(Optional.of(Duration.standardDays(1)));
}
@Test
public void testFailure_createUnlock_alreadyPendingUnlock() {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false)))
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("A pending unlock action already exists for example.tld");
}
@@ -243,7 +264,7 @@ public final class DomainLockUtilsTest {
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false)))
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.tld");
}
@@ -293,7 +314,7 @@ public final class DomainLockUtilsTest {
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false)))
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("Domain example.tld is already unlocked");
}
@@ -346,7 +367,8 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
RegistryLock unlock =
domainLockUtils.saveNewRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false);
assertThat(
@@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
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;
@@ -144,15 +143,23 @@ public class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsRep
.build());
nameserver3 = persistActiveHost("ns1.google.com");
nameserver4 = persistActiveHost("ns2.google.com");
domain1 = persistResource(newDomainBase("example.xn--q9jyb4c").asBuilder()
.setNameservers(ImmutableSet.of(Key.create(nameserver1), Key.create(nameserver2)))
.setDsData(ImmutableSet.of(
DelegationSignerData.create(12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")),
DelegationSignerData.create(56789, 2, 4, base16().decode("69FD46E6C4A45C55D4AC"))))
.build());
persistResource(newDomainBase("foobar.xn--q9jyb4c").asBuilder()
.setNameservers(ImmutableSet.of(Key.create(nameserver3), Key.create(nameserver4)))
.build());
domain1 =
persistResource(
newDomainBase("example.xn--q9jyb4c")
.asBuilder()
.setNameservers(ImmutableSet.of(nameserver1.createKey(), nameserver2.createKey()))
.setDsData(
ImmutableSet.of(
DelegationSignerData.create(
12345, 3, 1, base16().decode("49FD46E6C4B45C55D4AC")),
DelegationSignerData.create(
56789, 2, 4, base16().decode("69FD46E6C4A45C55D4AC"))))
.build());
persistResource(
newDomainBase("foobar.xn--q9jyb4c")
.asBuilder()
.setNameservers(ImmutableSet.of(nameserver3.createKey(), nameserver4.createKey()))
.build());
// Persist a domain in a different tld that should be ignored.
persistActiveDomain("should-be-ignored.example");
}
@@ -89,6 +89,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=UPDATE",
"--name=Judith Registrar",
"--email=judith.doe@example.com",
"--registry_lock_email=judith.doe@external.com",
"--phone=+1.2125650000",
"--fax=+1.2125650001",
"--contact_type=WHOIS",
@@ -102,6 +103,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Judith Registrar")
.setEmailAddress("judith.doe@example.com")
.setRegistryLockEmailAddress("judith.doe@external.com")
.setPhoneNumber("+1.2125650000")
.setFaxNumber("+1.2125650001")
.setTypes(ImmutableSet.of(WHOIS))
@@ -125,7 +127,11 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--email=jane.doe@example.com",
"--allow_console_access=true",
"NewRegistrar");
RegistrarContact registrarContact = loadRegistrar("NewRegistrar").getContacts().asList().get(1);
RegistrarContact registrarContact =
loadRegistrar("NewRegistrar").getContacts().stream()
.filter(rc -> rc.getEmailAddress().equals("jane.doe@example.com"))
.findFirst()
.get();
assertThat(registrarContact.getGaeUserId()).matches("-?[0-9]+");
}
@@ -292,6 +298,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=CREATE",
"--name=Jim Doe",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe@external.com",
"--contact_type=ADMIN,ABUSE",
"--visible_in_whois_as_admin=true",
"--visible_in_whois_as_tech=false",
@@ -303,6 +310,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Jim Doe")
.setEmailAddress("jim.doe@example.com")
.setRegistryLockEmailAddress("jim.doe@external.com")
.setTypes(ImmutableSet.of(ADMIN, ABUSE))
.setVisibleInWhoisAsAdmin(true)
.setVisibleInWhoisAsTech(false)
@@ -374,6 +382,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
"--mode=CREATE",
"--name=Jim Doe",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe.registry.lock@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar");
RegistrarContact registrarContact = loadRegistrar("NewRegistrar").getContacts().asList().get(1);
@@ -392,12 +401,30 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setEmailAddress("jim.doe@example.com")
.build());
assertThat(registrarContact.isAllowedToSetRegistryLockPassword()).isFalse();
// First, try (and fail) to set the password directly
assertThrows(
IllegalArgumentException.class,
() -> registrarContact.asBuilder().setRegistryLockPassword("foo"));
// Next, try (and fail) to allow registry lock without a registry lock email
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--mode=UPDATE",
"--email=jim.doe@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar")))
.hasMessageThat()
.isEqualTo("Registry lock email must not be null if allowing registry lock access");
// Next, include the email and it should succeed
runCommandForced(
"--mode=UPDATE",
"--email=jim.doe@example.com",
"--registry_lock_email=jim.doe.registry.lock@example.com",
"--allowed_to_set_registry_lock_password=true",
"NewRegistrar");
RegistrarContact newContact = reloadResource(registrarContact);
@@ -415,6 +442,7 @@ public class RegistrarContactCommandTest extends CommandTestCase<RegistrarContac
.setParent(registrar)
.setName("Jim Doe")
.setEmailAddress("jim.doe@example.com")
.setRegistryLockEmailAddress("jim.doe.registry.lock@example.com")
.setAllowedToSetRegistryLockPassword(true)
.setRegistryLockPassword("hi")
.build());
@@ -24,10 +24,10 @@ import static org.junit.Assert.assertThrows;
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
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 javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import org.junit.Before;
import org.junit.Test;
@@ -53,9 +53,9 @@ public class UniformRapidSuspensionCommandTest
}
private void persistDomainWithHosts(HostResource... hosts) {
ImmutableSet.Builder<Key<HostResource>> hostRefs = new ImmutableSet.Builder<>();
ImmutableSet.Builder<VKey<HostResource>> hostRefs = new ImmutableSet.Builder<>();
for (HostResource host : hosts) {
hostRefs.add(Key.create(host));
hostRefs.add(host.createKey());
}
persistResource(newDomainBase("evil.tld").asBuilder()
.setNameservers(hostRefs.build())
@@ -31,6 +31,7 @@ import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import org.junit.Test;
/** Unit tests for {@link UpdateDomainCommand}. */
@@ -116,12 +117,12 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
persistResource(
newDomainBase("example.abc")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host1)))
.setNameservers(ImmutableSet.of(host1.createKey()))
.build());
persistResource(
newDomainBase("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(Key.create(host2)))
.setNameservers(ImmutableSet.of(host2.createKey()))
.build());
runCommandForced(
"--client=NewRegistrar", nsParam, "example.abc", "example.tld");
@@ -171,8 +172,8 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
public void testSuccess_setNameservers() throws Exception {
HostResource host1 = persistActiveHost("ns1.zdns.google");
HostResource host2 = persistActiveHost("ns2.zdns.google");
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(host1), Key.create(host2));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(host1.createKey(), host2.createKey());
persistResource(
newDomainBase("example.tld").asBuilder().setNameservers(nameservers).build());
runCommandForced(
@@ -213,7 +214,7 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
@Test
public void testSuccess_setStatuses() throws Exception {
HostResource host = persistActiveHost("ns1.zdns.google");
ImmutableSet<Key<HostResource>> nameservers = ImmutableSet.of(Key.create(host));
ImmutableSet<VKey<HostResource>> nameservers = ImmutableSet.of(host.createKey());
persistResource(
newDomainBase("example.tld")
.asBuilder()
@@ -257,7 +258,7 @@ public class UpdateDomainCommandTest extends EppToolCommandTestCase<UpdateDomain
@Test
public void testFailure_cantUpdateRegistryLockedDomainEvenAsSuperuser() {
HostResource host = persistActiveHost("ns1.zdns.google");
ImmutableSet<Key<HostResource>> nameservers = ImmutableSet.of(Key.create(host));
ImmutableSet<VKey<HostResource>> nameservers = ImmutableSet.of(host.createKey());
persistResource(
newDomainBase("example.tld")
.asBuilder()
@@ -34,10 +34,10 @@ import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
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.FakeClock;
import google.registry.testing.mapreduce.MapreduceTestCase;
import java.net.InetAddress;
@@ -67,8 +67,8 @@ public class GenerateZoneFilesActionTest extends MapreduceTestCase<GenerateZoneF
HostResource host2 =
persistResource(newHostResource("ns.bar.tld").asBuilder().addInetAddresses(ips).build());
ImmutableSet<Key<HostResource>> nameservers =
ImmutableSet.of(Key.create(host1), Key.create(host2));
ImmutableSet<VKey<HostResource>> nameservers =
ImmutableSet.of(host1.createKey(), host2.createKey());
// This domain will have glue records, because it has a subordinate host which is its own
// nameserver. None of the other domains should have glue records, because their nameservers are
// subordinate to different domains.
@@ -190,7 +190,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
public void testSuccess_setRegistryLockPassword() {
addPasswordToTechContact();
techContact = Iterables.getOnlyElement(loadRegistrar(CLIENT_ID).getContactsOfType(Type.TECH));
assertThat(techContact.verifyRegistryLockPassword("hi")).isTrue();
assertThat(techContact.verifyRegistryLockPassword("hellothere")).isTrue();
assertMetric(CLIENT_ID, "update", "[OWNER]", "SUCCESS");
}
@@ -198,7 +198,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
public void testSuccess_setRegistryLockPassword_notOverriddenLater() {
addPasswordToTechContact();
techContact = Iterables.getOnlyElement(loadRegistrar(CLIENT_ID).getContactsOfType(Type.TECH));
assertThat(techContact.verifyRegistryLockPassword("hi")).isTrue();
assertThat(techContact.verifyRegistryLockPassword("hellothere")).isTrue();
techContact = Iterables.getOnlyElement(loadRegistrar(CLIENT_ID).getContactsOfType(Type.TECH));
Map<String, Object> techContactMap = techContact.toJsonMap();
@@ -211,14 +211,14 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
action.handleJsonRequest(ImmutableMap.of("op", "update", "id", CLIENT_ID, "args", reqJson));
assertThat(response).containsAtLeastEntriesIn(ImmutableMap.of("status", "SUCCESS"));
techContact = Iterables.getOnlyElement(loadRegistrar(CLIENT_ID).getContactsOfType(Type.TECH));
assertThat(techContact.verifyRegistryLockPassword("hi")).isTrue();
assertThat(techContact.verifyRegistryLockPassword("hellothere")).isTrue();
}
private void addPasswordToTechContact() {
techContact =
persistResource(techContact.asBuilder().setAllowedToSetRegistryLockPassword(true).build());
Map<String, Object> contactMap = techContact.toJsonMap();
contactMap.put("registryLockPassword", "hi");
contactMap.put("registryLockPassword", "hellothere");
Map<String, Object> reqJson = loadRegistrar(CLIENT_ID).toJsonMap();
reqJson.put(
"contacts",
@@ -237,6 +237,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
AppEngineRule.makeRegistrarContact2()
.asBuilder()
.setEmailAddress("someotheremail@example.com")
.setRegistryLockEmailAddress("someotherexample@example.com")
.setAllowedToSetRegistryLockPassword(true)
.build()
.toJsonMap(),
@@ -261,7 +262,7 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
// before we can set a password through the UI
Map<String, Object> contactMap =
techContact.asBuilder().setAllowedToSetRegistryLockPassword(true).build().toJsonMap();
contactMap.put("registryLockPassword", "hi");
contactMap.put("registryLockPassword", "hellothere");
Map<String, Object> reqJson = loadRegistrar(CLIENT_ID).toJsonMap();
reqJson.put(
"contacts",
@@ -302,4 +303,28 @@ public class ContactSettingsTest extends RegistrarSettingsActionTestCase {
"Cannot set isAllowedToSetRegistryLockPassword through UI");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormException");
}
@Test
public void testPost_failure_setRegistryLock_passwordTooShort() {
techContact =
persistResource(techContact.asBuilder().setAllowedToSetRegistryLockPassword(true).build());
Map<String, Object> contactMap = techContact.toJsonMap();
contactMap.put("registryLockPassword", "hi");
Map<String, Object> reqJson = loadRegistrar(CLIENT_ID).toJsonMap();
reqJson.put(
"contacts",
ImmutableList.of(AppEngineRule.makeRegistrarContact2().toJsonMap(), contactMap));
Map<String, Object> response =
action.handleJsonRequest(ImmutableMap.of("op", "update", "id", CLIENT_ID, "args", reqJson));
assertThat(response)
.containsExactly(
"status",
"ERROR",
"results",
ImmutableList.of(),
"message",
"Registry lock password must be at least 8 characters long");
assertMetric(CLIENT_ID, "update", "[OWNER]", "ERROR: FormException");
}
}
@@ -100,6 +100,7 @@ public abstract class RegistrarSettingsActionTestCase {
.setParent(loadRegistrar(CLIENT_ID))
.setName("Jian-Yang")
.setEmailAddress("jyang@bachman.accelerator")
.setRegistryLockEmailAddress("jyang.registrylock@bachman.accelerator")
.setPhoneNumber("+1.1234567890")
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
.build());
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.ADMIN;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
import static google.registry.testing.AppEngineRule.makeRegistrar2;
import static google.registry.testing.AppEngineRule.makeRegistrarContact2;
import static google.registry.testing.AppEngineRule.makeRegistrarContact3;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.SqlHelper.saveRegistryLock;
@@ -31,6 +32,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.gson.Gson;
import google.registry.model.registrar.RegistrarContact;
import google.registry.request.Action.Method;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
@@ -67,14 +69,15 @@ public final class RegistryLockGetActionTest {
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
private final FakeResponse response = new FakeResponse();
private final User user = new User("Marla.Singer@crr.com", "gmail.com", "12345");
private User user;
private AuthResult authResult;
private AuthenticatedRegistrarAccessor accessor;
private RegistryLockGetAction action;
@Before
public void setup() {
user = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
fakeClock.setTo(DateTime.parse("2000-06-08T22:00:00.0Z"));
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
accessor =
@@ -180,16 +183,16 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
true,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
ImmutableList.of(
new ImmutableMap.Builder<>()
.put("fullyQualifiedDomainName", "expiredunlock.test")
.put("lockedTime", "2000-06-08T22:00:00.000Z")
.put("lockedBy", "johndoe@theregistrar.com")
.put("userCanUnlock", true)
.put("fullyQualifiedDomainName", "adminexample.test")
.put("lockedTime", "2000-06-09T22:00:00.001Z")
.put("lockedBy", "admin")
.put("userCanUnlock", false)
.put("isLockPending", false)
.put("isUnlockPending", false)
.build(),
@@ -202,19 +205,11 @@ public final class RegistryLockGetActionTest {
.put("isUnlockPending", false)
.build(),
new ImmutableMap.Builder<>()
.put("fullyQualifiedDomainName", "adminexample.test")
.put("lockedTime", "2000-06-09T22:00:00.001Z")
.put("lockedBy", "admin")
.put("userCanUnlock", false)
.put("isLockPending", false)
.put("isUnlockPending", false)
.build(),
new ImmutableMap.Builder<>()
.put("fullyQualifiedDomainName", "pending.test")
.put("lockedTime", "")
.put("fullyQualifiedDomainName", "expiredunlock.test")
.put("lockedTime", "2000-06-08T22:00:00.000Z")
.put("lockedBy", "johndoe@theregistrar.com")
.put("userCanUnlock", true)
.put("isLockPending", true)
.put("isLockPending", false)
.put("isUnlockPending", false)
.build(),
new ImmutableMap.Builder<>()
@@ -224,6 +219,14 @@ public final class RegistryLockGetActionTest {
.put("userCanUnlock", true)
.put("isLockPending", false)
.put("isUnlockPending", true)
.build(),
new ImmutableMap.Builder<>()
.put("fullyQualifiedDomainName", "pending.test")
.put("lockedTime", "")
.put("lockedBy", "johndoe@theregistrar.com")
.put("userCanUnlock", true)
.put("isLockPending", true)
.put("isUnlockPending", false)
.build()))));
}
@@ -274,7 +277,7 @@ public final class RegistryLockGetActionTest {
"lockEnabledForContact",
false,
"email",
"Marla.Singer@crr.com",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
@@ -285,6 +288,8 @@ public final class RegistryLockGetActionTest {
public void testSuccess_lockAllowedForAdmin() {
// Locks are allowed for admins even when they're not enabled for the registrar
persistResource(makeRegistrar2().asBuilder().setRegistryLockAllowed(false).build());
// disallow the other user
persistResource(makeRegistrarContact2().asBuilder().setGaeUserId(null).build());
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, true));
accessor =
AuthenticatedRegistrarAccessor.createForTesting(
@@ -309,6 +314,29 @@ public final class RegistryLockGetActionTest {
ImmutableList.of())));
}
@Test
public void testSuccess_linkedToContactEmail() {
// Even though the user is some.email@gmail.com the contact is still Marla Singer
user = new User("some.email@gmail.com", "gmail.com", user.getUserId());
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
action =
new RegistryLockGetAction(
Method.GET, response, accessor, authResult, Optional.of("TheRegistrar"));
action.run();
assertThat(GSON.fromJson(response.getPayload(), Map.class).get("results"))
.isEqualTo(
ImmutableList.of(
ImmutableMap.of(
"lockEnabledForContact",
true,
"email",
"Marla.Singer.RegistryLock@crr.com",
"clientId",
"TheRegistrar",
"locks",
ImmutableList.of())));
}
@Test
public void testFailure_lockNotAllowedForRegistrar() {
// The UI shouldn't be making requests where lock isn't enabled for this registrar
@@ -337,4 +365,9 @@ public final class RegistryLockGetActionTest {
action.run();
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
}
static User userFromRegistrarContact(RegistrarContact registrarContact) {
return new User(
registrarContact.getEmailAddress(), "gmail.com", registrarContact.getGaeUserId());
}
}
@@ -20,9 +20,11 @@ import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.newDomainBase;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode;
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static google.registry.ui.server.registrar.RegistryLockGetActionTest.userFromRegistrarContact;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -48,9 +50,11 @@ import google.registry.util.EmailMessage;
import google.registry.util.SendEmailService;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -78,11 +82,8 @@ public final class RegistryLockPostActionTest {
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
private final User userWithoutPermission =
new User("johndoe@theregistrar.com", "gmail.com", "31337");
// Marla Singer has registry lock auth permissions
private final User userWithLockPermission =
new User("Marla.Singer@crr.com", "gmail.com", "31337");
private User userWithoutPermission;
private User userWithLockPermission;
private InternetAddress outgoingAddress;
private DomainBase domain;
@@ -93,6 +94,8 @@ public final class RegistryLockPostActionTest {
@Before
public void setup() throws Exception {
userWithLockPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
userWithoutPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact2());
createTld("tld");
domain = persistResource(newDomainBase("example.tld"));
outgoingAddress = new InternetAddress("domain-registry@example.com");
@@ -105,7 +108,7 @@ public final class RegistryLockPostActionTest {
@Test
public void testSuccess_lock() throws Exception {
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -113,7 +116,23 @@ public final class RegistryLockPostActionTest {
saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
assertSuccess(response, "unlock", "Marla.Singer@crr.com");
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
public void testSuccess_unlock_relockDurationSet() throws Exception {
saveRegistryLock(createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
ImmutableMap<String, Object> request =
new ImmutableMap.Builder<String, Object>()
.putAll(unlockRequest())
.put("relockDurationMillis", Duration.standardDays(1).getMillis())
.build();
Map<String, ?> response = action.handleJsonRequest(request);
assertSuccess(response, "unlock", "Marla.Singer.RegistryLock@crr.com");
RegistryLock savedUnlockRequest = getMostRecentRegistryLockByRepoId(domain.getRepoId()).get();
assertThat(savedUnlockRequest.getRelockDuration())
.isEqualTo(Optional.of(Duration.standardDays(1)));
}
@Test
@@ -133,6 +152,18 @@ public final class RegistryLockPostActionTest {
assertSuccess(response, "unlock", "johndoe@theregistrar.com");
}
@Test
public void testSuccess_linkedToContactEmail() throws Exception {
// Even though the user is some.email@gmail.com the contact is still Marla Singer
userWithLockPermission =
new User("some.email@gmail.com", "gmail.com", userWithLockPermission.getUserId());
action =
createAction(
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithLockPermission, false)));
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
public void testFailure_unlock_noLock() {
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
@@ -233,7 +264,7 @@ public final class RegistryLockPostActionTest {
persistResource(
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertFailureWithMessage(response, "Registry lock not allowed for this registrar");
assertFailureWithMessage(response, "Registry lock not allowed for registrar TheRegistrar");
}
@Test
@@ -244,7 +275,7 @@ public final class RegistryLockPostActionTest {
"clientId", "TheRegistrar",
"fullyQualifiedDomainName", "example.tld",
"isLock", true));
assertFailureWithMessage(response, "Missing key for password");
assertFailureWithMessage(response, "Incorrect registry lock password for contact");
}
@Test
@@ -297,7 +328,7 @@ public final class RegistryLockPostActionTest {
.build());
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -307,7 +338,7 @@ public final class RegistryLockPostActionTest {
previousLock = getRegistryLockByVerificationCode(verificationCode).get();
clock.setTo(previousLock.getLockRequestTimestamp().plusHours(2));
Map<String, ?> response = action.handleJsonRequest(lockRequest());
assertSuccess(response, "lock", "Marla.Singer@crr.com");
assertSuccess(response, "lock", "Marla.Singer.RegistryLock@crr.com");
}
@Test
@@ -386,9 +417,10 @@ public final class RegistryLockPostActionTest {
}
private RegistryLockPostAction createAction(AuthResult authResult) {
Role role = authResult.userAuthInfo().get().isUserAdmin() ? Role.ADMIN : Role.OWNER;
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of("TheRegistrar", Role.OWNER, "NewRegistrar", Role.OWNER));
ImmutableSetMultimap.of("TheRegistrar", role, "NewRegistrar", role));
JsonActionRunner jsonActionRunner =
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
DomainLockUtils domainLockUtils =
@@ -60,7 +60,8 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
route("/registry-lock-verify", FrontendServlet.class))
.setFilters(ObjectifyFilter.class, OfyFilter.class)
.setFixtures(BASIC)
.setEmail("Marla.Singer@crr.com")
.setEmail("Marla.Singer@crr.com") // from AppEngineRule.makeRegistrarContact3
.setGaeUserId("12345") // from AppEngineRule.makeRegistrarContact3
.build();
@Test
@@ -152,6 +153,7 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
persistResource(
makeRegistrarContact2()
.asBuilder()
.setRegistryLockEmailAddress("johndoe.registrylock@example.com")
.setAllowedToSetRegistryLockPassword(true)
.build());
persistResource(makeRegistrar2().asBuilder().setRegistryLockAllowed(true).build());
@@ -452,11 +454,12 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
createTld("tld");
// expired unlock request
DomainBase expiredUnlockRequestDomain = persistActiveDomain("expiredunlock.tld");
saveRegistryLock(createRegistryLock(expiredUnlockRequestDomain)
.asBuilder()
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
.build());
saveRegistryLock(
createRegistryLock(expiredUnlockRequestDomain)
.asBuilder()
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
.build());
DomainBase domain = persistActiveDomain("example.tld");
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
DomainBase otherDomain = persistActiveDomain("otherexample.tld");
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static google.registry.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
import static google.registry.util.NetworkUtils.getExternalAddressOfLocalSystem;
import static google.registry.util.NetworkUtils.pickUnusedPort;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -32,6 +33,7 @@ import google.registry.testing.UserInfo;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
@@ -66,7 +68,8 @@ public final class TestServerRule extends ExternalResource {
ImmutableList<Route> routes,
ImmutableList<Class<? extends Filter>> filters,
ImmutableList<Fixture> fixtures,
String email) {
String email,
Optional<String> gaeUserId) {
this.runfiles = runfiles;
this.routes = routes;
this.filters = filters;
@@ -79,7 +82,8 @@ public final class TestServerRule extends ExternalResource {
.withLocalModules()
.withUrlFetch()
.withTaskQueue()
.withUserService(UserInfo.createAdmin(email, THE_REGISTRAR_GAE_USER_ID))
.withUserService(
UserInfo.createAdmin(email, gaeUserId.orElse(THE_REGISTRAR_GAE_USER_ID)))
.build();
}
@@ -149,8 +153,8 @@ public final class TestServerRule extends ExternalResource {
/**
* Runs arbitrary code inside server event loop thread.
*
* <p>You should use this method when you want to do things like change Datastore, because the
* App Engine testing environment is thread-local.
* <p>You should use this method when you want to do things like change Datastore, because the App
* Engine testing environment is thread-local.
*/
public <T> T runInAppEngineEnvironment(Callable<T> callback) throws Throwable {
FutureTask<T> job = new FutureTask<>(callback);
@@ -211,7 +215,6 @@ public final class TestServerRule extends ExternalResource {
*
* <p>This builder has three required fields: {@link #setRunfiles}, {@link #setRoutes}, and {@link
* #setFilters}.
*
*/
public static final class Builder {
private ImmutableMap<String, Path> runfiles;
@@ -219,6 +222,7 @@ public final class TestServerRule extends ExternalResource {
ImmutableList<Class<? extends Filter>> filters;
private ImmutableList<Fixture> fixtures = ImmutableList.of();
private String email;
private Optional<String> gaeUserId = Optional.empty();
/** Sets the directories containing the static files for {@link TestServer}. */
public Builder setRunfiles(ImmutableMap<String, Path> runfiles) {
@@ -256,6 +260,13 @@ public final class TestServerRule extends ExternalResource {
return this;
}
/** Optionally, sets the GAE user ID for the logged in user. */
public Builder setGaeUserId(String gaeUserId) {
this.gaeUserId =
Optional.of(checkArgumentNotNull(gaeUserId, "Must specify a non-null GAE user ID"));
return this;
}
/** Returns a new {@link TestServerRule} instance. */
public TestServerRule build() {
return new TestServerRule(
@@ -263,7 +274,8 @@ public final class TestServerRule extends ExternalResource {
checkNotNull(this.routes),
checkNotNull(this.filters),
checkNotNull(this.fixtures),
checkNotNull(this.email));
checkNotNull(this.email),
this.gaeUserId);
}
}
}
@@ -37,6 +37,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.whois.WhoisResponse.WhoisResponseResults;
@@ -220,8 +221,8 @@ public class DomainWhoisResponseTest {
.setEmailAddress("EMAIL@EXAMPLE.tld")
.build());
Key<HostResource> hostResource1Key = Key.create(hostResource1);
Key<HostResource> hostResource2Key = Key.create(hostResource2);
VKey<HostResource> hostResource1Key = hostResource1.createKey();
VKey<HostResource> hostResource2Key = hostResource2.createKey();
Key<ContactResource> registrantResourceKey = Key.create(registrant);
Key<ContactResource> adminResourceKey = Key.create(adminContact);
Key<ContactResource> techResourceKey = Key.create(techContact);

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