Compare commits

...
Author SHA1 Message Date
Ben McIlwainandGitHub fa135dcd85 Re-enable prober data deletion cron jobs in prod & sandbox (#1611)
This reverts commit 52c759d1db.
2022-05-02 13:46:02 -04:00
sarahcaseybotandGitHub 5d82893478 Check PAK is present on billing domain flows (#1605)
* Check PAK on domain create

* Add unit test

* update docs

* Remove unneccesary setup

* Fix blank line

* Add check and test to all relevant flows

* Change error message
2022-04-29 14:30:24 -04:00
Rachel GuanandGitHub d0af81ecdf Change from assertThat(assertThrow()) to thrown = assertThrows() then assertThat(thrown) (#1606) 2022-04-28 16:09:36 -04:00
Michael MullerandGitHub f273783894 Ignore version UIDs during txn deserialization (#1607)
* Ignore version UIDs during txn deserialization

When deserializing transactions for replay to datastore, ignore class version
UIDs that don't match those of the local classes and just use the local class
descriptors instead.  This is a simple solution for the problem of persisted
VKeys containing references to classes where the class has been updated and
the serial version UID has changed.

Also add a "replay_txns" command that replays the transactions from a given
start point so we can verify all transactions are deserializable.

TESTED:
    Ran replay_txns against all transactions on sandbox beginning with
    transaction id 1828385, which includes Recurring billing events containing
    both the old and the new serial version UIDs.
2022-04-27 15:40:27 -04:00
Ben McIlwainandGitHub 0dfabe1c64 Convert more Guava caches to Caffeine (#1603)
* Convert more Guava caches to Caffeine
2022-04-26 11:26:51 -04:00
Weimin YuandGitHub 60a011c593 Remove stray file that slipped in the repo (#1604)
* Remove stray file that slipped in the repo
2022-04-25 17:08:58 -04:00
Michael MullerandGitHub 7716eebfff Change check for root directory during rollback (#1602)
* Change check for root directory during rollback

`rollback_tool` tries to infer the root of the nomulus tree by checking for a
directory named "nomulus".  This is potentially problematic (and, indeed, was
for me) since there is no guarantee what that directory will be named.

There are a number of features that characterize the root directory.  Check
for the presence of the `rollback_tool` wrapper script, as this is both at
root level and tightly coupled to the python code, so hopefully we won't
move it without testing that the script still works.
2022-04-25 12:39:16 -04:00
Ben McIlwainandGitHub 1e76eeed37 Validate that a registrar has billing accounts for all its allowed TLDs (#1601)
This will require edits to a substantial number of registrars on sandbox (nearly
all of them) because almost all of them have access to at least one TLD, but
almost none of them have any billing accounts set. Until this is set, any updates
to the existing registrars that aren't adding the billing accounts will cause
failures.

Unfortunately, there wasn't any less invasive foolproof way to implement this
change, and we already had one attempt to implement it on create registrar
command that wasn't working (because allowed TLDs tend not to be added on
initial registrar creation, but rather, afterwards as an update).
2022-04-22 16:33:18 -04:00
sarahcaseybotandGitHub 147d133aef Don't fail invoicing on missing PAK (#1595)
* Don't fail invoicing on missing PAK

* Skip line if missing PAK

* Add log check in test
2022-04-22 13:00:50 -04:00
Ben McIlwainandGitHub c2e1f2e640 Downgrade Caffeine to 2.9.3 (#1600)
* Downgrade Caffeine to 2.9.3

Apparently Caffeine >=3.* requires Java 11, and we're still stuck on Java 8
because of App Engine Standard.  Fortunately this doesn't affect the exposed
interface we're using, so we can simply go back to the newest Caffeine version
once Registry 3.0 Phase 3 (GKE migration) is completed.
2022-04-20 14:05:37 -04:00
Lai JiangandGitHub 5d2639834a Remove the BEAM RDE pipeline side job (#1599)
Now that SQL is the default, we do not need this side job to run
alongside the main one. Its purpose was to validate the BEAM pipeline
while Datastore was primary.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1599)
<!-- Reviewable:end -->
2022-04-20 12:12:23 -04:00
Rachel GuanandGitHub 7912576e3d Add rachelguan@ to CONTRIBUTORS (#1598) 2022-04-19 19:18:44 -04:00
Rachel GuanandGitHub 8424c85258 Fix build warning for unused variable (#1594) 2022-04-19 14:11:23 -04:00
Lai JiangandGitHub e72dd73ed8 Fix build (#1597) 2022-04-19 08:27:06 -04:00
Rachel GuanandGitHub 508d221b94 Replace .get()).isEqualTo() with hasValue() (#1589)
* Replace .get()).isEqualTo() with hasValue()

* Use containsExactly for list comparison

* Fix spacing
2022-04-18 18:35:46 -04:00
173 changed files with 1153 additions and 639 deletions
+1
View File
@@ -36,3 +36,4 @@ Shicong Huang <shicong@google.com>
Gustav Brodman <gbrodman@google.com>
Sarah Botwinick <sarahbot@google.com>
Legina Chen <legina@google.com>
Rachel Guan <rachelguan@google.com>
+1
View File
@@ -51,6 +51,7 @@ artifacts {
dependencies {
def deps = rootProject.dependencyMap
compile deps['com.github.ben-manes.caffeine:caffeine']
compile deps['com.google.code.findbugs:jsr305']
compile deps['com.google.guava:guava']
compile deps['javax.inject:javax.inject']
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,12 +1,13 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -16,7 +17,7 @@ joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.apiguardian:apiguardian-api:1.1.0
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -16,7 +17,7 @@ joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.apiguardian:apiguardian-api:1.1.0
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -17,7 +18,7 @@ joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.apiguardian:apiguardian-api:1.1.0
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -17,7 +18,7 @@ joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.apiguardian:apiguardian-api:1.1.0
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.2
org.junit.jupiter:junit-jupiter-engine:5.6.2
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -15,6 +16,6 @@ javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.ow2.asm:asm:9.0
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -15,6 +16,6 @@ javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.ow2.asm:asm:9.0
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -16,6 +17,6 @@ javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.ow2.asm:asm:9.0
@@ -1,9 +1,10 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.auto.value:auto-value-annotations:1.7.4
com.google.code.findbugs:jsr305:3.0.2
com.google.errorprone:error_prone_annotations:2.5.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -16,6 +17,6 @@ javax.inject:javax.inject:1
joda-time:joda-time:2.9.2
junit:junit:4.13.1
org.checkerframework:checker-compat-qual:2.5.3
org.checkerframework:checker-qual:3.9.1
org.checkerframework:checker-qual:3.19.0
org.hamcrest:hamcrest-core:1.3
org.ow2.asm:asm:9.0
@@ -14,9 +14,9 @@
package google.registry.testing;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.flogger.FluentLogger;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
@@ -29,7 +29,7 @@ public final class SystemInfo {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final LoadingCache<String, Boolean> hasCommandCache =
CacheBuilder.newBuilder()
Caffeine.newBuilder()
.build(
new CacheLoader<String, Boolean>() {
@Override
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -119,7 +119,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -244,7 +244,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -254,7 +254,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -119,7 +119,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -244,7 +244,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -118,7 +118,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -237,7 +237,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.conscrypt:conscrypt-openjdk-uber:2.5.1
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -123,7 +123,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -123,7 +123,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -123,7 +123,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -121,7 +121,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -265,7 +265,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -120,7 +120,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -258,7 +258,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.conscrypt:conscrypt-openjdk-uber:2.5.1
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -126,7 +126,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -275,7 +275,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -126,7 +126,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -275,7 +275,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -14,11 +14,11 @@
package google.registry.beam.invoicing;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.beam.BeamUtils.getQueryFromFile;
import static org.apache.beam.sdk.values.TypeDescriptors.strings;
import com.google.common.flogger.FluentLogger;
import google.registry.beam.common.RegistryJpaIO;
import google.registry.beam.common.RegistryJpaIO.Read;
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey;
@@ -36,6 +36,7 @@ import java.time.LocalTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;
import org.apache.beam.sdk.Pipeline;
@@ -75,6 +76,8 @@ public class InvoicingPipeline implements Serializable {
private static final Pattern SQL_COMMENT_REGEX =
Pattern.compile("^\\s*--.*\\n", Pattern.MULTILINE);
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final InvoicingPipelineOptions options;
InvoicingPipeline(InvoicingPipelineOptions options) {
@@ -115,38 +118,44 @@ public class InvoicingPipeline implements Serializable {
InvoicingPipelineOptions options, Pipeline pipeline) {
Read<Object[], BillingEvent> read =
RegistryJpaIO.read(
makeCloudSqlQuery(options.getYearMonth()), false, InvoicingPipeline::parseRow);
makeCloudSqlQuery(options.getYearMonth()), false, row -> parseRow(row).orElse(null));
return pipeline.apply("Read BillingEvents from Cloud SQL", read);
PCollection<BillingEvent> billingEventsWithNulls =
pipeline.apply("Read BillingEvents from Cloud SQL", read);
// Remove null billing events
return billingEventsWithNulls.apply(Filter.by(Objects::nonNull));
}
private static BillingEvent parseRow(Object[] row) {
private static Optional<BillingEvent> parseRow(Object[] row) {
google.registry.model.billing.BillingEvent.OneTime oneTime =
(google.registry.model.billing.BillingEvent.OneTime) row[0];
Registrar registrar = (Registrar) row[1];
CurrencyUnit currency = oneTime.getCost().getCurrencyUnit();
checkState(
registrar.getBillingAccountMap().containsKey(currency),
"Registrar %s does not have a product account key for the currency unit: %s",
registrar.getRegistrarId(),
currency);
if (!registrar.getBillingAccountMap().containsKey(currency)) {
logger.atSevere().log(
"Registrar %s does not have a product account key for the currency unit: %s",
registrar.getRegistrarId(), currency);
return Optional.empty();
}
return BillingEvent.create(
oneTime.getId(),
DateTimeUtils.toZonedDateTime(oneTime.getBillingTime(), ZoneId.of("UTC")),
DateTimeUtils.toZonedDateTime(oneTime.getEventTime(), ZoneId.of("UTC")),
registrar.getRegistrarId(),
registrar.getBillingAccountMap().get(currency),
registrar.getPoNumber().orElse(""),
DomainNameUtils.getTldFromDomainName(oneTime.getTargetId()),
oneTime.getReason().toString(),
oneTime.getTargetId(),
oneTime.getDomainRepoId(),
Optional.ofNullable(oneTime.getPeriodYears()).orElse(0),
oneTime.getCost().getCurrencyUnit().toString(),
oneTime.getCost().getAmount().doubleValue(),
String.join(
" ", oneTime.getFlags().stream().map(Flag::toString).collect(toImmutableSet())));
return Optional.of(
BillingEvent.create(
oneTime.getId(),
DateTimeUtils.toZonedDateTime(oneTime.getBillingTime(), ZoneId.of("UTC")),
DateTimeUtils.toZonedDateTime(oneTime.getEventTime(), ZoneId.of("UTC")),
registrar.getRegistrarId(),
registrar.getBillingAccountMap().get(currency),
registrar.getPoNumber().orElse(""),
DomainNameUtils.getTldFromDomainName(oneTime.getTargetId()),
oneTime.getReason().toString(),
oneTime.getTargetId(),
oneTime.getDomainRepoId(),
Optional.ofNullable(oneTime.getPeriodYears()).orElse(0),
oneTime.getCost().getCurrencyUnit().toString(),
oneTime.getCost().getAmount().doubleValue(),
String.join(
" ", oneTime.getFlags().stream().map(Flag::toString).collect(toImmutableSet()))));
}
/** Transform that converts a {@code BillingEvent} into an invoice CSV row. */
@@ -36,19 +36,6 @@
<target>backend</target>
</cron>
<cron>
<url>/_dr/task/rdeStaging?beam=true</url>
<description>
This job generates a full RDE escrow deposit as a single gigantic XML
document using the Beam pipeline regardless of the current TM
configuration and streams it to cloud storage. It does not trigger the
subsequent upload tasks and is meant to run parallel with the main cron
job in order to compare the results from both runs.
</description>
<schedule>every 8 hours from 00:07 to 20:00</schedule>
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=rde-upload&endpoint=/_dr/task/rdeUpload&forEachRealTld]]></url>
<description>
@@ -253,6 +240,16 @@
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/deleteProberData&runInEmpty]]></url>
<description>
This job clears out data from probers and runs once a week.
</description>
<schedule>every monday 14:00</schedule>
<timezone>UTC</timezone>
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/exportReservedTerms&forEachRealTld]]></url>
<description>
@@ -182,6 +182,16 @@
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/deleteProberData&runInEmpty]]></url>
<description>
This job clears out data from probers and runs once a week.
</description>
<schedule>every monday 14:00</schedule>
<timezone>UTC</timezone>
<target>backend</target>
</cron>
<cron>
<url><![CDATA[/_dr/cron/fanout?queue=retryable-cron-tasks&endpoint=/_dr/task/exportReservedTerms&forEachRealTld]]></url>
<description>
@@ -20,6 +20,7 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
import static google.registry.flows.domain.DomainFlowUtils.isAnchorTenant;
@@ -100,6 +101,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.InvalidIdnDomainLabelException}
* @error {@link DomainFlowUtils.InvalidPunycodeException}
* @error {@link DomainFlowUtils.LeadingDashException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RestoresAreAlwaysForOneYearException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
@@ -153,6 +155,7 @@ public final class DomainCheckFlow implements Flow {
boolean tldFirstTimeSeen = seenTlds.add(tld);
if (tldFirstTimeSeen && !isSuperuser) {
checkAllowedAccessToTld(registrarId, tld);
checkHasBillingAccount(registrarId, tld);
verifyNotInPredelegation(Registry.get(tld), now);
}
}
@@ -17,6 +17,7 @@ package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
@@ -60,6 +61,7 @@ import org.joda.time.DateTime;
* @error {@link google.registry.flows.FlowUtils.NotLoggedInException}
* @error {@link DomainFlowUtils.BadCommandForRegistryPhaseException}
* @error {@link DomainFlowUtils.ClaimsPeriodEndedException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
* @error {@link DomainClaimsCheckNotAllowedWithAllocationTokens}
@@ -99,6 +101,7 @@ public final class DomainClaimsCheckFlow implements Flow {
if (seenTlds.add(tld)) {
if (!isSuperuser) {
checkAllowedAccessToTld(registrarId, tld);
checkHasBillingAccount(registrarId, tld);
Registry registry = Registry.get(tld);
DateTime now = clock.nowUtc();
verifyNotInPredelegation(registry, now);
@@ -20,6 +20,7 @@ import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.domain.DomainFlowUtils.COLLISION_MESSAGE;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse;
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
@@ -180,6 +181,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.MalformedTcnIdException}
* @error {@link DomainFlowUtils.MaxSigLifeNotSupportedException}
* @error {@link DomainFlowUtils.MissingAdminContactException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.MissingClaimsNoticeException}
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingRegistrantException}
@@ -265,6 +267,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
// registering premium domains.
if (!isSuperuser) {
checkAllowedAccessToTld(registrarId, registry.getTldStr());
checkHasBillingAccount(registrarId, registry.getTldStr());
boolean isValidReservedCreate = isValidReservedCreate(domainName, allocationToken);
verifyIsGaOrIsSpecialCase(tldState, isAnchorTenant, isValidReservedCreate, hasSignedMarks);
if (launchCreate.isPresent()) {
@@ -293,6 +293,17 @@ public class DomainFlowUtils {
}
}
/** Check if the registrar has the correct billing account map configured. */
public static void checkHasBillingAccount(String registrarId, String tld) throws EppException {
CurrencyUnit currency = Registry.get(tld).getCurrency();
if (!Registrar.loadByRegistrarIdCached(registrarId)
.get()
.getBillingAccountMap()
.containsKey(currency)) {
throw new DomainFlowUtils.MissingBillingAccountMapException(currency);
}
}
/** Check that the DS data that will be set on a domain is valid. */
static void validateDsData(Set<DelegationSignerData> dsData) throws EppException {
if (dsData != null) {
@@ -1501,6 +1512,13 @@ public class DomainFlowUtils {
}
}
/** Registrar is missing the billing account map for this currency type. */
public static class MissingBillingAccountMapException extends AuthorizationErrorException {
public MissingBillingAccountMapException(CurrencyUnit currency) {
super("Registrar is not fully onboarded for TLDs that bill in " + currency);
}
}
/** Registrant is not allow-listed for this TLD. */
public static class RegistrantNotAllowedException extends StatusProhibitsOperationException {
public RegistrantNotAllowedException(String contactId) {
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEvent;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
@@ -106,6 +107,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
@@ -263,6 +265,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
if (!isSuperuser) {
verifyResourceOwnership(registrarId, existingDomain);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
checkHasBillingAccount(registrarId, existingDomain.getTld());
}
verifyUnitIsYears(command.getPeriod());
// If the date they specify doesn't match the expiration, fail. (This is an idempotence check).
@@ -20,6 +20,7 @@ import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEvent;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
@@ -104,6 +105,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.DomainReservedException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
@@ -216,6 +218,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
verifyNotReserved(InternetDomainName.from(targetId), false);
verifyPremiumNameIsNotBlocked(targetId, now, registrarId);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
checkHasBillingAccount(registrarId, existingDomain.getTld());
}
// No other changes can be specified on a restore request.
if (!command.noChangesPresent()) {
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfoPresentForResourceTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
@@ -111,6 +112,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.CurrencyValueScaleException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
@@ -273,6 +275,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
verifyTransferPeriod(period, superuserExtension);
if (!isSuperuser) {
checkAllowedAccessToTld(gainingClientId, existingDomain.getTld());
checkHasBillingAccount(gainingClientId, existingDomain.getTld());
verifyPremiumNameIsNotBlocked(targetId, now, gainingClientId);
}
}
@@ -21,11 +21,9 @@ import static com.google.common.collect.Maps.transformValues;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
@@ -59,36 +57,33 @@ public class ModelUtils {
/** Caches all instance fields on an object, including non-public and inherited fields. */
private static final LoadingCache<Class<?>, ImmutableMap<String, Field>> ALL_FIELDS_CACHE =
CacheBuilder.newBuilder()
CacheUtils.newCacheBuilder()
.build(
new CacheLoader<Class<?>, ImmutableMap<String, Field>>() {
@Override
public ImmutableMap<String, Field> load(Class<?> clazz) {
Deque<Class<?>> hierarchy = new ArrayDeque<>();
// Walk the hierarchy up to but not including ImmutableObject (to ignore
// hashCode).
for (; clazz != ImmutableObject.class; clazz = clazz.getSuperclass()) {
// Add to the front, so that shadowed fields show up later in the list.
// This will mean that getFieldValues will show the most derived value.
hierarchy.addFirst(clazz);
}
Map<String, Field> fields = new LinkedHashMap<>();
for (Class<?> hierarchyClass : hierarchy) {
// Don't use hierarchyClass.getFields() because it only picks up public fields.
for (Field field : hierarchyClass.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
fields.put(field.getName(), field);
}
clazz -> {
Deque<Class<?>> hierarchy = new ArrayDeque<>();
// Walk the hierarchy up to but not including ImmutableObject (to ignore
// hashCode).
for (; clazz != ImmutableObject.class; clazz = clazz.getSuperclass()) {
// Add to the front, so that shadowed fields show up later in the list.
// This will mean that getFieldValues will show the most derived value.
hierarchy.addFirst(clazz);
}
Map<String, Field> fields = new LinkedHashMap<>();
for (Class<?> hierarchyClass : hierarchy) {
// Don't use hierarchyClass.getFields() because it only picks up public fields.
for (Field field : hierarchyClass.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
fields.put(field.getName(), field);
}
}
return ImmutableMap.copyOf(fields);
}
return ImmutableMap.copyOf(fields);
});
/** Lists all instance fields on an object, including non-public and inherited fields. */
public static Map<String, Field> getAllFields(Class<?> clazz) {
return ALL_FIELDS_CACHE.getUnchecked(clazz);
return ALL_FIELDS_CACHE.get(clazz);
}
/** Return a string representing the persisted schema of a type or enum. */
@@ -38,6 +38,7 @@ import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.model.tld.Registry;
import google.registry.model.tld.Registry.TldState;
import google.registry.model.tld.Registry.TldType;
import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumListDao;
import google.registry.persistence.VKey;
@@ -111,6 +112,17 @@ public final class OteAccountBuilder {
DateTime.parse("2030-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 0));
/**
* The default billing account map applied to all OT&amp;E registrars.
*
* <p>This contains dummy values for USD and JPY so that OT&amp;E registrars can be granted access
* to all existing TLDs in sandbox. Note that OT&amp;E is only on sandbox and thus these dummy
* values will never be used in production (the only environment where real invoicing takes
* place).
*/
public static final ImmutableMap<CurrencyUnit, String> DEFAULT_BILLING_ACCOUNT_MAP =
ImmutableMap.of(CurrencyUnit.USD, "123", CurrencyUnit.JPY, "456");
private final ImmutableMap<String, String> registrarIdToTld;
private final Registry sunriseTld;
private final Registry gaTld;
@@ -305,6 +317,7 @@ public final class OteAccountBuilder {
.setTldStateTransitions(ImmutableSortedMap.of(START_OF_TIME, initialTldState))
.setDnsWriters(ImmutableSet.of("VoidDnsWriter"))
.setPremiumList(premiumList.get())
.setTldType(TldType.TEST)
.setRoidSuffix(
String.format(
"%S%X",
@@ -334,6 +347,7 @@ public final class OteAccountBuilder {
.setPhoneNumber("+1.2125550100")
.setIcannReferralEmail("nightmare@registrar.test")
.setState(Registrar.State.ACTIVE)
.setBillingAccountMap(DEFAULT_BILLING_ACCOUNT_MAP)
.build();
}
@@ -18,14 +18,13 @@ import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.flogger.FluentLogger;
import google.registry.config.RegistryEnvironment;
import google.registry.model.CacheUtils;
import google.registry.model.annotations.DeleteAfterMigration;
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
import google.registry.model.replay.SqlOnlyEntity;
@@ -135,18 +134,8 @@ public class DatabaseMigrationStateSchedule extends CrossTldSingleton implements
TimedTransitionProperty<MigrationState, MigrationStateTransition>>
// Each instance should cache the migration schedule for five minutes before reloading
CACHE =
CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofMinutes(5))
.build(
new CacheLoader<
Class<DatabaseMigrationStateSchedule>,
TimedTransitionProperty<MigrationState, MigrationStateTransition>>() {
@Override
public TimedTransitionProperty<MigrationState, MigrationStateTransition> load(
Class<DatabaseMigrationStateSchedule> unused) {
return DatabaseMigrationStateSchedule.getUncached();
}
});
CacheUtils.newCacheBuilder(Duration.ofMinutes(5))
.build(singletonClazz -> DatabaseMigrationStateSchedule.getUncached());
// Restrictions on the state transitions, e.g. no going from DATASTORE_ONLY to SQL_ONLY
private static final ImmutableMultimap<MigrationState, MigrationState> VALID_STATE_TRANSITIONS =
@@ -235,7 +224,7 @@ public class DatabaseMigrationStateSchedule extends CrossTldSingleton implements
/** Loads the currently-set migration schedule from the cache, or the default if none exists. */
public static TimedTransitionProperty<MigrationState, MigrationStateTransition> get() {
return CACHE.getUnchecked(DatabaseMigrationStateSchedule.class);
return CACHE.get(DatabaseMigrationStateSchedule.class);
}
/** Returns the database migration status at the given time. */
@@ -81,6 +81,7 @@ import google.registry.model.common.EntityGroupRoot;
import google.registry.model.registrar.Registrar.BillingAccountEntry.CurrencyMapper;
import google.registry.model.replay.DatastoreAndSqlEntity;
import google.registry.model.tld.Registry;
import google.registry.model.tld.Registry.TldType;
import google.registry.persistence.VKey;
import google.registry.util.CidrAddressBlock;
import java.security.cert.CertificateParsingException;
@@ -798,13 +799,9 @@ public class Registrar extends ImmutableObject
}
public Builder setBillingAccountMap(@Nullable Map<CurrencyUnit, String> billingAccountMap) {
if (billingAccountMap == null) {
getInstance().billingAccountMap = null;
} else {
getInstance().billingAccountMap =
billingAccountMap.entrySet().stream()
.collect(toImmutableMap(Map.Entry::getKey, BillingAccountEntry::new));
}
getInstance().billingAccountMap =
nullToEmptyImmutableCopy(billingAccountMap).entrySet().stream()
.collect(toImmutableMap(Map.Entry::getKey, BillingAccountEntry::new));
return this;
}
@@ -1015,6 +1012,20 @@ public class Registrar extends ImmutableObject
String.format(
"Supplied IANA ID is not valid for %s registrar type: %s",
getInstance().type, getInstance().ianaIdentifier));
// In order to grant access to real TLDs, the registrar must have a corresponding billing
// account ID for that TLD's billing currency.
ImmutableSet<String> nonBillableTlds =
Registry.get(getInstance().getAllowedTlds()).stream()
.filter(r -> r.getTldType() == TldType.REAL)
.filter(r -> !getInstance().getBillingAccountMap().containsKey(r.getCurrency()))
.map(Registry::getTldStr)
.collect(toImmutableSet());
checkArgument(
nonBillableTlds.isEmpty(),
"Cannot set these allowed, real TLDs because their currency is missing "
+ "from the billing account map: %s",
nonBillableTlds);
return cloneEmptyToNull(super.build());
}
}
@@ -16,15 +16,14 @@ package google.registry.model.server;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.primitives.Longs;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.Unindex;
import google.registry.model.CacheUtils;
import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason;
import google.registry.model.common.CrossTldSingleton;
@@ -32,7 +31,6 @@ import google.registry.model.replay.NonReplicatedEntity;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import javax.persistence.Column;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
@@ -52,14 +50,7 @@ public class ServerSecret extends CrossTldSingleton implements NonReplicatedEnti
* Supplier that can be reset for testing purposes.
*/
private static final LoadingCache<Class<ServerSecret>, ServerSecret> CACHE =
CacheBuilder.newBuilder()
.build(
new CacheLoader<Class<ServerSecret>, ServerSecret>() {
@Override
public ServerSecret load(Class<ServerSecret> unused) {
return retrieveAndSaveSecret();
}
});
CacheUtils.newCacheBuilder().build(singletonClazz -> retrieveAndSaveSecret());
private static ServerSecret retrieveAndSaveSecret() {
if (tm().isOfy()) {
@@ -84,11 +75,7 @@ public class ServerSecret extends CrossTldSingleton implements NonReplicatedEnti
/** Returns the global ServerSecret instance, creating it if one isn't already in Datastore. */
public static ServerSecret get() {
try {
return CACHE.get(ServerSecret.class);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return CACHE.get(ServerSecret.class);
}
/** Most significant 8 bytes of the UUID value (stored separately for legacy purposes). */
@@ -72,7 +72,7 @@ public final class Registries {
.stream()
.map(Key::getName)
.collect(toImmutableSet());
return Registry.getAll(tlds).stream()
return Registry.get(tlds).stream()
.map(e -> Maps.immutableEntry(e.getTldStr(), e.getTldType()))
.collect(entriesToImmutableMap());
} else {
@@ -105,7 +105,7 @@ public final class Registries {
/** Returns the Registry entities themselves of the given type loaded fresh from Datastore. */
public static ImmutableSet<Registry> getTldEntitiesOfType(TldType type) {
return Registry.getAll(filterValues(cache.get(), equalTo(type)).keySet());
return Registry.get(filterValues(cache.get(), equalTo(type)).keySet());
}
/** Pass-through check that the specified TLD exists, otherwise throw an IAE. */
@@ -142,10 +142,16 @@ public class Registry extends ImmutableObject
/** The type of TLD, which determines things like backups and escrow policy. */
public enum TldType {
/** A real, official TLD. */
/**
* A real, official TLD (but not necessarily only on production).
*
* <p>Note that, to avoid unnecessary costly DB writes, {@link
* google.registry.model.reporting.DomainTransactionRecord}s are only written out for REAL TLDs
* (these transaction records are only used for ICANN reporting purposes).
*/
REAL,
/** A test TLD, for the prober. */
/** A test TLD, for the prober, OT&amp;E, and other testing purposes. */
TEST
}
@@ -232,7 +238,7 @@ public class Registry extends ImmutableObject
}
/** Returns the registry entities for the given TLD strings, throwing if any don't exist. */
static ImmutableSet<Registry> getAll(Set<String> tlds) {
public static ImmutableSet<Registry> get(Set<String> tlds) {
try {
ImmutableMap<String, Optional<Registry>> registries = CACHE.getAll(tlds);
ImmutableSet<String> missingRegistries =
@@ -1000,7 +1006,7 @@ public class Registry extends ImmutableObject
instance.renewBillingCostTransitions.checkValidity();
instance.eapFeeSchedule.checkValidity();
// All costs must be in the expected currency.
// TODO(b/21854155): When we move PremiumList into Datastore, verify its currency too.
checkArgumentNotNull(instance.getCurrency(), "Currency must be set");
checkArgument(
instance.getStandardCreateCost().getCurrencyUnit().equals(instance.currency),
"Create cost must be in the registry's currency");
@@ -33,8 +33,10 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
/**
* A SQL transaction that can be serialized and stored in its own table.
@@ -105,7 +107,8 @@ public class Transaction extends ImmutableObject implements Buildable {
}
public static Transaction deserialize(byte[] serializedTransaction) throws IOException {
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializedTransaction));
ObjectInputStream in =
new LenientObjectInputStream(new ByteArrayInputStream(serializedTransaction));
// Verify that the data is what we expect.
int version = in.readInt();
@@ -304,4 +307,35 @@ public class Transaction extends ImmutableObject implements Buildable {
}
}
}
/**
* ObjectInputStream that ignores the UIDs of serialized objects.
*
* <p>We only really need to deserialize VKeys. However, VKeys have a class object associated with
* them, and if the class is changed and we haven't defined a serialVersionUID for it, we get an
* exception during deserialization.
*
* <p>It's safe for us to ignore this condition: we only care about attaching the correct local
* class object to the VKey. So this class effectively does so by replacing the class descriptor
* if it's version UID doesn't match that of the local class.
*/
private static class LenientObjectInputStream extends ObjectInputStream {
public LenientObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass persistedDescriptor = super.readClassDescriptor();
Class localClass = Class.forName(persistedDescriptor.getName());
ObjectStreamClass localDescriptor = ObjectStreamClass.lookup(localClass);
if (localDescriptor != null) {
if (persistedDescriptor.getSerialVersionUID() != localDescriptor.getSerialVersionUID()) {
return localDescriptor;
}
}
return persistedDescriptor;
}
}
}
@@ -24,14 +24,11 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import google.registry.flows.certs.CertificateChecker;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.tld.Registry;
import google.registry.tools.params.KeyValueMapParameter.CurrencyUnitToStringMap;
import google.registry.tools.params.OptionalLongParameter;
import google.registry.tools.params.OptionalPhoneNumberParameter;
@@ -46,7 +43,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.money.CurrencyUnit;
@@ -433,22 +429,6 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
// Require a phone passcode.
checkArgument(
newRegistrar.getPhonePasscode() != null, "--passcode is required for REAL registrars.");
// Check if registrar has billing account IDs for the currency of the TLDs that it is
// allowed to register.
ImmutableSet<CurrencyUnit> tldCurrencies =
newRegistrar
.getAllowedTlds()
.stream()
.map(tld -> Registry.get(tld).getCurrency())
.collect(toImmutableSet());
Set<CurrencyUnit> currenciesWithoutBillingAccountId =
newRegistrar.getBillingAccountMap() == null
? tldCurrencies
: Sets.difference(tldCurrencies, newRegistrar.getBillingAccountMap().keySet());
checkArgument(
currenciesWithoutBillingAccountId.isEmpty(),
"Need billing account map entries for currencies: %s",
Joiner.on(' ').join(currenciesWithoutBillingAccountId));
}
stageEntityChange(oldRegistrar, newRegistrar);
@@ -15,6 +15,7 @@
package google.registry.tools;
import com.google.common.collect.ImmutableMap;
import google.registry.tools.javascrap.BackfillRegistrarBillingAccountsCommand;
import google.registry.tools.javascrap.CompareEscrowDepositsCommand;
import google.registry.tools.javascrap.HardDeleteHostCommand;
@@ -30,6 +31,7 @@ public final class RegistryTool {
public static final ImmutableMap<String, Class<? extends Command>> COMMAND_MAP =
new ImmutableMap.Builder<String, Class<? extends Command>>()
.put("ack_poll_messages", AckPollMessagesCommand.class)
.put("backfill_registrar_billing_accounts", BackfillRegistrarBillingAccountsCommand.class)
.put("canonicalize_labels", CanonicalizeLabelsCommand.class)
.put("check_domain", CheckDomainCommand.class)
.put("check_domain_claims", CheckDomainClaimsCommand.class)
@@ -102,6 +104,7 @@ public final class RegistryTool {
.put("registrar_contact", RegistrarContactCommand.class)
.put("remove_registry_one_key", RemoveRegistryOneKeyCommand.class)
.put("renew_domain", RenewDomainCommand.class)
.put("replay_txns", ReplayTxnsCommand.class)
.put("resave_entities", ResaveEntitiesCommand.class)
.put("resave_environment_entities", ResaveEnvironmentEntitiesCommand.class)
.put("resave_epp_resource", ResaveEppResourceCommand.class)
@@ -43,6 +43,7 @@ import google.registry.request.Modules.UrlConnectionServiceModule;
import google.registry.request.Modules.UrlFetchServiceModule;
import google.registry.request.Modules.UserServiceModule;
import google.registry.tools.AuthModule.LocalCredentialModule;
import google.registry.tools.javascrap.BackfillRegistrarBillingAccountsCommand;
import google.registry.tools.javascrap.CompareEscrowDepositsCommand;
import google.registry.tools.javascrap.HardDeleteHostCommand;
import google.registry.util.UtilsModule;
@@ -90,6 +91,8 @@ import javax.inject.Singleton;
interface RegistryToolComponent {
void inject(AckPollMessagesCommand command);
void inject(BackfillRegistrarBillingAccountsCommand command);
void inject(CheckDomainClaimsCommand command);
void inject(CheckDomainCommand command);
@@ -0,0 +1,59 @@
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaJpaTm;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import google.registry.persistence.transaction.Transaction;
import google.registry.persistence.transaction.TransactionEntity;
import java.util.List;
@Parameters(separators = " =", commandDescription = "Replay a range of transactions.")
public class ReplayTxnsCommand implements CommandWithRemoteApi {
private static final int BATCH_SIZE = 200;
@Parameter(
names = {"-s", "--start-txn-id"},
description = "Transaction id to start replaying at.",
required = true)
long startTxnId;
@Override
public void run() throws Exception {
List<TransactionEntity> txns;
do {
txns =
replicaJpaTm()
.transact(
() ->
replicaJpaTm()
.query(
"SELECT txn FROM TransactionEntity txn where id >= :startTxn ORDER"
+ " BY id",
TransactionEntity.class)
.setParameter("startTxn", startTxnId)
.setMaxResults(BATCH_SIZE)
.getResultList());
for (TransactionEntity txn : txns) {
System.out.println("Replaying transaction " + txn.getId());
Transaction.deserialize(txn.getContents());
startTxnId = txn.getId() + 1;
}
} while (txns.size() > 0);
}
}
@@ -0,0 +1,56 @@
// Copyright 2021 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.javascrap;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.model.OteAccountBuilder.DEFAULT_BILLING_ACCOUNT_MAP;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.beust.jcommander.Parameters;
import google.registry.config.RegistryEnvironment;
import google.registry.model.registrar.Registrar;
import google.registry.tools.CommandWithRemoteApi;
/**
* Backfills the billing account maps on all Registrars that don't have any set.
*
* <p>This should not (and cannot) be used on production. Its purpose is to backfill these values on
* sandbox, where most registrars have an empty billing account map, including all that were created
* for OT&amp;E. The same default billing account map is used for all registrars, and includes
* values for USD and JPY. The actual values here don't matter as we don't do invoicing on sandbox
* anyway.
*/
@Parameters(separators = " =", commandDescription = "Backfill registrar billing account maps.")
public class BackfillRegistrarBillingAccountsCommand implements CommandWithRemoteApi {
@Override
public void run() throws Exception {
checkState(
RegistryEnvironment.get() != RegistryEnvironment.PRODUCTION,
"Do not run this on production");
System.out.println("Populating billing account maps on all registrars missing them ...");
tm().transact(
() ->
tm().loadAllOfStream(Registrar.class)
.filter(r -> r.getBillingAccountMap().isEmpty())
.forEach(
r ->
tm().update(
r.asBuilder()
.setBillingAccountMap(DEFAULT_BILLING_ACCOUNT_MAP)
.build())));
System.out.println("Done!");
}
}
@@ -22,17 +22,19 @@ import static google.registry.testing.DatabaseHelper.newRegistry;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static java.util.logging.Level.SEVERE;
import static org.joda.money.CurrencyUnit.CAD;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.testing.TestLogHandler;
import google.registry.beam.TestPipelineExtension;
import google.registry.model.billing.BillingEvent.Cancellation;
import google.registry.model.billing.BillingEvent.Flag;
@@ -59,7 +61,7 @@ import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.Optional;
import org.apache.beam.sdk.Pipeline.PipelineExecutionException;
import java.util.logging.Logger;
import org.apache.beam.sdk.coders.SerializableCoder;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.testing.PAssert;
@@ -252,9 +254,14 @@ class InvoicingPipelineTest {
private File billingBucketUrl;
private PCollection<BillingEvent> billingEvents;
private final TestLogHandler logHandler = new TestLogHandler();
private final Logger loggerToIntercept =
Logger.getLogger(InvoicingPipeline.class.getCanonicalName());
@BeforeEach
void beforeEach() throws Exception {
loggerToIntercept.addHandler(logHandler);
billingBucketUrl = Files.createDirectory(tmpDir.resolve(BILLING_BUCKET_URL)).toFile();
options.setBillingBucketUrl(billingBucketUrl.getAbsolutePath());
options.setYearMonth(YEAR_MONTH);
@@ -300,8 +307,9 @@ class InvoicingPipelineTest {
}
@Test
void testFailure_readFromCloudSqlMissingPAK() throws Exception {
Registrar registrar = persistNewRegistrar("TheRegistrar");
void testSuccess_readFromCloudSqlMissingPAK() throws Exception {
setupCloudSql();
Registrar registrar = persistNewRegistrar("ARegistrar");
registrar =
registrar
.asBuilder()
@@ -317,17 +325,16 @@ class InvoicingPipelineTest {
persistResource(test);
DomainBase domain = persistActiveDomain("mycanadiandomain.test");
persistOneTimeBillingEvent(1, domain, registrar, Reason.RENEW, 3, Money.of(CAD, 20.5));
persistOneTimeBillingEvent(25, domain, registrar, Reason.RENEW, 3, Money.of(CAD, 20.5));
PCollection<BillingEvent> billingEvents = InvoicingPipeline.readFromCloudSql(options, pipeline);
billingEvents = billingEvents.apply(new ChangeDomainRepo());
PAssert.that(billingEvents).empty();
PipelineExecutionException thrown =
assertThrows(PipelineExecutionException.class, () -> pipeline.run().waitUntilFinish());
assertThat(thrown)
.hasMessageThat()
.contains(
"Registrar TheRegistrar does not have a product account key for the currency unit:"
+ " CAD");
PAssert.that(billingEvents).containsInAnyOrder(INPUT_EVENTS);
pipeline.run().waitUntilFinish();
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(
SEVERE,
"Registrar ARegistrar does not have a product account key for the currency unit: CAD");
}
@Test
@@ -336,7 +336,11 @@ public class SyncRegistrarsSheetTest {
@TestOfyAndSql
void testRun_missingValues_stillWorks() throws Exception {
persistNewRegistrar("SomeRegistrar", "Some Registrar", Registrar.Type.REAL, 8L);
persistResource(
persistNewRegistrar("SomeRegistrar", "Some Registrar", Registrar.Type.REAL, 8L)
.asBuilder()
.setBillingAccountMap(ImmutableMap.of())
.build());
newSyncRegistrarsSheet().run("foobar");
@@ -30,6 +30,7 @@ import static google.registry.testing.DatabaseHelper.persistReservedList;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -57,6 +58,7 @@ import google.registry.flows.domain.DomainFlowUtils.FeeChecksDontSupportPhasesEx
import google.registry.flows.domain.DomainFlowUtils.InvalidIdnDomainLabelException;
import google.registry.flows.domain.DomainFlowUtils.InvalidPunycodeException;
import google.registry.flows.domain.DomainFlowUtils.LeadingDashException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.RestoresAreAlwaysForOneYearException;
import google.registry.flows.domain.DomainFlowUtils.TldDoesNotExistException;
@@ -600,6 +602,24 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccount() {
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown = assertThrows(MissingBillingAccountMapException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testSuccess_superuserNotAuthorizedForTld() throws Exception {
persistActiveDomain("example2.tld");
@@ -21,16 +21,20 @@ import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.flows.EppException;
import google.registry.flows.FlowUtils.NotLoggedInException;
import google.registry.flows.ResourceFlowTestCase;
import google.registry.flows.domain.DomainClaimsCheckFlow.DomainClaimsCheckNotAllowedWithAllocationTokens;
import google.registry.flows.domain.DomainFlowUtils.BadCommandForRegistryPhaseException;
import google.registry.flows.domain.DomainFlowUtils.ClaimsPeriodEndedException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.TldDoesNotExistException;
import google.registry.flows.exceptions.TooManyResourceChecksException;
@@ -40,6 +44,7 @@ import google.registry.model.tld.Registry.TldState;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.ReplayExtension;
import google.registry.testing.TestOfyAndSql;
import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -133,6 +138,24 @@ public class DomainClaimsCheckFlowTest
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccount() {
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown = assertThrows(MissingBillingAccountMapException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testSuccess_superuserNotAuthorizedForTld() throws Exception {
persistClaimsList(
@@ -59,6 +59,7 @@ import static google.registry.tmch.LordnTaskUtils.QUEUE_CLAIMS;
import static google.registry.tmch.LordnTaskUtils.QUEUE_SUNRISE;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -117,6 +118,7 @@ import google.registry.flows.domain.DomainFlowUtils.LinkedResourcesDoNotExistExc
import google.registry.flows.domain.DomainFlowUtils.MalformedTcnIdException;
import google.registry.flows.domain.DomainFlowUtils.MaxSigLifeNotSupportedException;
import google.registry.flows.domain.DomainFlowUtils.MissingAdminContactException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.MissingClaimsNoticeException;
import google.registry.flows.domain.DomainFlowUtils.MissingContactTypeException;
import google.registry.flows.domain.DomainFlowUtils.MissingRegistrantException;
@@ -2222,6 +2224,25 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccountMap() {
persistContactsAndHosts();
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown = assertThrows(MissingBillingAccountMapException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_registrantNotAllowListed() {
persistActiveContact("someone");
@@ -35,6 +35,7 @@ import static google.registry.testing.TestDataHelper.updateSubstitutions;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.EUR;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -55,6 +56,7 @@ import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsException;
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
@@ -122,6 +124,11 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
@BeforeEach
void initDomainTest() {
createTld("tld");
persistResource(
loadRegistrar("TheRegistrar")
.asBuilder()
.setBillingAccountMap(ImmutableMap.of(USD, "123", EUR, "567"))
.build());
setEppInput("domain_renew.xml", ImmutableMap.of("DOMAIN", "example.tld", "YEARS", "5"));
}
@@ -759,6 +766,25 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, DomainBa
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccountMap() throws Exception {
persistDomain();
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown = assertThrows(MissingBillingAccountMapException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_pendingTransfer() throws Exception {
persistDomain();
@@ -34,6 +34,7 @@ import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.EUR;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -53,6 +54,7 @@ import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
import google.registry.flows.domain.DomainFlowUtils.DomainReservedException;
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
@@ -106,6 +108,11 @@ class DomainRestoreRequestFlowTest
@BeforeEach
void initDomainTest() {
createTld("tld");
persistResource(
loadRegistrar("TheRegistrar")
.asBuilder()
.setBillingAccountMap(ImmutableMap.of(USD, "123", EUR, "567"))
.build());
setEppInput("domain_update_restore_request.xml", ImmutableMap.of("DOMAIN", "example.tld"));
}
@@ -705,6 +712,25 @@ class DomainRestoreRequestFlowTest
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccount() throws Exception {
persistPendingDeleteDomain();
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown = assertThrows(MissingBillingAccountMapException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testSuccess_superuserNotAuthorizedForTld() throws Exception {
persistResource(
@@ -44,6 +44,7 @@ import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptio
import static google.registry.testing.HistoryEntrySubject.assertAboutHistoryEntries;
import static google.registry.testing.HostResourceSubject.assertAboutHosts;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -70,6 +71,7 @@ import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchExceptio
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException;
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
import google.registry.flows.domain.DomainFlowUtils.PremiumNameBlockedException;
import google.registry.flows.domain.DomainFlowUtils.RegistrarMustBeActiveForThisOperationException;
@@ -1065,6 +1067,30 @@ class DomainTransferRequestFlowTest
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testFailure_missingBillingAccount() {
setupDomain("example", "tld");
persistResource(
Registry.get("tld")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.ofMajor(JPY, 800))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.ofMajor(JPY, 800)))
.setRegistryLockOrUnlockBillingCost(Money.ofMajor(JPY, 800))
.setServerStatusChangeBillingCost(Money.ofMajor(JPY, 800))
.setRestoreBillingCost(Money.ofMajor(JPY, 800))
.build());
EppException thrown =
assertThrows(
MissingBillingAccountMapException.class,
() ->
doSuccessfulTest(
"domain_transfer_request.xml", "domain_transfer_request_response.xml"));
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
@TestOfyAndSql
void testSuccess_superuserNotAuthorizedForTld() throws Exception {
setupDomain("example", "tld");
@@ -225,7 +225,9 @@ public final class OteAccountBuilderTest {
OteAccountBuilder oteSetupHelper = OteAccountBuilder.forRegistrarId("myclientid");
assertThat(assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist()))
IllegalStateException thrown =
assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist());
assertThat(thrown)
.hasMessageThat()
.contains("Found existing object(s) conflicting with OT&E objects");
}
@@ -236,7 +238,9 @@ public final class OteAccountBuilderTest {
OteAccountBuilder oteSetupHelper = OteAccountBuilder.forRegistrarId("myclientid");
assertThat(assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist()))
IllegalStateException thrown =
assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist());
assertThat(thrown)
.hasMessageThat()
.contains("Found existing object(s) conflicting with OT&E objects");
}
@@ -131,10 +131,11 @@ public class DatabaseMigrationStateScheduleTest extends EntityTestCase {
.put(startTime.plusHours(2), DATASTORE_PRIMARY_NO_ASYNC)
.put(startTime.plusHours(3), DATASTORE_PRIMARY_READ_ONLY)
.build();
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> jpaTm().transact(() -> DatabaseMigrationStateSchedule.set(nowInvalidMap))))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> jpaTm().transact(() -> DatabaseMigrationStateSchedule.set(nowInvalidMap)));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"Cannot transition from current state-as-of-now DATASTORE_ONLY "
@@ -143,14 +144,13 @@ public class DatabaseMigrationStateScheduleTest extends EntityTestCase {
@Test
void testFailure_notInTransaction() {
assertThat(
assertThrows(
IllegalStateException.class,
() ->
DatabaseMigrationStateSchedule.set(
DatabaseMigrationStateSchedule.DEFAULT_TRANSITION_MAP.toValueMap())))
.hasMessageThat()
.isEqualTo("Not in a transaction");
IllegalStateException thrown =
assertThrows(
IllegalStateException.class,
() ->
DatabaseMigrationStateSchedule.set(
DatabaseMigrationStateSchedule.DEFAULT_TRANSITION_MAP.toValueMap()));
assertThat(thrown).hasMessageThat().isEqualTo("Not in a transaction");
}
@Test
@@ -188,10 +188,11 @@ public class DatabaseMigrationStateScheduleTest extends EntityTestCase {
private void runInvalidTransition(MigrationState from, MigrationState to) {
ImmutableSortedMap<DateTime, MigrationState> transitions =
createMapEndingWithTransition(from, to);
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> jpaTm().transact(() -> DatabaseMigrationStateSchedule.set(transitions))))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> jpaTm().transact(() -> DatabaseMigrationStateSchedule.set(transitions)));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
String.format("validStateTransitions map cannot transition from %s to %s.", from, to));
@@ -197,12 +197,8 @@ public class AllocationTokenTest extends EntityTestCase {
.build());
AllocationToken loadedToken = loadByEntity(token);
assertThat(token).isEqualTo(loadedToken);
AllocationToken modifiedToken =
persistResource(
loadedToken
.asBuilder()
.setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED)
.build());
persistResource(
loadedToken.asBuilder().setRenewalPriceBehavior(RenewalPriceBehavior.SPECIFIED).build());
assertThat(loadByEntity(token).getRenewalPriceBehavior())
.isEqualTo(RenewalPriceBehavior.SPECIFIED);
}
@@ -30,11 +30,14 @@ import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.money.CurrencyUnit.USD;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.googlecode.objectify.Key;
import google.registry.config.RegistryConfig;
@@ -42,13 +45,17 @@ import google.registry.model.EntityTestCase;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.Registrar.Type;
import google.registry.model.tld.Registries;
import google.registry.model.tld.Registry;
import google.registry.model.tld.Registry.TldType;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import google.registry.testing.TestOfyOnly;
import google.registry.testing.TestSqlOnly;
import google.registry.util.CidrAddressBlock;
import google.registry.util.SerializeUtils;
import java.math.BigDecimal;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach;
/** Unit tests for {@link Registrar}. */
@@ -60,7 +67,20 @@ class RegistrarTest extends EntityTestCase {
@BeforeEach
void setUp() {
createTld("xn--q9jyb4c");
createTld("tld");
persistResource(
newRegistry("xn--q9jyb4c", "MINNA")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.of(JPY, new BigDecimal(1300)))
.setRestoreBillingCost(Money.of(JPY, new BigDecimal(1700)))
.setServerStatusChangeBillingCost(Money.of(JPY, new BigDecimal(1900)))
.setRegistryLockOrUnlockBillingCost(Money.of(JPY, new BigDecimal(2700)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.of(JPY, new BigDecimal(1100))))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(JPY)))
.setPremiumList(null)
.build());
// Set up a new persisted registrar entity.
registrar =
cloneAndSetAutoTimestamps(
@@ -251,8 +271,10 @@ class RegistrarTest extends EntityTestCase {
}
@TestOfyAndSql
void testSuccess_clearingBillingAccountMap() {
registrar = registrar.asBuilder().setBillingAccountMap(null).build();
void testSuccess_clearingBillingAccountMapAndAllowedTlds() {
registrar =
registrar.asBuilder().setAllowedTlds(ImmutableSet.of()).setBillingAccountMap(null).build();
assertThat(registrar.getAllowedTlds()).isEmpty();
assertThat(registrar.getBillingAccountMap()).isEmpty();
}
@@ -677,4 +699,48 @@ class RegistrarTest extends EntityTestCase {
assertThrows(IllegalArgumentException.class, () -> Registrar.loadByRegistrarIdCached(""));
assertThat(thrown).hasMessageThat().contains("registrarId must be specified");
}
@TestOfyAndSql
void testFailure_missingCurrenciesFromBillingMap() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
registrar
.asBuilder()
.setBillingAccountMap(null)
.setAllowedTlds(ImmutableSet.of("tld", "xn--q9jyb4c"))
.build());
assertThat(thrown)
.hasMessageThat()
.contains("their currency is missing from the billing account map: [tld, xn--q9jyb4c]");
}
@TestOfyAndSql
void testFailure_missingCurrencyFromBillingMap() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
registrar
.asBuilder()
.setBillingAccountMap(ImmutableMap.of(USD, "abc123"))
.setAllowedTlds(ImmutableSet.of("tld", "xn--q9jyb4c"))
.build());
assertThat(thrown)
.hasMessageThat()
.contains("their currency is missing from the billing account map: [xn--q9jyb4c]");
}
@TestOfyAndSql
void testSuccess_nonRealTldDoesntNeedEntryInBillingMap() {
persistResource(Registry.get("xn--q9jyb4c").asBuilder().setTldType(TldType.TEST).build());
// xn--q9jyb4c bills in JPY and we don't have a JPY entry in this billing account map, but it
// should succeed without throwing an error because xn--q9jyb4c is set to be a TEST TLD.
registrar
.asBuilder()
.setBillingAccountMap(ImmutableMap.of(USD, "abc123"))
.setAllowedTlds(ImmutableSet.of("tld", "xn--q9jyb4c"))
.build();
}
}
@@ -16,6 +16,7 @@ package google.registry.model.tld;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
import static google.registry.testing.SqlHelper.getMostRecentUnlockedRegistryLockByRepoId;
@@ -67,7 +68,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
() -> {
RegistryLock fromDatabase =
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
assertThat(fromDatabase.getLockCompletionTime().get()).isEqualTo(fakeClock.nowUtc());
assertThat(fromDatabase.getLockCompletionTime()).hasValue(fakeClock.nowUtc());
assertThat(fromDatabase.getLastUpdateTime()).isEqualTo(fakeClock.nowUtc());
});
}
@@ -87,7 +88,7 @@ public final class RegistryLockDaoTest extends EntityTestCase {
assertThat(fromDatabase.getUnlockRequestTime()).isEqualTo(Optional.of(fakeClock.nowUtc()));
assertThat(fromDatabase.getUnlockCompletionTime()).isEqualTo(Optional.of(fakeClock.nowUtc()));
assertThat(fromDatabase.isLocked()).isFalse();
assertThat(fromDatabase.getRelockDuration().get()).isEqualTo(Duration.standardHours(6));
assertThat(fromDatabase.getRelockDuration()).hasValue(Duration.standardHours(6));
}
@Test
@@ -190,7 +190,7 @@ public final class RegistryTest extends EntityTestCase {
@TestOfyAndSql
void testGetAll() {
createTld("foo");
assertThat(Registry.getAll(ImmutableSet.of("foo", "tld")))
assertThat(Registry.get(ImmutableSet.of("foo", "tld")))
.containsExactlyElementsIn(
tm().transact(
() ->
@@ -261,8 +261,8 @@ public final class RegistryTest extends EntityTestCase {
Registry registry = Registry.get("tld").asBuilder().setPremiumList(pl2).build();
Optional<String> pl = registry.getPremiumListName();
assertThat(pl).hasValue("tld2");
PremiumList stored = PremiumListDao.getLatestRevision(pl.get()).get();
assertThat(stored.getName()).isEqualTo("tld2");
assertThat(PremiumListDao.getLatestRevision("tld2")).isPresent();
assertThat(PremiumListDao.getLatestRevision("tld2").get().getName()).isEqualTo("tld2");
}
@TestOfyAndSql
@@ -261,7 +261,7 @@ public class PremiumListDaoTest {
assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).isNull();
PremiumListDao.save(testList);
PremiumList pl = PremiumListDao.getLatestRevision("testname").get();
assertThat(PremiumListDao.premiumListCache.getIfPresent("testname").get()).isEqualTo(pl);
assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).hasValue(pl);
TransactionManagerUtil.transactIfJpaTm(
() -> PremiumListDao.save("testname", USD, ImmutableList.of("test,USD 1")));
assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).isNull();
@@ -16,6 +16,7 @@ package google.registry.model.tld.label;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistReservedList;
@@ -100,8 +101,8 @@ public class PremiumListTest {
@Test
void testParse_canIncludeOrNotIncludeCurrencyUnit() {
PremiumListDao.save("tld", USD, ImmutableList.of("rofl,USD 90", "paper, 80"));
assertThat(PremiumListDao.getPremiumPrice("tld", "rofl").get()).isEqualTo(Money.of(USD, 90));
assertThat(PremiumListDao.getPremiumPrice("tld", "paper").get()).isEqualTo(Money.of(USD, 80));
assertThat(PremiumListDao.getPremiumPrice("tld", "rofl")).hasValue(Money.of(USD, 90));
assertThat(PremiumListDao.getPremiumPrice("tld", "paper")).hasValue(Money.of(USD, 80));
}
@Test
@@ -15,9 +15,9 @@
package google.registry.model.tmch;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import google.registry.model.EntityTestCase;
import java.util.Optional;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link TmchCrl}. */
@@ -29,7 +29,7 @@ public class TmchCrlTest extends EntityTestCase {
@Test
void testSuccess() {
assertThat(TmchCrl.get()).isEqualTo(Optional.empty());
assertThat(TmchCrl.get()).isEmpty();
TmchCrl.set("lolcat", "https://lol.cat");
assertThat(TmchCrl.get().get().getCrl()).isEqualTo("lolcat");
}
@@ -73,8 +73,10 @@ final class AbstractJsonableObjectTest {
@JsonableElement String myString = "A";
@JsonableElement("myString") String anotherString = "B";
};
assertThat(assertThrows(JsonableException.class, () -> jsonable.toJson()))
.hasMessageThat().contains("Encountered the same field name 'myString' multiple times");
JsonableException thrown = assertThrows(JsonableException.class, () -> jsonable.toJson());
assertThat(thrown)
.hasMessageThat()
.contains("Encountered the same field name 'myString' multiple times");
}
@Test
@@ -96,8 +98,8 @@ final class AbstractJsonableObjectTest {
return in;
}
};
assertThat(assertThrows(JsonableException.class, () -> jsonable.toJson()))
.hasMessageThat().contains("must have no arguments");
JsonableException thrown = assertThrows(JsonableException.class, () -> jsonable.toJson());
assertThat(thrown).hasMessageThat().contains("must have no arguments");
}
@Test
@@ -186,8 +188,10 @@ final class AbstractJsonableObjectTest {
@JsonableElement("myList[]")
Optional<Integer> myListMeaningOfLife = Optional.of(42);
};
assertThat(assertThrows(JsonableException.class, () -> jsonable.toJson()))
.hasMessageThat().contains("Encountered the same field name 'myList' multiple times");
JsonableException thrown = assertThrows(JsonableException.class, () -> jsonable.toJson());
assertThat(thrown)
.hasMessageThat()
.contains("Encountered the same field name 'myList' multiple times");
}
@RestrictJsonNames({"allowed", "allowedList[]"})
@@ -226,7 +230,8 @@ final class AbstractJsonableObjectTest {
@JsonableElement
JsonableWithNameRestrictions wrong = new JsonableWithNameRestrictions();
};
assertThat(assertThrows(JsonableException.class, () -> jsonable.toJson()))
JsonableException thrown = assertThrows(JsonableException.class, () -> jsonable.toJson());
assertThat(thrown)
.hasMessageThat()
.contains("must be named one of ['allowed', 'allowedList[]'], but is named 'wrong'");
}
@@ -237,9 +242,8 @@ final class AbstractJsonableObjectTest {
@JsonableElement
JsonableWithNoAllowedNames wrong = new JsonableWithNoAllowedNames();
};
assertThat(assertThrows(JsonableException.class, () -> jsonable.toJson()))
.hasMessageThat()
.contains("is annotated with an empty RestrictJsonNames");
JsonableException thrown = assertThrows(JsonableException.class, () -> jsonable.toJson());
assertThat(thrown).hasMessageThat().contains("is annotated with an empty RestrictJsonNames");
}
@RestrictJsonNames({})
@@ -232,17 +232,15 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
@TestOfyAndSql
void testNoTlds() {
deleteTld("tld");
assertThat(assertThrows(IllegalArgumentException.class, action::run))
.hasMessageThat()
.isEqualTo("There must exist at least one REAL TLD.");
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run);
assertThat(thrown).hasMessageThat().isEqualTo("There must exist at least one REAL TLD.");
}
@TestOfyAndSql
void testOnlyTestTlds() {
persistResource(Registry.get("tld").asBuilder().setTldType(TldType.TEST).build());
assertThat(assertThrows(IllegalArgumentException.class, action::run))
.hasMessageThat()
.isEqualTo("There must exist at least one REAL TLD.");
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run);
assertThat(thrown).hasMessageThat().isEqualTo("There must exist at least one REAL TLD.");
}
@TestOfyAndSql
@@ -278,7 +276,8 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
httpTransport.addNextResponse(badLoginResponse);
httpTransport.addNextResponse(badLoginResponse);
assertThat(assertThrows(RuntimeException.class, action::run))
RuntimeException thrown = assertThrows(RuntimeException.class, action::run);
assertThat(thrown)
.hasMessageThat()
.isEqualTo("Error contacting MosAPI server. Tried TLDs [secondtld, tld]");
}
@@ -316,9 +315,8 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest {
httpTransport.addNextResponse(logoutResponse);
httpTransport.addNextResponse(badLoginResponse);
assertThat(assertThrows(RuntimeException.class, action::run))
.hasCauseThat()
.isInstanceOf(JsonSyntaxException.class);
RuntimeException thrown = assertThrows(RuntimeException.class, action::run);
assertThat(thrown).hasCauseThat().isInstanceOf(JsonSyntaxException.class);
}
private static void addValidResponses(TestHttpTransport httpTransport) {
@@ -403,9 +403,9 @@ class AuthenticatedRegistrarAccessorTest {
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
assertThat(assertThrows(RegistrarAccessDeniedException.class, registrarAccessor::guessClientId))
.hasMessageThat()
.isEqualTo("TestUserId isn't associated with any registrar");
RegistrarAccessDeniedException thrown =
assertThrows(RegistrarAccessDeniedException.class, registrarAccessor::guessClientId);
assertThat(thrown).hasMessageThat().isEqualTo("TestUserId isn't associated with any registrar");
}
@TestOfyAndSql
@@ -66,6 +66,7 @@ import java.util.Set;
import java.util.logging.LogManager;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.joda.money.CurrencyUnit;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -289,6 +290,7 @@ public final class AppEngineExtension implements BeforeEachCallback, AfterEachCa
.build())
.setPhoneNumber("+1.3334445555")
.setPhonePasscode("12345")
.setBillingAccountMap(ImmutableMap.of(CurrencyUnit.USD, "abc123"))
.setContactsRequireSyncing(true);
}
@@ -762,6 +762,7 @@ public class DatabaseHelper {
.setType(type)
.setState(State.ACTIVE)
.setIanaIdentifier(ianaIdentifier)
.setBillingAccountMap(ImmutableMap.of(USD, "abc123"))
.setLocalizedAddress(
new RegistrarAddress.Builder()
.setStreet(ImmutableList.of("123 Fake St"))
@@ -61,41 +61,38 @@ abstract class CreateOrUpdateReservedListCommandTestCase<
@Test
void testFailure_fileDoesntExist() {
assertThat(
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + reservedTermsPath + "-nonexistent")))
.hasMessageThat()
.contains("-i not found");
ParameterException thrown =
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + reservedTermsPath + "-nonexistent"));
assertThat(thrown).hasMessageThat().contains("-i not found");
}
@Test
void testFailure_fileDoesntParse() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + invalidReservedTermsPath)))
.hasMessageThat()
.contains("No enum constant");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved", "--input=" + invalidReservedTermsPath));
assertThat(thrown).hasMessageThat().contains("No enum constant");
}
@Test
void testFailure_invalidLabel_includesFullDomainName() throws Exception {
Files.asCharSink(new File(invalidReservedTermsPath), UTF_8)
.write("example.tld,FULLY_BLOCKED\n\n");
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + invalidReservedTermsPath)))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved", "--input=" + invalidReservedTermsPath));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("Label example.tld must not be a multi-level domain name");
}
@@ -21,8 +21,11 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.newRegistry;
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
@@ -43,8 +46,10 @@ import google.registry.testing.DualDatabaseTest;
import google.registry.testing.InjectExtension;
import google.registry.testing.TestOfyAndSql;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -604,11 +609,11 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
Optional<Registrar> registrar = Registrar.loadByRegistrarId("clientz");
assertThat(registrar).isPresent();
assertThat(registrar.get().getBillingAccountMap())
.containsExactly(CurrencyUnit.USD, "abc123", CurrencyUnit.JPY, "789xyz");
.containsExactly(CurrencyUnit.USD, "abc123", JPY, "789xyz");
}
@TestOfyAndSql
void testFailure_billingAccountMap_doesNotContainEntryForTldAllowed() {
void testFailure_billingAccountMap_doesNotContainEntryForAllowedTld() {
createTlds("foo");
IllegalArgumentException thrown =
@@ -632,12 +637,26 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
"--cc US",
"--force",
"clientz"));
assertThat(thrown).hasMessageThat().contains("USD");
assertThat(thrown)
.hasMessageThat()
.contains("their currency is missing from the billing account map: [foo]");
}
@TestOfyAndSql
void testSuccess_billingAccountMap_onlyAppliesToRealRegistrar() throws Exception {
createTlds("foo");
persistResource(
newRegistry("foo", "FOO")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.of(JPY, new BigDecimal(1300)))
.setRestoreBillingCost(Money.of(JPY, new BigDecimal(1700)))
.setServerStatusChangeBillingCost(Money.of(JPY, new BigDecimal(1900)))
.setRegistryLockOrUnlockBillingCost(Money.of(JPY, new BigDecimal(2700)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.of(JPY, new BigDecimal(1100))))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(JPY)))
.setPremiumList(null)
.build());
runCommandForced(
"--name=blobio",
@@ -656,7 +675,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
Optional<Registrar> registrar = Registrar.loadByRegistrarId("clientz");
assertThat(registrar).isPresent();
assertThat(registrar.get().getBillingAccountMap()).containsExactly(CurrencyUnit.JPY, "789xyz");
assertThat(registrar.get().getBillingAccountMap()).containsExactly(JPY, "789xyz");
}
@TestOfyAndSql
@@ -60,7 +60,6 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.junit.jupiter.MockitoSettings;
@@ -317,12 +316,13 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty()));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("A pending unlock action already exists for example.tld");
}
@@ -332,37 +332,38 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true);
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty()));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.tld");
}
@TestOfyAndSql
void testFailure_createLock_unknownDomain() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
"asdf.tld", "TheRegistrar", POC_ID, false)))
.hasMessageThat()
.isEqualTo("Domain doesn't exist");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
"asdf.tld", "TheRegistrar", POC_ID, false));
assertThat(thrown).hasMessageThat().isEqualTo("Domain doesn't exist");
}
@TestOfyAndSql
void testFailure_createLock_alreadyPendingLock() {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
DOMAIN_NAME, "TheRegistrar", POC_ID, false)))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
DOMAIN_NAME, "TheRegistrar", POC_ID, false));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("A pending or completed lock action already exists for example.tld");
}
@@ -370,26 +371,24 @@ public final class DomainLockUtilsTest {
@TestOfyAndSql
void testFailure_createLock_alreadyLocked() {
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
DOMAIN_NAME, "TheRegistrar", POC_ID, false)))
.hasMessageThat()
.isEqualTo("Domain example.tld is already locked");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryLockRequest(
DOMAIN_NAME, "TheRegistrar", POC_ID, false));
assertThat(thrown).hasMessageThat().isEqualTo("Domain example.tld is already locked");
}
@TestOfyAndSql
void testFailure_createUnlock_alreadyUnlocked() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty())))
.hasMessageThat()
.isEqualTo("Domain example.tld is already unlocked");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty()));
assertThat(thrown).hasMessageThat().isEqualTo("Domain example.tld is already unlocked");
}
@TestOfyAndSql
@@ -398,12 +397,11 @@ public final class DomainLockUtilsTest {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
domain = loadByEntity(domain);
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false)))
.hasMessageThat()
.isEqualTo("Domain example.tld is already locked");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false));
assertThat(thrown).hasMessageThat().isEqualTo("Domain example.tld is already locked");
assertNoDomainChanges();
}
@@ -412,12 +410,11 @@ public final class DomainLockUtilsTest {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
clock.advanceBy(standardDays(1));
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true)))
.hasMessageThat()
.isEqualTo("The pending lock has expired; please try again");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true));
assertThat(thrown).hasMessageThat().isEqualTo("The pending lock has expired; please try again");
assertNoDomainChanges();
}
@@ -425,12 +422,11 @@ public final class DomainLockUtilsTest {
void testFailure_applyLock_nonAdmin_applyAdminLock() {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true);
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false)))
.hasMessageThat()
.isEqualTo("Non-admin user cannot complete admin lock");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false));
assertThat(thrown).hasMessageThat().isEqualTo("Non-admin user cannot complete admin lock");
assertNoDomainChanges();
}
@@ -444,12 +440,11 @@ public final class DomainLockUtilsTest {
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false);
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false)))
.hasMessageThat()
.isEqualTo("Domain example.tld is already unlocked");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false));
assertThat(thrown).hasMessageThat().isEqualTo("Domain example.tld is already unlocked");
assertNoDomainChanges();
}
@@ -461,12 +456,11 @@ public final class DomainLockUtilsTest {
// reload to pick up modification times, etc
lock = getRegistryLockByVerificationCode(verificationCode).get();
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(verificationCode, false)))
.hasMessageThat()
.isEqualTo("Domain example.tld is already locked");
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.verifyAndApplyLock(verificationCode, false));
assertThat(thrown).hasMessageThat().isEqualTo("Domain example.tld is already locked");
// Failure during Datastore portion shouldn't affect the SQL object
RegistryLock afterAction = getRegistryLockByVerificationCode(lock.getVerificationCode()).get();
@@ -517,10 +511,11 @@ public final class DomainLockUtilsTest {
.setRegistrarPocId("someone@example.com")
.setVerificationCode("hi")
.build());
assertThat(
Assert.assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.enqueueDomainRelock(lockWithoutDuration)))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> domainLockUtils.enqueueDomainRelock(lockWithoutDuration));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
String.format(
@@ -139,14 +139,15 @@ public class SetDatabaseMigrationStateCommandTest
@TestOfyAndSql
void testFailure_invalidTransition() {
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
String.format(
"--migration_schedule=%s=DATASTORE_ONLY,%s=DATASTORE_PRIMARY_READ_ONLY",
START_OF_TIME, START_OF_TIME.plusHours(1)))))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
String.format(
"--migration_schedule=%s=DATASTORE_ONLY,%s=DATASTORE_PRIMARY_READ_ONLY",
START_OF_TIME, START_OF_TIME.plusHours(1))));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"validStateTransitions map cannot transition from DATASTORE_ONLY "
@@ -158,18 +159,16 @@ public class SetDatabaseMigrationStateCommandTest
// The map we pass in is valid by itself, but we can't go from DATASTORE_ONLY now to
// DATASTORE_PRIMARY_READ_ONLY now
DateTime now = fakeClock.nowUtc();
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
String.format(
"--migration_schedule=%s=DATASTORE_ONLY,%s=DATASTORE_PRIMARY,"
+ "%s=DATASTORE_PRIMARY_NO_ASYNC,%s=DATASTORE_PRIMARY_READ_ONLY",
START_OF_TIME,
now.minusHours(3),
now.minusHours(2),
now.minusHours(1)))))
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
String.format(
"--migration_schedule=%s=DATASTORE_ONLY,%s=DATASTORE_PRIMARY,"
+ "%s=DATASTORE_PRIMARY_NO_ASYNC,%s=DATASTORE_PRIMARY_READ_ONLY",
START_OF_TIME, now.minusHours(3), now.minusHours(2), now.minusHours(1))));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(
"Cannot transition from current state-as-of-now DATASTORE_ONLY "
@@ -21,8 +21,10 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT3;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT3_HASH;
import static google.registry.testing.DatabaseHelper.createTlds;
import static google.registry.testing.DatabaseHelper.loadRegistrar;
import static google.registry.testing.DatabaseHelper.newRegistry;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.joda.time.DateTimeZone.UTC;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -38,8 +40,10 @@ import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.Registrar.Type;
import google.registry.testing.AppEngineExtension;
import google.registry.util.CidrAddressBlock;
import java.math.BigDecimal;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -359,6 +363,8 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
@Test
void testSuccess_billingAccountMap() throws Exception {
persistResource(
loadRegistrar("NewRegistrar").asBuilder().setBillingAccountMap(ImmutableMap.of()).build());
assertThat(loadRegistrar("NewRegistrar").getBillingAccountMap()).isEmpty();
runCommand("--billing_account_map=USD=abc123,JPY=789xyz", "--force", "NewRegistrar");
assertThat(loadRegistrar("NewRegistrar").getBillingAccountMap())
@@ -366,8 +372,14 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
}
@Test
void testFailure_billingAccountMap_doesNotContainEntryForTldAllowed() {
void testFailure_billingAccountMap_doesNotContainEntryForAllowedTld() {
createTlds("foo");
persistResource(
loadRegistrar("NewRegistrar")
.asBuilder()
.setAllowedTlds(ImmutableSet.of())
.setBillingAccountMap(ImmutableMap.of())
.build());
assertThat(loadRegistrar("NewRegistrar").getBillingAccountMap()).isEmpty();
IllegalArgumentException thrown =
assertThrows(
@@ -379,12 +391,28 @@ class UpdateRegistrarCommandTest extends CommandTestCase<UpdateRegistrarCommand>
"--force",
"--registrar_type=REAL",
"NewRegistrar"));
assertThat(thrown).hasMessageThat().contains("USD");
assertThat(thrown)
.hasMessageThat()
.contains("their currency is missing from the billing account map: [foo]");
}
@Test
void testSuccess_billingAccountMap_onlyAppliesToRealRegistrar() throws Exception {
createTlds("foo");
persistResource(
newRegistry("foo", "FOO")
.asBuilder()
.setCurrency(JPY)
.setCreateBillingCost(Money.of(JPY, new BigDecimal(1300)))
.setRestoreBillingCost(Money.of(JPY, new BigDecimal(1700)))
.setServerStatusChangeBillingCost(Money.of(JPY, new BigDecimal(1900)))
.setRegistryLockOrUnlockBillingCost(Money.of(JPY, new BigDecimal(2700)))
.setRenewBillingCostTransitions(
ImmutableSortedMap.of(START_OF_TIME, Money.of(JPY, new BigDecimal(1100))))
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(JPY)))
.setPremiumList(null)
.build());
persistResource(
loadRegistrar("NewRegistrar").asBuilder().setBillingAccountMap(ImmutableMap.of()).build());
assertThat(loadRegistrar("NewRegistrar").getBillingAccountMap()).isEmpty();
runCommand("--billing_account_map=JPY=789xyz", "--allowed_tlds=foo", "--force", "NewRegistrar");
assertThat(loadRegistrar("NewRegistrar").getBillingAccountMap())
@@ -51,7 +51,7 @@ class FormFieldTest {
@Test
void testConvert_emptyString_returnsEmpty() {
assertThat(FormField.named("lol").build().convert("").get()).isEmpty();
assertThat(FormField.named("lol").build().convert("")).hasValue("");
}
@Test
@@ -249,7 +249,8 @@ class FormFieldTest {
@Test
void testAsList_empty_returnsEmpty() {
assertThat(FormField.named("lol").asList().build().convert(ImmutableList.of()).get()).isEmpty();
assertThat(FormField.named("lol").asList().build().convert(ImmutableList.of()))
.hasValue(ImmutableList.of());
}
@Test
@@ -277,16 +278,16 @@ class FormFieldTest {
void testAsEnum() {
FormField<String, ICanHazEnum> omgField =
FormField.named("omg").asEnum(ICanHazEnum.class).build();
assertThat(omgField.convert("LOL").get()).isEqualTo(ICanHazEnum.LOL);
assertThat(omgField.convert("CAT").get()).isEqualTo(ICanHazEnum.CAT);
assertThat(omgField.convert("LOL")).hasValue(ICanHazEnum.LOL);
assertThat(omgField.convert("CAT")).hasValue(ICanHazEnum.CAT);
}
@Test
void testAsEnum_lowercase_works() {
FormField<String, ICanHazEnum> omgField =
FormField.named("omg").asEnum(ICanHazEnum.class).build();
assertThat(omgField.convert("lol").get()).isEqualTo(ICanHazEnum.LOL);
assertThat(omgField.convert("cat").get()).isEqualTo(ICanHazEnum.CAT);
assertThat(omgField.convert("lol")).hasValue(ICanHazEnum.LOL);
assertThat(omgField.convert("cat")).hasValue(ICanHazEnum.CAT);
}
@Test
@@ -226,25 +226,22 @@ final class RegistryLockGetActionTest {
@Test
void testFailure_invalidMethod() {
action.method = Method.POST;
assertThat(assertThrows(IllegalArgumentException.class, action::run))
.hasMessageThat()
.isEqualTo("Only GET requests allowed");
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run);
assertThat(thrown).hasMessageThat().isEqualTo("Only GET requests allowed");
}
@Test
void testFailure_noAuthInfo() {
action.authResult = AuthResult.NOT_AUTHENTICATED;
assertThat(assertThrows(IllegalArgumentException.class, action::run))
.hasMessageThat()
.isEqualTo("User auth info must be present");
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run);
assertThat(thrown).hasMessageThat().isEqualTo("User auth info must be present");
}
@Test
void testFailure_noClientId() {
action.paramClientId = Optional.empty();
assertThat(assertThrows(IllegalArgumentException.class, action::run))
.hasMessageThat()
.isEqualTo("clientId must be present");
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, action::run);
assertThat(thrown).hasMessageThat().isEqualTo("clientId must be present");
}
@Test
+1 -1
View File
@@ -18,7 +18,7 @@ ext {
dependencyList = [
'args4j:args4j:2.0.26',
'com.beust:jcommander:1.60',
'com.github.ben-manes.caffeine:caffeine:3.0.6',
'com.github.ben-manes.caffeine:caffeine:2.9.3',
'com.google.api:gax:1.66.0',
'com.google.api.grpc:proto-google-cloud-secretmanager-v1:1.4.0',
// The two below are needed only for Datastore bulk delete pipeline.
+6
View File
@@ -269,6 +269,7 @@ information.
* Domain name must have exactly one part above the TLD.
* Domain name must not equal an existing multi-part TLD.
* 2201
* Registrar is missing the billing account map for this currency type.
* Registrar is not authorized to access this TLD.
* 2306
* Too many resource checks requested in one check command.
@@ -304,6 +305,7 @@ An EPP flow that checks whether domain labels are trademarked.
* 2004
* Domain name is under tld which doesn't exist.
* 2201
* Registrar is missing the billing account map for this currency type.
* Registrar is not authorized to access this TLD.
* 2304
* The claims period for this TLD has ended.
@@ -361,6 +363,7 @@ An EPP flow that creates a new domain resource.
* The allocation token is invalid.
* Only a tool can pass a metadata extension.
* Registrar is not authorized to access this TLD.
* Registrar is missing the billing account map for this currency type.
* Registrar must be active in order to perform this operation.
* 2302
* Resource with this id already exists.
@@ -501,6 +504,7 @@ comes in at the exact millisecond that the domain would have expired.
server policy.
* 2201
* The specified resource belongs to another client.
* Registrar is missing the billing account map for this currency type.
* Registrar is not authorized to access this TLD.
* Registrar must be active in order to perform this operation.
* 2303
@@ -561,6 +565,7 @@ regardless of what the original expiration time was.
* Specified extension is not implemented.
* 2201
* The specified resource belongs to another client.
* Registrar is missing the billing account map for this currency type.
* Registrar is not authorized to access this TLD.
* Registrar must be active in order to perform this operation.
* 2303
@@ -736,6 +741,7 @@ new ones with the correct approval time).
server policy.
* 2201
* Authorization info is required to request a transfer.
* Registrar is missing the billing account map for this currency type.
* Registrar is not authorized to access this TLD.
* Registrar must be active in order to perform this operation.
* 2202
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -254,7 +254,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -118,7 +118,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -241,7 +241,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.conscrypt:conscrypt-openjdk-uber:2.5.1
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -254,7 +254,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -254,7 +254,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -253,7 +253,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -257,7 +257,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -13,7 +13,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -118,7 +118,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -245,7 +245,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.conscrypt:conscrypt-openjdk-uber:2.5.1
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -257,7 +257,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -17,7 +17,7 @@ com.fasterxml.jackson.core:jackson-databind:2.13.0
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0
com.fasterxml.jackson:jackson-bom:2.13.0
com.fasterxml:classmate:1.5.1
com.github.ben-manes.caffeine:caffeine:3.0.6
com.github.ben-manes.caffeine:caffeine:2.9.3
com.github.docker-java:docker-java-api:3.2.7
com.github.docker-java:docker-java-transport-zerodep:3.2.7
com.github.docker-java:docker-java-transport:3.2.7
@@ -124,7 +124,7 @@ com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.9
com.google.common.html.types:types:1.0.6
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.11.0
com.google.errorprone:error_prone_annotations:2.10.0
com.google.escapevelocity:escapevelocity:0.9.1
com.google.flatbuffers:flatbuffers-java:1.12.0
com.google.flogger:flogger-system-backend:0.7.4
@@ -257,7 +257,7 @@ org.bouncycastle:bcpg-jdk15on:1.67
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.21.3
org.checkerframework:checker-qual:3.21.0
org.codehaus.jackson:jackson-core-asl:1.9.13
org.codehaus.jackson:jackson-mapper-asl:1.9.13
org.codehaus.mojo:animal-sniffer-annotations:1.20
@@ -1,6 +1,7 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.android:annotations:4.1.1.4
com.google.api-client:google-api-client:1.31.3
com.google.api.grpc:proto-google-cloud-tasks-v2:1.33.2
@@ -21,7 +22,7 @@ com.google.cloud:google-cloud-tasks:1.33.2
com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.7
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.7.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -68,7 +69,7 @@ org.apache.httpcomponents:httpcore:4.4.14
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
org.codehaus.mojo:animal-sniffer-annotations:1.20
org.conscrypt:conscrypt-openjdk-uber:2.5.1
org.threeten:threetenbp:1.5.1
@@ -1,6 +1,7 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.api-client:google-api-client:1.31.3
com.google.api.grpc:proto-google-cloud-tasks-v2:1.33.2
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.89.2
@@ -20,7 +21,7 @@ com.google.cloud:google-cloud-tasks:1.33.2
com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.7
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.7.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:30.1.1-jre
@@ -66,7 +67,7 @@ org.apache.httpcomponents:httpcore:4.4.14
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
org.conscrypt:conscrypt-openjdk-uber:2.5.1
org.threeten:threetenbp:1.5.1
org.yaml:snakeyaml:1.17
@@ -1,6 +1,7 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.android:annotations:4.1.1.4
com.google.api-client:google-api-client:1.31.3
com.google.api.grpc:proto-google-cloud-tasks-v2:1.33.2
@@ -21,7 +22,7 @@ com.google.cloud:google-cloud-tasks:1.33.2
com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.7
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.7.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -70,7 +71,7 @@ org.apache.httpcomponents:httpcore:4.4.14
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
org.codehaus.mojo:animal-sniffer-annotations:1.20
org.conscrypt:conscrypt-openjdk-uber:2.5.1
org.threeten:threetenbp:1.5.1
@@ -1,6 +1,7 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3
com.google.android:annotations:4.1.1.4
com.google.api-client:google-api-client:1.31.3
com.google.api.grpc:proto-google-cloud-tasks-v2:1.33.2
@@ -21,7 +22,7 @@ com.google.cloud:google-cloud-tasks:1.33.2
com.google.code.findbugs:jsr305:3.0.2
com.google.code.gson:gson:2.8.7
com.google.dagger:dagger:2.33
com.google.errorprone:error_prone_annotations:2.7.1
com.google.errorprone:error_prone_annotations:2.10.0
com.google.flogger:flogger-system-backend:0.7.4
com.google.flogger:flogger:0.7.4
com.google.guava:failureaccess:1.0.1
@@ -70,7 +71,7 @@ org.apache.httpcomponents:httpcore:4.4.14
org.bouncycastle:bcpkix-jdk15on:1.67
org.bouncycastle:bcprov-jdk15on:1.67
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:3.8.0
org.checkerframework:checker-qual:3.19.0
org.codehaus.mojo:animal-sniffer-annotations:1.20
org.conscrypt:conscrypt-openjdk-uber:2.5.1
org.threeten:threetenbp:1.5.1

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