mirror of
https://github.com/google/nomulus
synced 2026-06-09 16:33:02 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f134c4bf37 | |||
| 44921c29d6 | |||
| ce80278ab7 | |||
| 594ce30122 | |||
| 736f788eea | |||
| d6f49f5c08 | |||
| 8b9139bc4c | |||
| b148102716 | |||
| 9ea06ebf35 | |||
| c0afb9aeee | |||
| 76d8afe856 | |||
| 36787c37fb | |||
| 36e46097e3 | |||
| ce2f98f680 | |||
| daaf231d39 | |||
| 955c3d9aeb | |||
| d03cea2443 |
@@ -97,6 +97,7 @@ nomulus.iws
|
||||
!/gradle/wrapper/**/*.jar
|
||||
.gradle/
|
||||
**/build
|
||||
cloudbuild-caches/
|
||||
node_modules/**
|
||||
/repos/
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import sys
|
||||
import re
|
||||
|
||||
# We should never analyze any generated files
|
||||
UNIVERSALLY_SKIPPED_PATTERNS = {"/build/", "/out/"}
|
||||
UNIVERSALLY_SKIPPED_PATTERNS = {"/build/", "cloudbuild-caches", "/out/"}
|
||||
# We can't rely on CI to have the Enum package installed so we do this instead.
|
||||
FORBIDDEN = 1
|
||||
REQUIRED = 2
|
||||
|
||||
+11
-2
@@ -52,9 +52,11 @@ def outcastTestPatterns = [
|
||||
def dockerIncompatibleTestPatterns = [
|
||||
// The webdriver tests start headless Chrome in a Docker container,
|
||||
// resulting in Docker-in-Docker complications. Likewise,
|
||||
// GenerateSqlSchemaCommandTest launches postgresql in a docker container.
|
||||
// GenerateSqlSchemaCommandTest and DumpGoldenSchemaCommandTest launch
|
||||
// postgresql in a docker container.
|
||||
"google/registry/webdriver/*",
|
||||
"google/registry/tools/GenerateSqlSchemaCommandTest.*",
|
||||
"google/registry/tools/DumpGoldenSchemaCommandTest.*",
|
||||
// PathParameterTest includes tests which validate that file permissions are
|
||||
// respected. However when running in Docker the user is root by default, so
|
||||
// every file is read/write-able. There is no way to exclude specific test
|
||||
@@ -93,7 +95,11 @@ sourceSets {
|
||||
nonprod {
|
||||
java {
|
||||
compileClasspath += main.output
|
||||
runtimeClasspath += main.output
|
||||
|
||||
// Add the DB runtime classpath to nonprod so we can load the flyway
|
||||
// scripts.
|
||||
runtimeClasspath += main.output +
|
||||
rootProject.project(":db").sourceSets.main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
test {
|
||||
@@ -321,6 +327,9 @@ dependencies {
|
||||
// Tool dependencies. used for doc generation.
|
||||
compile files("${System.properties['java.home']}/../lib/tools.jar")
|
||||
|
||||
// Flyway classes needed to generate the golden file.
|
||||
compile deps['org.flywaydb:flyway-core']
|
||||
|
||||
closureCompiler deps['com.google.javascript:closure-compiler']
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -84,22 +84,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -124,7 +124,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -146,10 +146,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -183,8 +183,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -193,6 +193,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -83,22 +83,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -123,7 +123,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
io.grpc:grpc-netty:1.17.1
|
||||
@@ -144,10 +144,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -180,8 +180,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -190,6 +190,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -157,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -194,8 +194,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -204,6 +204,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -157,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -193,8 +193,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -203,6 +203,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -84,22 +84,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -124,7 +124,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -146,10 +146,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -183,8 +183,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -193,6 +193,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -83,22 +83,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -123,7 +123,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
io.grpc:grpc-netty:1.17.1
|
||||
@@ -144,10 +144,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -181,8 +181,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -191,6 +191,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -84,22 +84,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -124,7 +124,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -146,10 +146,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -183,8 +183,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -193,6 +193,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -84,22 +84,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -124,7 +124,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -146,10 +146,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -183,8 +183,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -193,6 +193,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -84,22 +84,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -124,7 +124,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -146,10 +146,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -183,8 +183,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -193,6 +193,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -157,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -193,8 +193,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -203,6 +203,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -86,11 +86,11 @@ com.google.guava:guava-testlib:28.1-jre
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
@@ -98,11 +98,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:contrib:1.0.7
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -133,7 +133,7 @@ io.github.classgraph:classgraph:4.8.52
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -155,10 +155,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -198,8 +198,8 @@ org.apache.commons:commons-lang3:3.8.1
|
||||
org.apache.commons:commons-text:1.6
|
||||
org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
@@ -215,6 +215,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-all:1.3
|
||||
|
||||
@@ -10,11 +10,11 @@ com.fasterxml.jackson.core:jackson-annotations:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-core:2.9.10
|
||||
com.fasterxml.jackson.core:jackson-databind:2.9.10
|
||||
com.fasterxml:classmate:1.3.4
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -85,11 +85,11 @@ com.google.guava:guava-testlib:28.1-jre
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
@@ -97,11 +97,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:contrib:1.0.7
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -132,7 +132,7 @@ io.github.classgraph:classgraph:4.8.52
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
io.grpc:grpc-netty:1.17.1
|
||||
@@ -153,10 +153,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -196,8 +196,8 @@ org.apache.commons:commons-lang3:3.8.1
|
||||
org.apache.commons:commons-text:1.6
|
||||
org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
@@ -213,6 +213,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hamcrest:hamcrest-all:1.3
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -97,11 +97,11 @@ com.google.guava:guava-testlib:28.1-jre
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
@@ -109,11 +109,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:contrib:1.0.7
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -145,7 +145,7 @@ io.github.java-diff-utils:java-diff-utils:4.0
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -167,10 +167,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -210,8 +210,8 @@ org.apache.commons:commons-lang3:3.8.1
|
||||
org.apache.commons:commons-text:1.6
|
||||
org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -97,11 +97,11 @@ com.google.guava:guava-testlib:28.1-jre
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
@@ -109,11 +109,11 @@ com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:contrib:1.0.7
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -145,7 +145,7 @@ io.github.java-diff-utils:java-diff-utils:4.0
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -167,10 +167,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -210,8 +210,8 @@ org.apache.commons:commons-lang3:3.8.1
|
||||
org.apache.commons:commons-text:1.6
|
||||
org.apache.ftpserver:ftplet-api:1.0.6
|
||||
org.apache.ftpserver:ftpserver-core:1.0.6
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.apache.mina:mina-core:2.0.4
|
||||
org.apache.sshd:sshd-core:2.0.0
|
||||
org.apache.sshd:sshd-scp:2.0.0
|
||||
|
||||
@@ -61,6 +61,16 @@
|
||||
<url-pattern>/registry-lock-get</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>frontend-servlet</servlet-name>
|
||||
<url-pattern>/registry-lock-post</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>frontend-servlet</servlet-name>
|
||||
<url-pattern>/registry-lock-verify</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
|
||||
@@ -53,7 +53,6 @@ import java.util.concurrent.ExecutionException;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Transient;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
@@ -117,7 +116,6 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
DateTime lastEppUpdateTime;
|
||||
|
||||
/** Status values associated with this resource. */
|
||||
@Type(type = "google.registry.model.eppcommon.StatusValue$StatusValueSetType")
|
||||
@Column(name = "statuses")
|
||||
// TODO(mmuller): rename to "statuses" once we're off datastore.
|
||||
Set<StatusValue> status;
|
||||
|
||||
@@ -185,7 +185,6 @@ public class DomainBase extends EppResource
|
||||
String idnTableName;
|
||||
|
||||
/** Fully qualified host names of this domain's active subordinate hosts. */
|
||||
@org.hibernate.annotations.Type(type = "google.registry.persistence.StringSetUserType")
|
||||
Set<String> subordinateHosts;
|
||||
|
||||
/** When this domain's registration will expire. */
|
||||
|
||||
@@ -15,16 +15,22 @@
|
||||
package google.registry.model.eppcommon;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.OnLoad;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.JsonMapBuilder;
|
||||
import google.registry.model.Jsonifiable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Transient;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
|
||||
@@ -42,12 +48,21 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
* @see google.registry.model.registrar.RegistrarAddress
|
||||
*/
|
||||
@XmlTransient
|
||||
@Embeddable
|
||||
@MappedSuperclass
|
||||
public class Address extends ImmutableObject implements Jsonifiable {
|
||||
|
||||
/** The schema validation will enforce that this has 3 lines at most. */
|
||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||
@Transient
|
||||
List<String> street;
|
||||
|
||||
@Ignore String streetLine1;
|
||||
|
||||
@Ignore String streetLine2;
|
||||
|
||||
@Ignore String streetLine3;
|
||||
|
||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||
String city;
|
||||
|
||||
@@ -64,7 +79,23 @@ public class Address extends ImmutableObject implements Jsonifiable {
|
||||
String countryCode;
|
||||
|
||||
public ImmutableList<String> getStreet() {
|
||||
return nullToEmptyImmutableCopy(street);
|
||||
if (street == null && streetLine1 != null) {
|
||||
return ImmutableList.of(streetLine1, nullToEmpty(streetLine2), nullToEmpty(streetLine3));
|
||||
} else {
|
||||
return nullToEmptyImmutableCopy(street);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStreetLine1() {
|
||||
return streetLine1;
|
||||
}
|
||||
|
||||
public String getStreetLine2() {
|
||||
return streetLine2;
|
||||
}
|
||||
|
||||
public String getStreetLine13() {
|
||||
return streetLine3;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
@@ -139,4 +170,14 @@ public class Address extends ImmutableObject implements Jsonifiable {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@OnLoad
|
||||
void setStreetForCloudSql() {
|
||||
if (street == null || street.size() == 0) {
|
||||
return;
|
||||
}
|
||||
streetLine1 = street.get(0);
|
||||
streetLine2 = street.size() >= 2 ? street.get(1) : null;
|
||||
streetLine3 = street.size() >= 3 ? street.get(2) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.translators.EnumToAttributeAdapter.EppEnum;
|
||||
import google.registry.model.translators.StatusValueAdapter;
|
||||
import google.registry.persistence.EnumSetUserType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
/**
|
||||
@@ -166,11 +165,4 @@ public enum StatusValue implements EppEnum {
|
||||
return StatusValue.valueOf(LOWER_CAMEL.to(UPPER_UNDERSCORE, nullToEmpty(xmlName)));
|
||||
}
|
||||
|
||||
/** Hibernate type for sets of {@link StatusValue}. */
|
||||
public static class StatusValueSetType extends EnumSetUserType<StatusValue> {
|
||||
@Override
|
||||
protected Object convertToElem(Object value) {
|
||||
return StatusValue.valueOf((String) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,12 +85,28 @@ import java.util.function.Predicate;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Information about a registrar. */
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity
|
||||
@Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrarName", name = "registrar_name_idx"),
|
||||
@javax.persistence.Index(
|
||||
columnList = "ianaIdentifier",
|
||||
name = "registrar_iana_identifier_idx"),
|
||||
})
|
||||
public class Registrar extends ImmutableObject implements Buildable, Jsonifiable {
|
||||
|
||||
/** Represents the type of a registrar entity. */
|
||||
@@ -208,14 +224,17 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
.doTransactionless(
|
||||
() -> Maps.uniqueIndex(loadAll(), Registrar::getClientId)));
|
||||
|
||||
@Parent
|
||||
Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
|
||||
|
||||
/**
|
||||
* Unique registrar client id. Must conform to "clIDType" as defined in RFC5730.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5730#section-4.2">Shared Structure Schema</a>
|
||||
* <p>TODO(shicong): Rename this field to clientId
|
||||
*/
|
||||
@Id
|
||||
@javax.persistence.Id
|
||||
@Column(name = "client_id", nullable = false)
|
||||
String clientIdentifier;
|
||||
|
||||
/**
|
||||
@@ -229,12 +248,17 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
* @see <a href="http://www.icann.org/registrar-reports/accredited-list.html">ICANN-Accredited
|
||||
* Registrars</a>
|
||||
*/
|
||||
@Index String registrarName;
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
String registrarName;
|
||||
|
||||
/** The type of this registrar. */
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
Type type;
|
||||
|
||||
/** The state of this registrar. */
|
||||
@Enumerated(EnumType.STRING)
|
||||
State state;
|
||||
|
||||
/** The set of TLDs which this registrar is allowed to access. */
|
||||
@@ -277,6 +301,7 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
String passwordHash;
|
||||
|
||||
/** Randomly generated hash salt. */
|
||||
@Column(name = "password_salt")
|
||||
String salt;
|
||||
|
||||
// The following fields may appear redundant to the above, but are
|
||||
@@ -287,6 +312,24 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
* unrestricted UTF-8.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
name = "streetLine1",
|
||||
column = @Column(name = "localized_address_street_line1")),
|
||||
@AttributeOverride(
|
||||
name = "streetLine2",
|
||||
column = @Column(name = "localized_address_street_line2")),
|
||||
@AttributeOverride(
|
||||
name = "streetLine3",
|
||||
column = @Column(name = "localized_address_street_line3")),
|
||||
@AttributeOverride(name = "city", column = @Column(name = "localized_address_city")),
|
||||
@AttributeOverride(name = "state", column = @Column(name = "localized_address_state")),
|
||||
@AttributeOverride(name = "zip", column = @Column(name = "localized_address_zip")),
|
||||
@AttributeOverride(
|
||||
name = "countryCode",
|
||||
column = @Column(name = "localized_address_country_code"))
|
||||
})
|
||||
RegistrarAddress localizedAddress;
|
||||
|
||||
/**
|
||||
@@ -294,6 +337,16 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
* representable in the 7-bit US-ASCII character set.
|
||||
*/
|
||||
@IgnoreSave(IfNull.class)
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "streetLine1", column = @Column(name = "i18n_address_street_line1")),
|
||||
@AttributeOverride(name = "streetLine2", column = @Column(name = "i18n_address_street_line2")),
|
||||
@AttributeOverride(name = "streetLine3", column = @Column(name = "i18n_address_street_line3")),
|
||||
@AttributeOverride(name = "city", column = @Column(name = "i18n_address_city")),
|
||||
@AttributeOverride(name = "state", column = @Column(name = "i18n_address_state")),
|
||||
@AttributeOverride(name = "zip", column = @Column(name = "i18n_address_zip")),
|
||||
@AttributeOverride(name = "countryCode", column = @Column(name = "i18n_address_country_code"))
|
||||
})
|
||||
RegistrarAddress internationalizedAddress;
|
||||
|
||||
/** Voice number. */
|
||||
@@ -309,16 +362,17 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
|
||||
/**
|
||||
* Registrar identifier used for reporting to ICANN.
|
||||
*
|
||||
* <ul>
|
||||
* <li>8 is used for Testing Registrar.
|
||||
* <li>9997 is used by ICAAN for SLA monitoring.
|
||||
* <li>9999 is used for cases when the registry operator acts as registrar.
|
||||
* </ul>
|
||||
* @see <a href="http://www.iana.org/assignments/registrar-ids/registrar-ids.txt">Registrar IDs</a>
|
||||
*
|
||||
* @see <a href="http://www.iana.org/assignments/registrar-ids/registrar-ids.txt">Registrar
|
||||
* IDs</a>
|
||||
*/
|
||||
@Index
|
||||
@Nullable
|
||||
Long ianaIdentifier;
|
||||
@Index @Nullable Long ianaIdentifier;
|
||||
|
||||
/** Identifier of registrar used in external billing system (e.g. Oracle). */
|
||||
@Nullable
|
||||
@@ -338,18 +392,19 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
*/
|
||||
@Nullable
|
||||
@Mapify(CurrencyMapper.class)
|
||||
@org.hibernate.annotations.Type(type = "google.registry.persistence.CurrencyToBillingMapUserType")
|
||||
Map<CurrencyUnit, BillingAccountEntry> billingAccountMap;
|
||||
|
||||
/** A billing account entry for this registrar, consisting of a currency and an account Id. */
|
||||
@Embed
|
||||
static class BillingAccountEntry extends ImmutableObject {
|
||||
public static class BillingAccountEntry extends ImmutableObject {
|
||||
|
||||
CurrencyUnit currency;
|
||||
String accountId;
|
||||
|
||||
BillingAccountEntry() {}
|
||||
|
||||
BillingAccountEntry(CurrencyUnit currency, String accountId) {
|
||||
public BillingAccountEntry(CurrencyUnit currency, String accountId) {
|
||||
this.accountId = accountId;
|
||||
this.currency = currency;
|
||||
}
|
||||
@@ -366,6 +421,11 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
return billingAccountEntry.currency;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the account id of this entry. */
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
}
|
||||
|
||||
/** URL of registrar's website. */
|
||||
@@ -390,14 +450,10 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
/** An automatically managed last-saved timestamp. */
|
||||
UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null);
|
||||
|
||||
/**
|
||||
* The time that the certificate was last updated.
|
||||
*/
|
||||
/** The time that the certificate was last updated. */
|
||||
DateTime lastCertificateUpdateTime;
|
||||
|
||||
/**
|
||||
* Telephone support passcode (5-digit numeric)
|
||||
*/
|
||||
/** Telephone support passcode (5-digit numeric) */
|
||||
String phonePasscode;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import static google.registry.util.CollectionUtils.forceEmptyToNull;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import google.registry.model.eppcommon.Address;
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
/**
|
||||
* Registrar Address
|
||||
@@ -29,6 +30,7 @@ import google.registry.model.eppcommon.Address;
|
||||
* classes.
|
||||
*/
|
||||
@Embed
|
||||
@Embeddable
|
||||
public class RegistrarAddress extends Address {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,9 @@ import google.registry.model.annotations.ReportedOn;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
/**
|
||||
* A contact for a Registrar. Note, equality, hashCode and comparable have been overridden to only
|
||||
@@ -56,10 +59,16 @@ import java.util.Set;
|
||||
*/
|
||||
@ReportedOn
|
||||
@Entity
|
||||
@javax.persistence.Entity
|
||||
@Table(
|
||||
name = "RegistrarPoc",
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "gaeUserId", name = "registrarpoc_gae_user_id_idx")
|
||||
})
|
||||
// TODO(shicong): Rename the class name to RegistrarPoc after database migration
|
||||
public class RegistrarContact extends ImmutableObject implements Jsonifiable {
|
||||
|
||||
@Parent
|
||||
Key<Registrar> parent;
|
||||
@Parent @Transient Key<Registrar> parent;
|
||||
|
||||
/**
|
||||
* Registrar contacts types for partner communication tracking.
|
||||
@@ -99,6 +108,8 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
|
||||
|
||||
/** The email address of the contact. */
|
||||
@Id
|
||||
@javax.persistence.Id
|
||||
@Column(nullable = false)
|
||||
String emailAddress;
|
||||
|
||||
/** The voice number of the contact. */
|
||||
@@ -108,8 +119,8 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
|
||||
String faxNumber;
|
||||
|
||||
/**
|
||||
* Multiple types are used to associate the registrar contact with
|
||||
* various mailing groups. This data is internal to the registry.
|
||||
* Multiple types are used to associate the registrar contact with various mailing groups. This
|
||||
* data is internal to the registry.
|
||||
*/
|
||||
Set<Type> types;
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import google.registry.ui.server.registrar.OteStatusAction;
|
||||
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||
import google.registry.ui.server.registrar.RegistrarSettingsAction;
|
||||
import google.registry.ui.server.registrar.RegistryLockGetAction;
|
||||
import google.registry.ui.server.registrar.RegistryLockPostAction;
|
||||
import google.registry.ui.server.registrar.RegistryLockVerifyAction;
|
||||
|
||||
/** Dagger component with per-request lifetime for "default" App Engine module. */
|
||||
@RequestScope
|
||||
@@ -53,6 +55,10 @@ interface FrontendRequestComponent {
|
||||
|
||||
RegistryLockGetAction registryLockGetAction();
|
||||
|
||||
RegistryLockPostAction registryLockPostAction();
|
||||
|
||||
RegistryLockVerifyAction registryLockVerifyAction();
|
||||
|
||||
@Subcomponent.Builder
|
||||
abstract class Builder implements RequestComponentBuilder<FrontendRequestComponent> {
|
||||
@Override public abstract Builder requestModule(RequestModule requestModule);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/**
|
||||
* JPA {@link AttributeConverter} for storing/retrieving {@link List<CidrAddressBlock>} objects.
|
||||
* TODO(shicong): Investigate if we can have one converter for any List type
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
public class CidrAddressBlockListConverter extends StringListConverterBase<CidrAddressBlock> {
|
||||
|
||||
@Override
|
||||
String toString(CidrAddressBlock element) {
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
CidrAddressBlock fromString(String value) {
|
||||
return CidrAddressBlock.create(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
|
||||
import google.registry.model.registrar.Registrar.BillingAccountEntry;
|
||||
import java.util.Map;
|
||||
import org.hibernate.usertype.UserType;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
|
||||
/**
|
||||
* A custom {@link UserType} for storing/retrieving {@link Map<CurrencyUnit, BillingAccountEntry>}
|
||||
* objects.
|
||||
*/
|
||||
public class CurrencyToBillingMapUserType extends MapUserType {
|
||||
|
||||
@Override
|
||||
public Object toEntityTypeMap(Map<String, String> map) {
|
||||
return map.entrySet().stream()
|
||||
.collect(
|
||||
toImmutableMap(
|
||||
entry -> CurrencyUnit.of(entry.getKey()),
|
||||
entry ->
|
||||
new BillingAccountEntry(CurrencyUnit.of(entry.getKey()), entry.getValue())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> toDbSupportedMap(Object map) {
|
||||
return ((Map<CurrencyUnit, BillingAccountEntry>) map)
|
||||
.entrySet().stream()
|
||||
.collect(
|
||||
toImmutableMap(
|
||||
entry -> entry.getKey().getCode(), entry -> entry.getValue().getAccountId()));
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import java.sql.Array;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Collection;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
/** Generic Hibernate user type to store/retrieve Java collection as an array in Cloud SQL. */
|
||||
public abstract class GenericCollectionUserType<T extends Collection> extends MutableUserType {
|
||||
|
||||
abstract T getNewCollection();
|
||||
|
||||
abstract ArrayColumnType getColumnType();
|
||||
|
||||
enum ArrayColumnType {
|
||||
STRING(Types.ARRAY, "text");
|
||||
|
||||
final int typeCode;
|
||||
final String typeName;
|
||||
|
||||
ArrayColumnType(int typeCode, String typeName) {
|
||||
this.typeCode = typeCode;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
int getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
String getTypeDdlName() {
|
||||
return typeName + "[]";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] sqlTypes() {
|
||||
return new int[] {getColumnType().getTypeCode()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nullSafeGet(
|
||||
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
if (rs.getArray(names[0]) != null) {
|
||||
T result = getNewCollection();
|
||||
for (Object element : (Object[]) rs.getArray(names[0]).getArray()) {
|
||||
result.add(convertToElem(element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullSafeSet(
|
||||
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
if (value == null) {
|
||||
st.setArray(index, null);
|
||||
return;
|
||||
}
|
||||
T list = (T) value;
|
||||
Array arr = st.getConnection().createArrayOf(getColumnType().getTypeName(), list.toArray());
|
||||
st.setArray(index, arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to convert an element value retrieved from the database to a different type.
|
||||
*
|
||||
* <p>This method is useful when encoding a java type to one of the types that can be used as an
|
||||
* array element.
|
||||
*/
|
||||
protected Object convertToElem(Object columnValue) {
|
||||
return columnValue;
|
||||
}
|
||||
}
|
||||
@@ -45,13 +45,29 @@ public class MapUserType extends MutableUserType {
|
||||
public Object nullSafeGet(
|
||||
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
return rs.getObject(names[0]);
|
||||
return toEntityTypeMap((Map<String, String>) rs.getObject(names[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullSafeSet(
|
||||
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
st.setObject(index, value);
|
||||
st.setObject(index, toDbSupportedMap(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass can override this method to convert the {@link Map<String, String>} to a {@link Map}
|
||||
* of specific type defined in the entity class.
|
||||
*/
|
||||
public Object toEntityTypeMap(Map<String, String> map) {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass can override this method to convert the {@link Map} of specific type to a {@link
|
||||
* Map<String, String>} that can be stored in the hstore type column.
|
||||
*/
|
||||
public Map<String, String> toDbSupportedMap(Object map) {
|
||||
return (Map<String, String>) map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
// limitations under the License.
|
||||
package google.registry.persistence;
|
||||
|
||||
import google.registry.persistence.GenericCollectionUserType.ArrayColumnType;
|
||||
import java.sql.Types;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.dialect.PostgreSQL95Dialect;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
/** Nomulus mapping rules for column types in Postgresql. */
|
||||
public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
|
||||
@@ -25,8 +26,15 @@ public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
|
||||
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamptz");
|
||||
registerColumnType(Types.TIMESTAMP, "timestamptz");
|
||||
registerColumnType(Types.OTHER, "hstore");
|
||||
for (ArrayColumnType arrayType : ArrayColumnType.values()) {
|
||||
registerColumnType(arrayType.getTypeCode(), arrayType.getTypeDdlName());
|
||||
}
|
||||
registerColumnType(
|
||||
StringCollectionDescriptor.COLUMN_TYPE, StringCollectionDescriptor.COLUMN_DDL_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeTypes(
|
||||
TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||
super.contributeTypes(typeContributions, serviceRegistry);
|
||||
typeContributions.contributeJavaTypeDescriptor(new StringCollectionDescriptor());
|
||||
typeContributions.contributeSqlTypeDescriptor(new StringCollectionDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
+10
-13
@@ -14,24 +14,21 @@
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import java.util.HashSet;
|
||||
import google.registry.model.registrar.RegistrarContact.Type;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** Abstract Hibernate user type for storing/retrieving {@link Set<Enum<E>>}. */
|
||||
public class EnumSetUserType<E extends Enum<E>> extends GenericCollectionUserType<Set<Enum<E>>> {
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<Type>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class RegistrarPocSetConverter extends StringSetConverterBase<Type> {
|
||||
@Override
|
||||
Set<Enum<E>> getNewCollection() {
|
||||
return new HashSet<Enum<E>>();
|
||||
String toString(Type element) {
|
||||
return element.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayColumnType getColumnType() {
|
||||
return ArrayColumnType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class returnedClass() {
|
||||
return Set.class;
|
||||
Type fromString(String value) {
|
||||
return Type.valueOf(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<StatusValue>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StatusValueSetConverter extends StringSetConverterBase<StatusValue> {
|
||||
|
||||
@Override
|
||||
String toString(StatusValue element) {
|
||||
return element.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
StatusValue fromString(String value) {
|
||||
return StatusValue.valueOf(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static google.registry.persistence.StringCollectionDescriptor.StringCollection;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.sql.Array;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Collection;
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
|
||||
import org.hibernate.type.descriptor.sql.BasicBinder;
|
||||
import org.hibernate.type.descriptor.sql.BasicExtractor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
/**
|
||||
* The {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor} for {@link StringCollection}.
|
||||
*
|
||||
* <p>A {@link StringCollection} object is a simple wrapper for a {@link Collection<String>} which
|
||||
* can be stored as a string array in the database. The {@link JavaTypeDescriptor} and {@link
|
||||
* SqlTypeDescriptor} is used by JPA/Hibernate to map between the collection and {@link Array} which
|
||||
* is the actual type that JDBC uses to read from and write to the database.
|
||||
*
|
||||
* @see <a
|
||||
* href="https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-jpa-convert">JPA
|
||||
* 2.1 AttributeConverters</a>
|
||||
*/
|
||||
public class StringCollectionDescriptor extends AbstractTypeDescriptor<StringCollection>
|
||||
implements SqlTypeDescriptor {
|
||||
public static final int COLUMN_TYPE = Types.ARRAY;
|
||||
public static final String COLUMN_NAME = "text";
|
||||
public static final String COLUMN_DDL_NAME = COLUMN_NAME + "[]";
|
||||
|
||||
protected StringCollectionDescriptor() {
|
||||
super(StringCollection.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringCollection fromString(String string) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Constructing StringCollectionDescriptor from string is not allowed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X unwrap(StringCollection value, Class<X> type, WrapperOptions options) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (Collection.class.isAssignableFrom(type)) {
|
||||
return (X) value.getCollection();
|
||||
}
|
||||
throw unknownUnwrap(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> StringCollection wrap(X value, WrapperOptions options) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Array) {
|
||||
try {
|
||||
String[] arr = (String[]) ((Array) value).getArray();
|
||||
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
|
||||
for (String str : arr) {
|
||||
builder.add(str);
|
||||
}
|
||||
return StringCollection.create(builder.build());
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
throw unknownWrap(value.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSqlType() {
|
||||
return COLUMN_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeRemapped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
return new BasicBinder<X>(javaTypeDescriptor, this) {
|
||||
@Override
|
||||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
||||
throws SQLException {
|
||||
if (value == null) {
|
||||
st.setArray(index, null);
|
||||
return;
|
||||
}
|
||||
if (value instanceof StringCollection) {
|
||||
StringCollection stringCollection = (StringCollection) value;
|
||||
if (stringCollection.getCollection() == null) {
|
||||
st.setArray(index, null);
|
||||
} else {
|
||||
st.setArray(
|
||||
index,
|
||||
st.getConnection()
|
||||
.createArrayOf(COLUMN_NAME, stringCollection.getCollection().toArray()));
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
String.format(
|
||||
"Binding type %s is not supported by StringCollectionDescriptor",
|
||||
value.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
|
||||
throws SQLException {
|
||||
// CallableStatement.setArray() doesn't have an overload version for setting array by its
|
||||
// column name
|
||||
throw new UnsupportedOperationException(
|
||||
"Binding array by its column name is not supported");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
return new BasicExtractor<X>(javaTypeDescriptor, this) {
|
||||
@Override
|
||||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
|
||||
return javaTypeDescriptor.wrap(rs.getArray(name), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, int index, WrapperOptions options)
|
||||
throws SQLException {
|
||||
return javaTypeDescriptor.wrap(statement.getArray(index), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
|
||||
throws SQLException {
|
||||
return javaTypeDescriptor.wrap(statement.getArray(name), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class StringCollection {
|
||||
private Collection<String> collection;
|
||||
|
||||
private StringCollection(Collection<String> collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public static StringCollection create(Collection<String> collection) {
|
||||
return new StringCollection(collection);
|
||||
}
|
||||
|
||||
public Collection<String> getCollection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-12
@@ -14,24 +14,21 @@
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** Abstract Hibernate user type for storing/retrieving {@link List<String>}. */
|
||||
public class StringListUserType extends GenericCollectionUserType<List<String>> {
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link List<String>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StringListConverter extends StringListConverterBase<String> {
|
||||
|
||||
@Override
|
||||
List<String> getNewCollection() {
|
||||
return Lists.newArrayList();
|
||||
String toString(String element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayColumnType getColumnType() {
|
||||
return ArrayColumnType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class returnedClass() {
|
||||
return List.class;
|
||||
String fromString(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import google.registry.persistence.StringCollectionDescriptor.StringCollection;
|
||||
import java.util.List;
|
||||
import javax.persistence.AttributeConverter;
|
||||
|
||||
/**
|
||||
* Base JPA converter for {@link List} objects that are stored as an array of strings in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class StringListConverterBase<T>
|
||||
implements AttributeConverter<List<T>, StringCollection> {
|
||||
|
||||
abstract String toString(T element);
|
||||
|
||||
abstract T fromString(String value);
|
||||
|
||||
@Override
|
||||
public StringCollection convertToDatabaseColumn(List<T> attribute) {
|
||||
return attribute == null
|
||||
? null
|
||||
: StringCollection.create(
|
||||
attribute.stream().map(this::toString).collect(toImmutableList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> convertToEntityAttribute(StringCollection dbData) {
|
||||
return dbData == null || dbData.getCollection() == null
|
||||
? null
|
||||
: dbData.getCollection().stream().map(this::fromString).collect(toImmutableList());
|
||||
}
|
||||
}
|
||||
+9
-12
@@ -14,24 +14,21 @@
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
/** Abstract Hibernate user type for storing/retrieving {@link Set<String>}. */
|
||||
public class StringSetUserType extends GenericCollectionUserType<Set<String>> {
|
||||
/** JPA {@link AttributeConverter} for storing/retrieving {@link Set<String>}. */
|
||||
@Converter(autoApply = true)
|
||||
public class StringSetConverter extends StringSetConverterBase<String> {
|
||||
|
||||
@Override
|
||||
Set<String> getNewCollection() {
|
||||
return Sets.newHashSet();
|
||||
String toString(String element) {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
ArrayColumnType getColumnType() {
|
||||
return ArrayColumnType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class returnedClass() {
|
||||
return Set.class;
|
||||
String fromString(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
import google.registry.persistence.StringCollectionDescriptor.StringCollection;
|
||||
import java.util.Set;
|
||||
import javax.persistence.AttributeConverter;
|
||||
|
||||
/**
|
||||
* Base JPA converter for {@link Set} objects that are stored as an array of strings in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class StringSetConverterBase<T>
|
||||
implements AttributeConverter<Set<T>, StringCollection> {
|
||||
|
||||
abstract String toString(T element);
|
||||
|
||||
abstract T fromString(String value);
|
||||
|
||||
@Override
|
||||
public StringCollection convertToDatabaseColumn(Set<T> attribute) {
|
||||
return attribute == null
|
||||
? null
|
||||
: StringCollection.create(attribute.stream().map(this::toString).collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> convertToEntityAttribute(StringCollection dbData) {
|
||||
return dbData == null || dbData.getCollection() == null
|
||||
? null
|
||||
: dbData.getCollection().stream().map(this::fromString).collect(toImmutableSet());
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,11 @@ public class PremiumListDao {
|
||||
RevisionIdAndLabel.create(premiumList.getRevisionId(), label);
|
||||
try {
|
||||
Optional<BigDecimal> price = PremiumListCache.cachePremiumEntries.get(revisionIdAndLabel);
|
||||
return price.map(p -> Money.of(premiumList.getCurrency(), p));
|
||||
return price.map(
|
||||
p ->
|
||||
Money.of(
|
||||
premiumList.getCurrency(),
|
||||
p.setScale(premiumList.getCurrency().getDecimalPlaces())));
|
||||
} catch (InvalidCacheLoadException | ExecutionException e) {
|
||||
throw new RuntimeException(
|
||||
String.format(
|
||||
|
||||
@@ -62,12 +62,6 @@ public abstract class CreateOrUpdateReservedListCommand extends MutatingCommand
|
||||
arity = 1)
|
||||
Boolean shouldPublish;
|
||||
|
||||
@Parameter(
|
||||
names = {"--also_cloud_sql"},
|
||||
description =
|
||||
"Persist reserved list to Cloud SQL in addition to Datastore; defaults to false.")
|
||||
boolean alsoCloudSql;
|
||||
|
||||
google.registry.schema.tld.ReservedList cloudSqlReservedList;
|
||||
|
||||
abstract void saveToCloudSql();
|
||||
@@ -78,23 +72,18 @@ public abstract class CreateOrUpdateReservedListCommand extends MutatingCommand
|
||||
String output = super.execute();
|
||||
logger.atInfo().log(output);
|
||||
|
||||
String cloudSqlMessage;
|
||||
if (alsoCloudSql) {
|
||||
String cloudSqlMessage =
|
||||
String.format(
|
||||
"Saved reserved list %s with %d entries",
|
||||
name, cloudSqlReservedList.getLabelsToReservations().size());
|
||||
try {
|
||||
logger.atInfo().log("Saving reserved list to Cloud SQL for TLD %s", name);
|
||||
saveToCloudSql();
|
||||
logger.atInfo().log(cloudSqlMessage);
|
||||
} catch (Throwable e) {
|
||||
cloudSqlMessage =
|
||||
String.format(
|
||||
"Saved reserved list %s with %d entries",
|
||||
name, cloudSqlReservedList.getLabelsToReservations().size());
|
||||
try {
|
||||
logger.atInfo().log("Saving reserved list to Cloud SQL for TLD %s", name);
|
||||
saveToCloudSql();
|
||||
logger.atInfo().log(cloudSqlMessage);
|
||||
} catch (Throwable e) {
|
||||
cloudSqlMessage =
|
||||
"Unexpected error saving reserved list to Cloud SQL from nomulus tool command";
|
||||
logger.atSevere().withCause(e).log(cloudSqlMessage);
|
||||
}
|
||||
} else {
|
||||
cloudSqlMessage = "Persisting reserved list to Cloud SQL is not enabled";
|
||||
"Unexpected error saving reserved list to Cloud SQL from nomulus tool command";
|
||||
logger.atSevere().withCause(e).log(cloudSqlMessage);
|
||||
}
|
||||
return cloudSqlMessage;
|
||||
}
|
||||
|
||||
@@ -67,11 +67,9 @@ final class CreateReservedListCommand extends CreateOrUpdateReservedListCommand
|
||||
.setLastUpdateTime(now)
|
||||
.build();
|
||||
stageEntityChange(null, reservedList);
|
||||
if (alsoCloudSql) {
|
||||
cloudSqlReservedList =
|
||||
google.registry.schema.tld.ReservedList.create(
|
||||
name, shouldPublish, parseToReservationsByLabels(allLines));
|
||||
}
|
||||
cloudSqlReservedList =
|
||||
google.registry.schema.tld.ReservedList.create(
|
||||
name, shouldPublish, parseToReservationsByLabels(allLines));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,12 +32,14 @@ import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.util.Clock;
|
||||
import google.registry.util.StringGenerator;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Utility class for validating and applying {@link RegistryLock}s.
|
||||
* Utility functions for validating and applying {@link RegistryLock}s.
|
||||
*
|
||||
* <p>For both locks and unlocks, a lock must be requested via the createRegistry*Requst methods
|
||||
* then verified through the verifyAndApply* methods. These methods will verify that the domain in
|
||||
@@ -45,9 +47,16 @@ import javax.annotation.Nullable;
|
||||
*/
|
||||
public final class DomainLockUtils {
|
||||
|
||||
private DomainLockUtils() {}
|
||||
private static final int VERIFICATION_CODE_LENGTH = 32;
|
||||
|
||||
public static RegistryLock createRegistryLockRequest(
|
||||
private final StringGenerator stringGenerator;
|
||||
|
||||
@Inject
|
||||
public DomainLockUtils(@Named("base58StringGenerator") StringGenerator stringGenerator) {
|
||||
this.stringGenerator = stringGenerator;
|
||||
}
|
||||
|
||||
public RegistryLock createRegistryLockRequest(
|
||||
String domainName,
|
||||
String registrarId,
|
||||
@Nullable String registrarPocId,
|
||||
@@ -68,7 +77,7 @@ public final class DomainLockUtils {
|
||||
|
||||
RegistryLock lock =
|
||||
new RegistryLock.Builder()
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
||||
.setDomainName(domainName)
|
||||
.setRepoId(domainBase.getRepoId())
|
||||
.setRegistrarId(registrarId)
|
||||
@@ -78,7 +87,7 @@ public final class DomainLockUtils {
|
||||
return RegistryLockDao.save(lock);
|
||||
}
|
||||
|
||||
public static RegistryLock createRegistryUnlockRequest(
|
||||
public RegistryLock createRegistryUnlockRequest(
|
||||
String domainName, String registrarId, boolean isAdmin, Clock clock) {
|
||||
DomainBase domainBase = getDomain(domainName, clock);
|
||||
Optional<RegistryLock> lockOptional =
|
||||
@@ -121,7 +130,7 @@ public final class DomainLockUtils {
|
||||
}
|
||||
RegistryLock newLock =
|
||||
newLockBuilder
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode(stringGenerator.createString(VERIFICATION_CODE_LENGTH))
|
||||
.isSuperuser(isAdmin)
|
||||
.setUnlockRequestTimestamp(clock.nowUtc())
|
||||
.setRegistrarId(registrarId)
|
||||
@@ -129,8 +138,7 @@ public final class DomainLockUtils {
|
||||
return RegistryLockDao.save(newLock);
|
||||
}
|
||||
|
||||
public static RegistryLock verifyAndApplyLock(
|
||||
String verificationCode, boolean isAdmin, Clock clock) {
|
||||
public RegistryLock verifyAndApplyLock(String verificationCode, boolean isAdmin, Clock clock) {
|
||||
return jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
@@ -156,8 +164,7 @@ public final class DomainLockUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static RegistryLock verifyAndApplyUnlock(
|
||||
String verificationCode, boolean isAdmin, Clock clock) {
|
||||
public RegistryLock verifyAndApplyUnlock(String verificationCode, boolean isAdmin, Clock clock) {
|
||||
return jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
|
||||
@@ -60,11 +60,11 @@ public class LockDomainCommand extends LockOrUnlockDomainCommand {
|
||||
|
||||
@Override
|
||||
protected RegistryLock createLock(String domain) {
|
||||
return DomainLockUtils.createRegistryLockRequest(domain, clientId, null, true, clock);
|
||||
return domainLockUtils.createRegistryLockRequest(domain, clientId, null, true, clock);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalizeLockOrUnlockRequest(RegistryLock lock) {
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
static final ImmutableSet<StatusValue> REGISTRY_LOCK_STATUSES =
|
||||
public static final ImmutableSet<StatusValue> REGISTRY_LOCK_STATUSES =
|
||||
ImmutableSet.of(
|
||||
SERVER_DELETE_PROHIBITED, SERVER_TRANSFER_PROHIBITED, SERVER_UPDATE_PROHIBITED);
|
||||
|
||||
@@ -57,6 +57,8 @@ public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand
|
||||
|
||||
@Inject Clock clock;
|
||||
|
||||
@Inject DomainLockUtils domainLockUtils;
|
||||
|
||||
protected ImmutableSet<String> relevantDomains = ImmutableSet.of();
|
||||
|
||||
protected ImmutableSet<String> getDomains() {
|
||||
|
||||
@@ -60,11 +60,11 @@ public class UnlockDomainCommand extends LockOrUnlockDomainCommand {
|
||||
|
||||
@Override
|
||||
protected RegistryLock createLock(String domain) {
|
||||
return DomainLockUtils.createRegistryUnlockRequest(domain, clientId, true, clock);
|
||||
return domainLockUtils.createRegistryUnlockRequest(domain, clientId, true, clock);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalizeLockOrUnlockRequest(RegistryLock lock) {
|
||||
DomainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), true, clock);
|
||||
domainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), true, clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,11 +50,9 @@ final class UpdateReservedListCommand extends CreateOrUpdateReservedListCommand
|
||||
.setLastUpdateTime(new SystemClock().nowUtc())
|
||||
.setShouldPublish(shouldPublish);
|
||||
stageEntityChange(existing.get(), updated.build());
|
||||
if (alsoCloudSql) {
|
||||
cloudSqlReservedList =
|
||||
google.registry.schema.tld.ReservedList.create(
|
||||
name, shouldPublish, parseToReservationsByLabels(allLines));
|
||||
}
|
||||
cloudSqlReservedList =
|
||||
google.registry.schema.tld.ReservedList.create(
|
||||
name, shouldPublish, parseToReservationsByLabels(allLines));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,11 +37,6 @@ final class UploadClaimsListCommand extends ConfirmingCommand implements Command
|
||||
@Parameter(description = "Claims list filename")
|
||||
private List<String> mainParameters = new ArrayList<>();
|
||||
|
||||
@Parameter(
|
||||
names = {"--also_cloud_sql"},
|
||||
description = "Persist claims list to Cloud SQL in addition to Datastore; defaults to false.")
|
||||
boolean alsoCloudSql;
|
||||
|
||||
private String claimsListFilename;
|
||||
|
||||
private ClaimsList claimsList;
|
||||
@@ -64,9 +59,7 @@ final class UploadClaimsListCommand extends ConfirmingCommand implements Command
|
||||
@Override
|
||||
public String execute() {
|
||||
ClaimsListShard.create(claimsList.getTmdbGenerationTime(), claimsList.getLabelsToKeys()).save();
|
||||
if (alsoCloudSql) {
|
||||
ClaimsListDao.trySave(claimsList);
|
||||
}
|
||||
ClaimsListDao.trySave(claimsList);
|
||||
return String.format("Successfully uploaded claims list %s", claimsListFilename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
|
||||
import static google.registry.request.RequestParameters.extractBooleanParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalIntParameter;
|
||||
import static google.registry.request.RequestParameters.extractOptionalParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
@@ -144,4 +144,16 @@ public final class RegistrarConsoleModule {
|
||||
static Optional<String> provideOptionalPasscode(HttpServletRequest req) {
|
||||
return extractOptionalParameter(req, "passcode");
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("lockVerificationCode")
|
||||
static String provideLockVerificationCode(HttpServletRequest req) {
|
||||
return extractRequiredParameter(req, "lockVerificationCode");
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("isLock")
|
||||
static Boolean provideIsLock(HttpServletRequest req) {
|
||||
return extractBooleanParameter(req, "isLock");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
import static google.registry.security.JsonResponseHelper.Status.ERROR;
|
||||
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
||||
import static google.registry.ui.server.registrar.RegistrarConsoleModule.PARAM_CLIENT_ID;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.config.RegistryConfig;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.RegistrarContact;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Action.Method;
|
||||
import google.registry.request.HttpException.ForbiddenException;
|
||||
import google.registry.request.JsonActionRunner;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.security.JsonResponseHelper;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.util.Clock;
|
||||
import google.registry.util.EmailMessage;
|
||||
import google.registry.util.SendEmailService;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
|
||||
/**
|
||||
* UI action that allows for creating registry locks. Locks / unlocks must be verified separately
|
||||
* before they are written permanently.
|
||||
*
|
||||
* <p>Note: at the moment we have no mechanism for JSON GET/POSTs in the same class or at the same
|
||||
* URL, which is why this is distinct from the {@link RegistryLockGetAction}.
|
||||
*/
|
||||
@Action(
|
||||
service = Action.Service.DEFAULT,
|
||||
path = RegistryLockPostAction.PATH,
|
||||
method = Method.POST,
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAction {
|
||||
public static final String PATH = "/registry-lock-post";
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private static final URL URL_BASE = RegistryConfig.getDefaultServer();
|
||||
private static final String VERIFICATION_EMAIL_TEMPLATE =
|
||||
"Please click the link below to perform the lock / unlock action on domain %s. Note: "
|
||||
+ "this code will expire in one hour.\n\n%s";
|
||||
|
||||
private final JsonActionRunner jsonActionRunner;
|
||||
private final AuthResult authResult;
|
||||
private final AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
private final SendEmailService sendEmailService;
|
||||
private final Clock clock;
|
||||
private final DomainLockUtils domainLockUtils;
|
||||
private final InternetAddress gSuiteOutgoingEmailAddress;
|
||||
|
||||
@Inject
|
||||
RegistryLockPostAction(
|
||||
JsonActionRunner jsonActionRunner,
|
||||
AuthResult authResult,
|
||||
AuthenticatedRegistrarAccessor registrarAccessor,
|
||||
SendEmailService sendEmailService,
|
||||
Clock clock,
|
||||
DomainLockUtils domainLockUtils,
|
||||
@Config("gSuiteOutgoingEmailAddress") InternetAddress gSuiteOutgoingEmailAddress) {
|
||||
this.jsonActionRunner = jsonActionRunner;
|
||||
this.authResult = authResult;
|
||||
this.registrarAccessor = registrarAccessor;
|
||||
this.sendEmailService = sendEmailService;
|
||||
this.clock = clock;
|
||||
this.domainLockUtils = domainLockUtils;
|
||||
this.gSuiteOutgoingEmailAddress = gSuiteOutgoingEmailAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
jsonActionRunner.run(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ?> handleJsonRequest(Map<String, ?> input) {
|
||||
try {
|
||||
checkArgumentNotNull(input, "Null JSON");
|
||||
RegistryLockPostInput postInput =
|
||||
GSON.fromJson(GSON.toJsonTree(input), RegistryLockPostInput.class);
|
||||
checkArgument(
|
||||
!Strings.isNullOrEmpty(postInput.clientId),
|
||||
"Missing key for client: %s",
|
||||
PARAM_CLIENT_ID);
|
||||
checkArgument(
|
||||
!Strings.isNullOrEmpty(postInput.fullyQualifiedDomainName),
|
||||
"Missing key for fullyQualifiedDomainName");
|
||||
checkNotNull(postInput.isLock, "Missing key for isLock");
|
||||
UserAuthInfo userAuthInfo =
|
||||
authResult
|
||||
.userAuthInfo()
|
||||
.orElseThrow(() -> new ForbiddenException("User is not logged in"));
|
||||
|
||||
boolean isAdmin = userAuthInfo.isUserAdmin();
|
||||
String userEmail = userAuthInfo.user().getEmail();
|
||||
if (!isAdmin) {
|
||||
verifyRegistryLockPassword(postInput, userEmail);
|
||||
}
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
RegistryLock registryLock =
|
||||
postInput.isLock
|
||||
? domainLockUtils.createRegistryLockRequest(
|
||||
postInput.fullyQualifiedDomainName,
|
||||
postInput.clientId,
|
||||
userEmail,
|
||||
isAdmin,
|
||||
clock)
|
||||
: domainLockUtils.createRegistryUnlockRequest(
|
||||
postInput.fullyQualifiedDomainName, postInput.clientId, isAdmin, clock);
|
||||
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
|
||||
});
|
||||
String action = postInput.isLock ? "lock" : "unlock";
|
||||
return JsonResponseHelper.create(SUCCESS, String.format("Successful %s", action));
|
||||
} catch (Throwable e) {
|
||||
logger.atWarning().withCause(e).log("Failed to lock/unlock domain with input %s", input);
|
||||
return JsonResponseHelper.create(
|
||||
ERROR,
|
||||
Optional.ofNullable(Throwables.getRootCause(e).getMessage()).orElse("Unspecified error"));
|
||||
}
|
||||
}
|
||||
|
||||
private void sendVerificationEmail(RegistryLock lock, String userEmail, boolean isLock) {
|
||||
try {
|
||||
String url =
|
||||
new URIBuilder()
|
||||
.setScheme("https")
|
||||
.setHost(URL_BASE.getHost())
|
||||
.setPath("registry-lock-verify")
|
||||
.setParameter("lockVerificationCode", lock.getVerificationCode())
|
||||
.setParameter("isLock", String.valueOf(isLock))
|
||||
.build()
|
||||
.toString();
|
||||
String body = String.format(VERIFICATION_EMAIL_TEMPLATE, lock.getDomainName(), url);
|
||||
ImmutableList<InternetAddress> recipients =
|
||||
ImmutableList.of(new InternetAddress(userEmail, true));
|
||||
String action = isLock ? "lock" : "unlock";
|
||||
sendEmailService.sendEmail(
|
||||
EmailMessage.newBuilder()
|
||||
.setBody(body)
|
||||
.setSubject(String.format("Registry %s verification", action))
|
||||
.setRecipients(recipients)
|
||||
.setFrom(gSuiteOutgoingEmailAddress)
|
||||
.build());
|
||||
} catch (AddressException | URISyntaxException e) {
|
||||
throw new RuntimeException(e); // caught above -- this is so we can run in a transaction
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyRegistryLockPassword(RegistryLockPostInput postInput, String userEmail)
|
||||
throws RegistrarAccessDeniedException {
|
||||
// Verify that the user can access the registrar and that the user has
|
||||
// registry lock enabled and provided a correct password
|
||||
Registrar registrar = registrarAccessor.getRegistrar(postInput.clientId);
|
||||
checkArgument(
|
||||
registrar.isRegistryLockAllowed(), "Registry lock not allowed for this registrar");
|
||||
checkArgument(!Strings.isNullOrEmpty(postInput.password), "Missing key for password");
|
||||
RegistrarContact registrarContact =
|
||||
registrar.getContacts().stream()
|
||||
.filter(contact -> contact.getEmailAddress().equals(userEmail))
|
||||
.findFirst()
|
||||
.orElseThrow(
|
||||
() ->
|
||||
new IllegalArgumentException(
|
||||
String.format("Unknown user email %s", userEmail)));
|
||||
checkArgument(
|
||||
registrarContact.verifyRegistryLockPassword(postInput.password),
|
||||
"Incorrect registry lock password for contact");
|
||||
}
|
||||
|
||||
/** Value class that represents the expected input body from the UI request. */
|
||||
private static class RegistryLockPostInput {
|
||||
private String clientId;
|
||||
private String fullyQualifiedDomainName;
|
||||
private Boolean isLock;
|
||||
private String password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static google.registry.ui.server.SoyTemplateUtils.CSS_RENAMING_MAP_SUPPLIER;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.template.soy.tofu.SoyTofu;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.ui.server.SoyTemplateUtils;
|
||||
import google.registry.ui.soy.registrar.RegistryLockVerificationSoyInfo;
|
||||
import google.registry.util.Clock;
|
||||
import java.util.HashMap;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Action that allows for verification of registry lock / unlock requests */
|
||||
@Action(
|
||||
service = Action.Service.DEFAULT,
|
||||
path = RegistryLockVerifyAction.PATH,
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public final class RegistryLockVerifyAction extends HtmlAction {
|
||||
|
||||
public static final String PATH = "/registry-lock-verify";
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private static final Supplier<SoyTofu> TOFU_SUPPLIER =
|
||||
SoyTemplateUtils.createTofuSupplier(
|
||||
google.registry.ui.soy.ConsoleSoyInfo.getInstance(),
|
||||
google.registry.ui.soy.AnalyticsSoyInfo.getInstance(),
|
||||
google.registry.ui.soy.registrar.RegistryLockVerificationSoyInfo.getInstance());
|
||||
|
||||
private final Clock clock;
|
||||
private final DomainLockUtils domainLockUtils;
|
||||
private final String lockVerificationCode;
|
||||
private final Boolean isLock;
|
||||
|
||||
@Inject
|
||||
public RegistryLockVerifyAction(
|
||||
Clock clock,
|
||||
DomainLockUtils domainLockUtils,
|
||||
@Parameter("lockVerificationCode") String lockVerificationCode,
|
||||
@Parameter("isLock") Boolean isLock) {
|
||||
this.clock = clock;
|
||||
this.domainLockUtils = domainLockUtils;
|
||||
this.lockVerificationCode = lockVerificationCode;
|
||||
this.isLock = isLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAfterLogin(HashMap<String, Object> data) {
|
||||
try {
|
||||
boolean isAdmin = authResult.userAuthInfo().get().isUserAdmin();
|
||||
final RegistryLock resultLock;
|
||||
if (isLock) {
|
||||
resultLock = domainLockUtils.verifyAndApplyLock(lockVerificationCode, isAdmin, clock);
|
||||
} else {
|
||||
resultLock = domainLockUtils.verifyAndApplyUnlock(lockVerificationCode, isAdmin, clock);
|
||||
}
|
||||
data.put("isLock", isLock);
|
||||
data.put("success", true);
|
||||
data.put("fullyQualifiedDomainName", resultLock.getDomainName());
|
||||
} catch (Throwable t) {
|
||||
logger.atWarning().withCause(t).log(
|
||||
"Error when verifying verification code %s", lockVerificationCode);
|
||||
data.put("success", false);
|
||||
data.put("errorMessage", Throwables.getRootCause(t).getMessage());
|
||||
}
|
||||
response.setPayload(
|
||||
TOFU_SUPPLIER
|
||||
.get()
|
||||
.newRenderer(RegistryLockVerificationSoyInfo.VERIFICATION_PAGE)
|
||||
.setCssRenamingMap(CSS_RENAMING_MAP_SUPPLIER.get())
|
||||
.setData(data)
|
||||
.render());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return PATH;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
* Use Hibernate's ServiceRegistry for bootstrapping (not JPA-compliant)
|
||||
-->
|
||||
<class>google.registry.model.domain.DomainBase</class>
|
||||
<class>google.registry.model.registrar.Registrar</class>
|
||||
<class>google.registry.model.registrar.RegistrarContact</class>
|
||||
<class>google.registry.schema.domain.RegistryLock</class>
|
||||
<class>google.registry.schema.tmch.ClaimsList</class>
|
||||
<class>google.registry.schema.cursor.Cursor</class>
|
||||
@@ -37,9 +39,14 @@
|
||||
|
||||
<!-- Customized type converters -->
|
||||
<class>google.registry.persistence.BloomFilterConverter</class>
|
||||
<class>google.registry.persistence.CidrAddressBlockListConverter</class>
|
||||
<class>google.registry.persistence.CreateAutoTimestampConverter</class>
|
||||
<class>google.registry.persistence.CurrencyUnitConverter</class>
|
||||
<class>google.registry.persistence.DateTimeConverter</class>
|
||||
<class>google.registry.persistence.RegistrarPocSetConverter</class>
|
||||
<class>google.registry.persistence.StatusValueSetConverter</class>
|
||||
<class>google.registry.persistence.StringListConverter</class>
|
||||
<class>google.registry.persistence.StringSetConverter</class>
|
||||
<class>google.registry.persistence.UpdateAutoTimestampConverter</class>
|
||||
<class>google.registry.persistence.ZonedDateTimeConverter</class>
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
{namespace registry.soy.registrar.registrylock.verification}
|
||||
|
||||
|
||||
/**
|
||||
* Results page for a registry lock/unlock verification.
|
||||
*/
|
||||
{template .verificationPage}
|
||||
{@param username: string} /** Arbitrary username to display. */
|
||||
{@param analyticsConfig: [googleAnalyticsId: string|null]}
|
||||
{@param success: bool}
|
||||
{@param? errorMessage: string}
|
||||
{@param? isLock: bool}
|
||||
{@param? fullyQualifiedDomainName: string}
|
||||
{call registry.soy.console.header}
|
||||
{param app: 'registrar' /}
|
||||
{param subtitle: 'Verify Registry Lock' /}
|
||||
{param analyticsConfig: $analyticsConfig /}
|
||||
{/call}
|
||||
{call registry.soy.console.googlebar data="all" /}
|
||||
<div id="reg-content-and-footer">
|
||||
<div id="reg-content">
|
||||
<h1>Registry Lock Verification</h1>
|
||||
{if $success}
|
||||
{call .success data="all" /}
|
||||
{else}
|
||||
{call .failure data="all" /}
|
||||
{/if}
|
||||
<h3><a href="/registrar">Return to Registrar Console</a></h3>
|
||||
</div>
|
||||
{call registry.soy.console.footer /}
|
||||
</div>
|
||||
{/template}
|
||||
|
||||
/**
|
||||
* Result page for failure, e.g. the UUID was invalid
|
||||
*/
|
||||
{template .failure}
|
||||
{@param? errorMessage: string}
|
||||
<h2 class="{css('kd-errormessage')}">Failed: {if isNonnull($errorMessage)}
|
||||
{$errorMessage}
|
||||
{else}
|
||||
Undefined error message
|
||||
{/if}
|
||||
</h2>
|
||||
{/template}
|
||||
|
||||
/**
|
||||
* Result page for a successful lock / unlock.
|
||||
*/
|
||||
{template .success}
|
||||
{@param? isLock: bool}
|
||||
{@param? fullyQualifiedDomainName: string}
|
||||
<h3>
|
||||
Success: {if $isLock}lock{else}unlock{/if} has been applied to {$fullyQualifiedDomainName}
|
||||
</h3>
|
||||
{/template}
|
||||
|
||||
@@ -26,7 +26,9 @@ public class DevTool {
|
||||
* any invocations in scripts (e.g. PDT, ICANN reporting).
|
||||
*/
|
||||
public static final ImmutableMap<String, Class<? extends Command>> COMMAND_MAP =
|
||||
ImmutableMap.of("generate_sql_schema", GenerateSqlSchemaCommand.class);
|
||||
ImmutableMap.of(
|
||||
"dump_golden_schema", DumpGoldenSchemaCommand.class,
|
||||
"generate_sql_schema", GenerateSqlSchemaCommand.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
RegistryToolEnvironment.parseFromArgs(args).setup();
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.testcontainers.containers.BindMode;
|
||||
import org.testcontainers.containers.Container;
|
||||
|
||||
/**
|
||||
* Generates a schema for JPA annotated classes using Hibernate.
|
||||
*
|
||||
* <p>Note that this isn't complete yet, as all of the persistent classes have not yet been
|
||||
* converted. After converting a class, a call to "addAnnotatedClass()" for the new class must be
|
||||
* added to the code below.
|
||||
*/
|
||||
@Parameters(separators = " =", commandDescription = "Dump golden schema.")
|
||||
public class DumpGoldenSchemaCommand extends PostgresqlCommand {
|
||||
|
||||
// The mount point in the container.
|
||||
private static final String CONTAINER_MOUNT_POINT = "/tmp/pg_dump.out";
|
||||
|
||||
@Parameter(
|
||||
names = {"--output", "-o"},
|
||||
description = "Output file",
|
||||
required = true)
|
||||
Path output;
|
||||
|
||||
@Override
|
||||
void runCommand() throws IOException, InterruptedException {
|
||||
Flyway flyway =
|
||||
Flyway.configure()
|
||||
.locations("sql/flyway")
|
||||
.dataSource(
|
||||
postgresContainer.getJdbcUrl(),
|
||||
postgresContainer.getUsername(),
|
||||
postgresContainer.getPassword())
|
||||
.load();
|
||||
flyway.migrate();
|
||||
|
||||
String userName = postgresContainer.getUsername();
|
||||
String databaseName = postgresContainer.getDatabaseName();
|
||||
Container.ExecResult result =
|
||||
postgresContainer.execInContainer(getSchemaDumpCommand(userName, databaseName));
|
||||
if (result.getExitCode() != 0) {
|
||||
throw new RuntimeException(result.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContainerCreate() throws IOException {
|
||||
// open the output file for write so we can mount it.
|
||||
new FileOutputStream(output.toFile()).close();
|
||||
postgresContainer.withFileSystemBind(
|
||||
output.toString(), CONTAINER_MOUNT_POINT, BindMode.READ_WRITE);
|
||||
}
|
||||
|
||||
private static String[] getSchemaDumpCommand(String username, String dbName) {
|
||||
return new String[] {
|
||||
"pg_dump",
|
||||
"-h",
|
||||
"localhost",
|
||||
"-U",
|
||||
username,
|
||||
"-f",
|
||||
CONTAINER_MOUNT_POINT,
|
||||
"--schema-only",
|
||||
"--no-owner",
|
||||
"--no-privileges",
|
||||
"--exclude-table",
|
||||
"flyway_schema_history",
|
||||
dbName
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright 2019 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 com.beust.jcommander.Parameter;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.persistence.NomulusPostgreSql;
|
||||
import org.testcontainers.containers.PostgreSQLContainer;
|
||||
|
||||
/** Base class for commands that need a PostgreSQL database. */
|
||||
public abstract class PostgresqlCommand implements Command {
|
||||
static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
protected static final String DB_NAME = "postgres";
|
||||
protected static final String DB_USERNAME = "postgres";
|
||||
protected static final String DB_PASSWORD = "domain-registry";
|
||||
|
||||
@VisibleForTesting
|
||||
public static final String DB_OPTIONS_CLASH =
|
||||
"Database host and port may not be specified along with the option to start a "
|
||||
+ "PostgreSQL container.";
|
||||
|
||||
@VisibleForTesting public static final int POSTGRESQL_PORT = 5432;
|
||||
|
||||
protected PostgreSQLContainer postgresContainer = null;
|
||||
|
||||
@Parameter(
|
||||
names = {"-s", "--start_postgresql"},
|
||||
description = "If specified, start PostgreSQL in a Docker container.")
|
||||
boolean startPostgresql = false;
|
||||
|
||||
@Parameter(
|
||||
names = {"-a", "--db_host"},
|
||||
description = "Database host name.")
|
||||
String databaseHost;
|
||||
|
||||
@Parameter(
|
||||
names = {"-p", "--db_port"},
|
||||
description = "Database port number. This defaults to the PostgreSQL default port.")
|
||||
Integer databasePort;
|
||||
|
||||
/**
|
||||
* Starts the database if appropriate.
|
||||
*
|
||||
* <p>Returns true if the database was successfully initialized, false if not.
|
||||
*/
|
||||
private boolean initializeDatabase() {
|
||||
// Start PostgreSQL if requested.
|
||||
if (startPostgresql) {
|
||||
// Complain if the user has also specified either --db_host or --db_port.
|
||||
if (databaseHost != null || databasePort != null) {
|
||||
System.err.println(DB_OPTIONS_CLASH);
|
||||
// TODO: it would be nice to exit(1) here, but this breaks testability.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the container and store the address information.
|
||||
postgresContainer =
|
||||
new PostgreSQLContainer(NomulusPostgreSql.getDockerTag())
|
||||
.withDatabaseName(DB_NAME)
|
||||
.withUsername(DB_USERNAME)
|
||||
.withPassword(DB_PASSWORD);
|
||||
try {
|
||||
onContainerCreate();
|
||||
} catch (Exception e) {
|
||||
logger.atSevere().withCause(e).log("Error in container callback hook.");
|
||||
return false;
|
||||
}
|
||||
postgresContainer.start();
|
||||
databaseHost = postgresContainer.getContainerIpAddress();
|
||||
databasePort = postgresContainer.getMappedPort(POSTGRESQL_PORT);
|
||||
} else if (databaseHost == null) {
|
||||
System.err.println(
|
||||
"You must specify either --start_postgresql to start a PostgreSQL database in a\n"
|
||||
+ "docker instance, or specify --db_host (and, optionally, --db_port) to identify\n"
|
||||
+ "the location of a running instance. To start a long-lived instance (suitable\n"
|
||||
+ "for running this command multiple times) run this:\n\n"
|
||||
+ " docker run --rm --name some-postgres -e POSTGRES_PASSWORD=domain-registry \\\n"
|
||||
+ " -d "
|
||||
+ NomulusPostgreSql.getDockerTag()
|
||||
+ "\n\nCopy the container id output from the command, then run:\n\n"
|
||||
+ " docker inspect <container-id> | grep IPAddress\n\n"
|
||||
+ "To obtain the value for --db-host.\n");
|
||||
// TODO(mmuller): need exit(1), see above.
|
||||
return false;
|
||||
}
|
||||
|
||||
// use the default port if non has been defined.
|
||||
if (databasePort == null) {
|
||||
databasePort = POSTGRESQL_PORT;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
if (!initializeDatabase()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
runCommand();
|
||||
} finally {
|
||||
if (postgresContainer != null) {
|
||||
postgresContainer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Called after the container has been created but before it has been started. */
|
||||
protected void onContainerCreate() throws Exception {}
|
||||
|
||||
/** Command to be run while the database is running. */
|
||||
abstract void runCommand() throws Exception;
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.FakeClock;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -201,7 +200,7 @@ public final class RegistryLockDaoTest {
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("example.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.isSuperuser(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link CidrAddressBlockListConverter}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class CidrAddressBlockListUserTypeTest {
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
|
||||
|
||||
@Test
|
||||
public void roundTripConversion_returnsSameCidrAddressBlock() {
|
||||
List<CidrAddressBlock> addresses =
|
||||
ImmutableList.of(
|
||||
CidrAddressBlock.create("0.0.0.0/32"),
|
||||
CidrAddressBlock.create("255.255.255.254/31"),
|
||||
CidrAddressBlock.create("::"),
|
||||
CidrAddressBlock.create("8000::/1"),
|
||||
CidrAddressBlock.create("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
|
||||
TestEntity testEntity = new TestEntity(addresses);
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
|
||||
TestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
|
||||
assertThat(persisted.addresses).isEqualTo(addresses);
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
||||
private static class TestEntity extends ImmutableObject {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
List<CidrAddressBlock> addresses;
|
||||
|
||||
private TestEntity() {}
|
||||
|
||||
private TestEntity(List<CidrAddressBlock> addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.registrar.Registrar.BillingAccountEntry;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link CurrencyToBillingMapUserType}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class CurrencyToBillingMapUserTypeTest {
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder()
|
||||
.withInitScript("sql/flyway/V14__load_extension_for_hstore.sql")
|
||||
.withEntityClass(TestEntity.class)
|
||||
.buildUnitTestRule();
|
||||
|
||||
@Test
|
||||
public void roundTripConversion_returnsSameCurrencyToBillingMap() {
|
||||
ImmutableMap<CurrencyUnit, BillingAccountEntry> currencyToBilling =
|
||||
ImmutableMap.of(
|
||||
CurrencyUnit.of("USD"),
|
||||
new BillingAccountEntry(CurrencyUnit.of("USD"), "accountId1"),
|
||||
CurrencyUnit.of("CNY"),
|
||||
new BillingAccountEntry(CurrencyUnit.of("CNY"), "accountId2"));
|
||||
TestEntity testEntity = new TestEntity(currencyToBilling);
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
|
||||
TestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
|
||||
assertThat(persisted.currencyToBilling).containsExactlyEntriesIn(currencyToBilling);
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
||||
private static class TestEntity extends ImmutableObject {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
@Type(type = "google.registry.persistence.CurrencyToBillingMapUserType")
|
||||
Map<CurrencyUnit, BillingAccountEntry> currencyToBilling;
|
||||
|
||||
private TestEntity() {}
|
||||
|
||||
private TestEntity(Map<CurrencyUnit, BillingAccountEntry> currencyToBilling) {
|
||||
this.currencyToBilling = currencyToBilling;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-22
@@ -18,29 +18,27 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link EnumSetUserType}. */
|
||||
/** Unit tests for {@link StatusValueSetConverter}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class EnumSetUserTypeTest {
|
||||
public class StatusValueSetConverterTest {
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
|
||||
|
||||
public EnumSetUserTypeTest() {}
|
||||
|
||||
@Test
|
||||
public void testRoundTrip() {
|
||||
Set<TestEnum> enums = ImmutableSet.of(TestEnum.BAR, TestEnum.FOO);
|
||||
Set<StatusValue> enums = ImmutableSet.of(StatusValue.INACTIVE, StatusValue.PENDING_DELETE);
|
||||
TestEntity obj = new TestEntity("foo", enums);
|
||||
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(obj));
|
||||
@@ -49,29 +47,15 @@ public class EnumSetUserTypeTest {
|
||||
assertThat(persisted.data).isEqualTo(enums);
|
||||
}
|
||||
|
||||
enum TestEnum {
|
||||
FOO,
|
||||
BAR,
|
||||
BAZ;
|
||||
|
||||
public static class TestEnumType extends EnumSetUserType<TestEnum> {
|
||||
@Override
|
||||
protected Object convertToElem(Object value) {
|
||||
return TestEnum.valueOf((String) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity")
|
||||
static class TestEntity {
|
||||
@Id String name;
|
||||
|
||||
@Type(type = "google.registry.persistence.EnumSetUserTypeTest$TestEnum$TestEnumType")
|
||||
Set<TestEnum> data;
|
||||
Set<StatusValue> data;
|
||||
|
||||
TestEntity() {}
|
||||
|
||||
TestEntity(String name, Set<TestEnum> data) {
|
||||
TestEntity(String name, Set<StatusValue> data) {
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
}
|
||||
+2
-4
@@ -26,15 +26,14 @@ import java.util.List;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.NoResultException;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link StringListUserType}. */
|
||||
/** Unit tests for {@link StringListConverter}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class StringListUserTypeTest {
|
||||
public class StringListConverterTest {
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
|
||||
@@ -123,7 +122,6 @@ public class StringListUserTypeTest {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
@Type(type = "google.registry.persistence.StringListUserType")
|
||||
List<String> tlds;
|
||||
|
||||
private TestEntity() {}
|
||||
+2
-4
@@ -24,15 +24,14 @@ import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link StringSetUserType}. */
|
||||
/** Unit tests for {@link StringSetConverter}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class StringSetUserTypeTest {
|
||||
public class StringSetConverterTest {
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
|
||||
@@ -70,7 +69,6 @@ public class StringSetUserTypeTest {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
@Type(type = "google.registry.persistence.StringSetUserType")
|
||||
Set<String> tlds;
|
||||
|
||||
private TestEntity() {}
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.registrar.Registrar.State;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link Enumerated} annotation. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class StringValueEnumeratedTest {
|
||||
|
||||
@Rule
|
||||
public final JpaUnitTestRule jpaRule =
|
||||
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
|
||||
|
||||
@Test
|
||||
public void roundTripConversion_returnsSameEnum() {
|
||||
TestEntity testEntity = new TestEntity(State.ACTIVE);
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
|
||||
TestEntity persisted =
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
|
||||
assertThat(persisted.state).isEqualTo(State.ACTIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNativeQuery_succeeds() {
|
||||
TestEntity testEntity = new TestEntity(State.DISABLED);
|
||||
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
|
||||
|
||||
assertThat(
|
||||
jpaTm()
|
||||
.transact(
|
||||
() ->
|
||||
jpaTm()
|
||||
.getEntityManager()
|
||||
.createNativeQuery("SELECT state FROM \"TestEntity\" WHERE name = 'id'")
|
||||
.getSingleResult()))
|
||||
.isEqualTo("DISABLED");
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
||||
private static class TestEntity extends ImmutableObject {
|
||||
|
||||
@Id String name = "id";
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
State state;
|
||||
|
||||
private TestEntity() {}
|
||||
|
||||
private TestEntity(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import google.registry.tools.UpdateReservedListCommandTest;
|
||||
import google.registry.tools.server.CreatePremiumListActionTest;
|
||||
import google.registry.tools.server.UpdatePremiumListActionTest;
|
||||
import google.registry.ui.server.registrar.RegistryLockGetActionTest;
|
||||
import google.registry.ui.server.registrar.RegistryLockVerifyActionTest;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
@@ -60,6 +61,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
PremiumListDaoTest.class,
|
||||
RegistryLockDaoTest.class,
|
||||
RegistryLockGetActionTest.class,
|
||||
RegistryLockVerifyActionTest.class,
|
||||
ReservedListDaoTest.class,
|
||||
UnlockDomainCommandTest.class,
|
||||
UpdatePremiumListActionTest.class,
|
||||
|
||||
@@ -202,4 +202,38 @@ public class PremiumListDaoTest {
|
||||
() -> PremiumListDao.getPremiumPrice("foobar", Registry.get("tld")));
|
||||
assertThat(thrown).hasMessageThat().isEqualTo("Could not load premium list 'tld'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPremiumPrice_worksForJPY() {
|
||||
persistResource(
|
||||
newRegistry("foobar", "FOOBAR")
|
||||
.asBuilder()
|
||||
.setPremiumListKey(
|
||||
Key.create(
|
||||
getCrossTldKey(),
|
||||
google.registry.model.registry.label.PremiumList.class,
|
||||
"premlist"))
|
||||
.build());
|
||||
PremiumListDao.saveNew(
|
||||
PremiumList.create(
|
||||
"premlist",
|
||||
JPY,
|
||||
ImmutableMap.of(
|
||||
"silver",
|
||||
BigDecimal.valueOf(10.00),
|
||||
"gold",
|
||||
BigDecimal.valueOf(1000.0),
|
||||
"palladium",
|
||||
BigDecimal.valueOf(15000))));
|
||||
assertThat(PremiumListDao.getPremiumPrice("silver", Registry.get("foobar")))
|
||||
.hasValue(moneyOf(JPY, 10));
|
||||
assertThat(PremiumListDao.getPremiumPrice("gold", Registry.get("foobar")))
|
||||
.hasValue(moneyOf(JPY, 1000));
|
||||
assertThat(PremiumListDao.getPremiumPrice("palladium", Registry.get("foobar")))
|
||||
.hasValue(moneyOf(JPY, 15000));
|
||||
}
|
||||
|
||||
private static Money moneyOf(CurrencyUnit unit, double amount) {
|
||||
return Money.of(unit, BigDecimal.valueOf(amount).setScale(unit.getDecimalPlaces()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,9 @@ public final class RegistryTestServer {
|
||||
route("/registrar-ote-setup", FrontendServlet.class),
|
||||
route("/registrar-ote-status", FrontendServlet.class),
|
||||
route("/registrar-settings", FrontendServlet.class),
|
||||
route("/registry-lock-get", FrontendServlet.class));
|
||||
route("/registry-lock-get", FrontendServlet.class),
|
||||
route("/registry-lock-post", FrontendServlet.class),
|
||||
route("/registry-lock-verify", FrontendServlet.class));
|
||||
|
||||
private static final ImmutableList<Class<? extends Filter>> FILTERS = ImmutableList.of(
|
||||
ObjectifyFilter.class,
|
||||
|
||||
@@ -178,8 +178,7 @@ public class CreateReservedListCommandTest extends
|
||||
|
||||
@Test
|
||||
public void testSaveToCloudSql_succeeds() throws Exception {
|
||||
runCommandForced(
|
||||
"--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath, "--also_cloud_sql");
|
||||
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
|
||||
verifyXnq9jyb4cInDatastore();
|
||||
verifyXnq9jyb4cInCloudSql();
|
||||
}
|
||||
@@ -193,8 +192,7 @@ public class CreateReservedListCommandTest extends
|
||||
"xn--q9jyb4c_common-reserved",
|
||||
true,
|
||||
ImmutableMap.of("testdomain", ReservedEntry.create(FULLY_BLOCKED, ""))));
|
||||
runCommandForced(
|
||||
"--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath, "--also_cloud_sql");
|
||||
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
|
||||
verifyXnq9jyb4cInDatastore();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,10 @@ import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCo
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.DatastoreHelper;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.UserInfo;
|
||||
import google.registry.util.StringGenerator.Alphabets;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.joda.time.Duration;
|
||||
@@ -57,6 +59,8 @@ public final class DomainLockUtilsTest {
|
||||
private static final String POC_ID = "marla.singer@example.com";
|
||||
|
||||
private final FakeClock clock = new FakeClock();
|
||||
private final DomainLockUtils domainLockUtils =
|
||||
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
|
||||
|
||||
@Rule
|
||||
public final AppEngineRule appEngineRule =
|
||||
@@ -80,39 +84,39 @@ public final class DomainLockUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testSuccess_createLock() {
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_createUnlock() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
DomainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_createUnlock_adminUnlockingAdmin() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
DomainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
domainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", true, clock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_createLock_previousLockExpired() {
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
clock.advanceBy(Duration.standardDays(1));
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_applyLockDomain() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
assertThat(reloadDomain().getStatusValues()).containsExactlyElementsIn(REGISTRY_LOCK_STATUSES);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_UPDATE);
|
||||
assertThat(historyEntry.getRequestedByRegistrar()).isTrue();
|
||||
@@ -125,12 +129,12 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testSuccess_applyUnlockDomain() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
RegistryLock unlock =
|
||||
DomainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
DomainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false, clock);
|
||||
|
||||
assertThat(reloadDomain().getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
|
||||
ImmutableList<HistoryEntry> historyEntries =
|
||||
@@ -149,8 +153,8 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testSuccess_applyAdminLock_onlyHistoryEntry() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_UPDATE);
|
||||
assertThat(historyEntry.getRequestedByRegistrar()).isFalse();
|
||||
@@ -161,16 +165,16 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_createUnlock_alreadyPendingUnlock() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
DomainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryUnlockRequest(
|
||||
domainLockUtils.createRegistryUnlockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("A pending unlock action already exists for example.tld");
|
||||
@@ -179,13 +183,13 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_createUnlock_nonAdminUnlockingAdmin() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock);
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryUnlockRequest(
|
||||
domainLockUtils.createRegistryUnlockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.tld");
|
||||
@@ -197,7 +201,7 @@ public final class DomainLockUtilsTest {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
"asdf.tld", "TheRegistrar", POC_ID, false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Unknown domain asdf.tld");
|
||||
@@ -205,12 +209,12 @@ public final class DomainLockUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_createLock_alreadyPendingLock() {
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("A pending or completed lock action already exists for example.tld");
|
||||
@@ -223,7 +227,7 @@ public final class DomainLockUtilsTest {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain example.tld is already locked");
|
||||
@@ -235,7 +239,7 @@ public final class DomainLockUtilsTest {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.createRegistryUnlockRequest(
|
||||
domainLockUtils.createRegistryUnlockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain example.tld is already unlocked");
|
||||
@@ -244,14 +248,14 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_applyLock_alreadyApplied() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domain = reloadDomain();
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock)))
|
||||
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain example.tld is already locked");
|
||||
assertNoDomainChanges();
|
||||
@@ -260,13 +264,13 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_applyLock_expired() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
clock.advanceBy(Duration.standardDays(1));
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock)))
|
||||
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("The pending lock has expired; please try again");
|
||||
assertNoDomainChanges();
|
||||
@@ -275,11 +279,11 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_applyLock_nonAdmin_applyAdminLock() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
domainLockUtils.createRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", null, true, clock);
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock)))
|
||||
() -> domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Non-admin user cannot complete admin lock");
|
||||
assertNoDomainChanges();
|
||||
@@ -288,18 +292,18 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_applyUnlock_alreadyUnlocked() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false, clock);
|
||||
RegistryLock unlock =
|
||||
DomainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
DomainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false, clock);
|
||||
domainLockUtils.createRegistryUnlockRequest(DOMAIN_NAME, "TheRegistrar", false, clock);
|
||||
domainLockUtils.verifyAndApplyUnlock(unlock.getVerificationCode(), false, clock);
|
||||
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
DomainLockUtils.verifyAndApplyUnlock(
|
||||
domainLockUtils.verifyAndApplyUnlock(
|
||||
unlock.getVerificationCode(), false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain example.tld is already unlocked");
|
||||
@@ -309,7 +313,7 @@ public final class DomainLockUtilsTest {
|
||||
@Test
|
||||
public void testFailure_applyLock_alreadyLocked() {
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
domainLockUtils.createRegistryLockRequest(
|
||||
DOMAIN_NAME, "TheRegistrar", POC_ID, false, clock);
|
||||
String verificationCode = lock.getVerificationCode();
|
||||
// reload to pick up modification times, etc
|
||||
@@ -318,7 +322,7 @@ public final class DomainLockUtilsTest {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> DomainLockUtils.verifyAndApplyLock(verificationCode, false, clock)))
|
||||
() -> domainLockUtils.verifyAndApplyLock(verificationCode, false, clock)))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain example.tld is already locked");
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class DumpGoldenSchemaCommandTest extends CommandTestCase<DumpGoldenSchemaCommand> {
|
||||
|
||||
@Rule public TemporaryFolder tmp = new TemporaryFolder();
|
||||
|
||||
public DumpGoldenSchemaCommandTest() {}
|
||||
|
||||
@Test
|
||||
public void testSchemaGeneration() throws Exception {
|
||||
runCommand(
|
||||
"--output=" + tmp.getRoot() + File.separatorChar + "golden.sql", "--start_postgresql");
|
||||
assertThat(new File(tmp.getRoot(), "golden.sql").length()).isGreaterThan(1);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,9 @@ import google.registry.model.registrar.Registrar.Type;
|
||||
import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.util.StringGenerator.Alphabets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -51,6 +53,8 @@ public class LockDomainCommandTest extends CommandTestCase<LockDomainCommand> {
|
||||
createTld("tld");
|
||||
command.registryAdminClientId = "adminreg";
|
||||
command.clock = new FakeClock();
|
||||
command.domainLockUtils =
|
||||
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -33,7 +33,9 @@ import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.util.StringGenerator.Alphabets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -54,14 +56,16 @@ public class UnlockDomainCommandTest extends CommandTestCase<UnlockDomainCommand
|
||||
createTld("tld");
|
||||
command.registryAdminClientId = "adminreg";
|
||||
command.clock = new FakeClock();
|
||||
command.domainLockUtils =
|
||||
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
|
||||
}
|
||||
|
||||
private DomainBase persistLockedDomain(String domainName, String registrarId) {
|
||||
DomainBase domain = persistResource(newDomainBase(domainName));
|
||||
RegistryLock lock =
|
||||
DomainLockUtils.createRegistryLockRequest(
|
||||
command.domainLockUtils.createRegistryLockRequest(
|
||||
domainName, registrarId, null, true, command.clock);
|
||||
DomainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, command.clock);
|
||||
command.domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), true, command.clock);
|
||||
return reloadResource(domain);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,20 +116,18 @@ public class UpdateReservedListCommandTest extends
|
||||
public void testSaveToCloudSql_succeeds() throws Exception {
|
||||
populateInitialReservedListInDatastore(true);
|
||||
populateInitialReservedListInCloudSql(true);
|
||||
runCommandForced(
|
||||
"--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath, "--also_cloud_sql");
|
||||
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
|
||||
verifyXnq9jyb4cInDatastore();
|
||||
verifyXnq9jyb4cInCloudSql();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveToCloudSql_succeedsEvenPreviousListNotExist() throws Exception {
|
||||
// Note that, during the dual-write phase, we just always save the revered list to
|
||||
// Cloud SQL (if --also_cloud_sql is set) without checking if there is a list with
|
||||
// same name. This is to backfill the existing list in Datastore when we update it.
|
||||
// Note that, during the dual-write phase, we always save the reserved list to Cloud SQL without
|
||||
// checking if there is a list with same name. This is to backfill the existing list in Cloud
|
||||
// Datastore when we update it.
|
||||
populateInitialReservedListInDatastore(true);
|
||||
runCommandForced(
|
||||
"--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath, "--also_cloud_sql");
|
||||
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
|
||||
verifyXnq9jyb4cInDatastore();
|
||||
assertThat(ReservedListDao.checkExists("xn--q9jyb4c_common-reserved")).isTrue();
|
||||
}
|
||||
|
||||
+4
-5
@@ -43,7 +43,6 @@ import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -97,7 +96,7 @@ public final class RegistryLockGetActionTest {
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("example.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.build();
|
||||
@@ -107,7 +106,7 @@ public final class RegistryLockGetActionTest {
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("adminexample.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode("122222222ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.isSuperuser(true)
|
||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.build();
|
||||
@@ -116,7 +115,7 @@ public final class RegistryLockGetActionTest {
|
||||
.setRepoId("repoId")
|
||||
.setDomainName("incomplete.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode("111111111ABCDEFGHJKLMNPQRSTUVWXY")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.build();
|
||||
|
||||
@@ -126,7 +125,7 @@ public final class RegistryLockGetActionTest {
|
||||
.setDomainName("unlocked.test")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setVerificationCode("123456789ABCDEFGHJKLMNPQRSTUUUUU")
|
||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
||||
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatastoreHelper.newDomainBase;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestRule;
|
||||
import google.registry.request.JsonActionRunner;
|
||||
import google.registry.request.JsonResponse;
|
||||
import google.registry.request.ResponseImpl;
|
||||
import google.registry.request.auth.AuthLevel;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.Role;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.util.EmailMessage;
|
||||
import google.registry.util.SendEmailService;
|
||||
import google.registry.util.StringGenerator.Alphabets;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class RegistryLockPostActionTest {
|
||||
|
||||
private static final String EMAIL_MESSAGE_TEMPLATE =
|
||||
"Please click the link below to perform the lock \\/ unlock action on domain example.tld. "
|
||||
+ "Note: this code will expire in one hour.\n\n"
|
||||
+ "https:\\/\\/localhost\\/registry-lock-verify\\?lockVerificationCode="
|
||||
+ "[0-9a-zA-Z_\\-]+&isLock=(true|false)";
|
||||
|
||||
@Rule public final AppEngineRule appEngineRule = AppEngineRule.builder().withDatastore().build();
|
||||
|
||||
@Rule
|
||||
public final JpaIntegrationTestRule jpaRule =
|
||||
new JpaTestRules.Builder().buildIntegrationTestRule();
|
||||
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
private final User userWithoutPermission =
|
||||
new User("johndoe@theregistrar.com", "gmail.com", "31337");
|
||||
// Marla Singer has registry lock auth permissions
|
||||
private final User userWithLockPermission =
|
||||
new User("Marla.Singer@crr.com", "gmail.com", "31337");
|
||||
private final FakeClock clock = new FakeClock();
|
||||
|
||||
private InternetAddress outgoingAddress;
|
||||
private DomainBase domain;
|
||||
private RegistryLockPostAction action;
|
||||
|
||||
@Mock SendEmailService emailService;
|
||||
@Mock HttpServletResponse mockResponse;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
createTld("tld");
|
||||
domain = persistResource(newDomainBase("example.tld"));
|
||||
outgoingAddress = new InternetAddress("domain-registry@example.com");
|
||||
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithLockPermission, false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_lock() throws Exception {
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "Marla.Singer@crr.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_unlock() throws Exception {
|
||||
RegistryLockDao.save(
|
||||
createLock().asBuilder().setLockCompletionTimestamp(clock.nowUtc()).build());
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
assertSuccess(response, "unlock", "Marla.Singer@crr.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_unlock_adminUnlockingAdmin() throws Exception {
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.isSuperuser(true)
|
||||
.setLockCompletionTimestamp(clock.nowUtc())
|
||||
.build());
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithoutPermission, true)));
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
// we should still email the admin user's email address
|
||||
assertSuccess(response, "unlock", "johndoe@theregistrar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_unlock_noLock() {
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
assertFailureWithMessage(response, "No lock object for domain example.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_unlock_alreadyUnlocked() {
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(clock.nowUtc())
|
||||
.setUnlockRequestTimestamp(clock.nowUtc())
|
||||
.build());
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
assertFailureWithMessage(response, "A pending unlock action already exists for example.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_unlock_nonAdminUnlockingAdmin() {
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.isSuperuser(true)
|
||||
.setLockCompletionTimestamp(clock.nowUtc())
|
||||
.build());
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
assertFailureWithMessage(
|
||||
response, "Non-admin user cannot unlock admin-locked domain example.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_adminUser() throws Exception {
|
||||
// Admin user should be able to lock/unlock regardless -- and we use the admin user's email
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithoutPermission, true)));
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_adminUser_doesNotRequirePassword() throws Exception {
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithoutPermission, true)));
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"isLock", true));
|
||||
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_noInput() {
|
||||
Map<String, ?> response = action.handleJsonRequest(null);
|
||||
assertFailureWithMessage(response, "Null JSON");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_noClientId() {
|
||||
Map<String, ?> response = action.handleJsonRequest(ImmutableMap.of());
|
||||
assertFailureWithMessage(response, "Missing key for client: clientId");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_emptyClientId() {
|
||||
Map<String, ?> response = action.handleJsonRequest(ImmutableMap.of("clientId", ""));
|
||||
assertFailureWithMessage(response, "Missing key for client: clientId");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_noDomainName() {
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of("clientId", "TheRegistrar", "password", "hi", "isLock", true));
|
||||
assertFailureWithMessage(response, "Missing key for fullyQualifiedDomainName");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_noLockParam() {
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"password", "hi"));
|
||||
assertFailureWithMessage(response, "Missing key for isLock");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_notAllowedOnRegistrar() {
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertFailureWithMessage(response, "Registry lock not allowed for this registrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_noPassword() {
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"isLock", true));
|
||||
assertFailureWithMessage(response, "Missing key for password");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_notEnabledForRegistrarContact() {
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithoutPermission, false)));
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"isLock", true,
|
||||
"password", "hi"));
|
||||
assertFailureWithMessage(response, "Incorrect registry lock password for contact");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_badPassword() {
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"isLock", true,
|
||||
"password", "badPassword"));
|
||||
assertFailureWithMessage(response, "Incorrect registry lock password for contact");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_invalidDomain() {
|
||||
Map<String, ?> response =
|
||||
action.handleJsonRequest(
|
||||
ImmutableMap.of(
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "bad.tld",
|
||||
"isLock", true,
|
||||
"password", "hi"));
|
||||
assertFailureWithMessage(response, "Unknown domain bad.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_previousLockUnlocked() throws Exception {
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(clock.nowUtc().minusMinutes(1))
|
||||
.setUnlockRequestTimestamp(clock.nowUtc().minusMinutes(1))
|
||||
.setUnlockCompletionTimestamp(clock.nowUtc().minusMinutes(1))
|
||||
.build());
|
||||
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "Marla.Singer@crr.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_previousLockExpired() throws Exception {
|
||||
RegistryLock previousLock = RegistryLockDao.save(createLock());
|
||||
previousLock = RegistryLockDao.getByVerificationCode(previousLock.getVerificationCode()).get();
|
||||
clock.setTo(previousLock.getLockRequestTimestamp().plusHours(2));
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "Marla.Singer@crr.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyPendingLock() {
|
||||
RegistryLockDao.save(createLock());
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertFailureWithMessage(
|
||||
response, "A pending or completed lock action already exists for example.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyLocked() {
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertFailureWithMessage(response, "Domain example.tld is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyUnlocked() {
|
||||
Map<String, ?> response = action.handleJsonRequest(unlockRequest());
|
||||
assertFailureWithMessage(response, "Domain example.tld is already unlocked");
|
||||
}
|
||||
|
||||
private ImmutableMap<String, Object> lockRequest() {
|
||||
return fullRequest(true);
|
||||
}
|
||||
|
||||
private ImmutableMap<String, Object> unlockRequest() {
|
||||
return fullRequest(false);
|
||||
}
|
||||
|
||||
private ImmutableMap<String, Object> fullRequest(boolean lock) {
|
||||
return ImmutableMap.of(
|
||||
"isLock", lock,
|
||||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"password", "hi");
|
||||
}
|
||||
|
||||
private RegistryLock createLock() {
|
||||
DomainBase domain = loadByForeignKey(DomainBase.class, "example.tld", clock.nowUtc()).get();
|
||||
return new RegistryLock.Builder()
|
||||
.setDomainName("example.tld")
|
||||
.isSuperuser(false)
|
||||
.setVerificationCode(UUID.randomUUID().toString())
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setRepoId(domain.getRepoId())
|
||||
.setRegistrarPocId("Marla.Singer@crr.com")
|
||||
.build();
|
||||
}
|
||||
|
||||
private void assertSuccess(Map<String, ?> response, String lockAction, String recipient)
|
||||
throws Exception {
|
||||
assertThat(response)
|
||||
.containsExactly(
|
||||
"status", "SUCCESS",
|
||||
"results", ImmutableList.of(),
|
||||
"message", String.format("Successful %s", lockAction));
|
||||
verifyEmail(recipient);
|
||||
}
|
||||
|
||||
private void assertFailureWithMessage(Map<String, ?> response, String message) {
|
||||
assertThat(response)
|
||||
.containsExactly("status", "ERROR", "results", ImmutableList.of(), "message", message);
|
||||
verifyNoMoreInteractions(emailService);
|
||||
}
|
||||
|
||||
private void verifyEmail(String recipient) throws Exception {
|
||||
ArgumentCaptor<EmailMessage> emailCaptor = ArgumentCaptor.forClass(EmailMessage.class);
|
||||
verify(emailService).sendEmail(emailCaptor.capture());
|
||||
EmailMessage sentMessage = emailCaptor.getValue();
|
||||
assertThat(sentMessage.subject()).matches("Registry (un)?lock verification");
|
||||
assertThat(sentMessage.body()).matches(EMAIL_MESSAGE_TEMPLATE);
|
||||
assertThat(sentMessage.from()).isEqualTo(new InternetAddress("domain-registry@example.com"));
|
||||
assertThat(sentMessage.recipients()).containsExactly(new InternetAddress(recipient));
|
||||
}
|
||||
|
||||
private RegistryLockPostAction createAction(AuthResult authResult) {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
AuthenticatedRegistrarAccessor.createForTesting(
|
||||
ImmutableSetMultimap.of("TheRegistrar", Role.OWNER, "NewRegistrar", Role.OWNER));
|
||||
JsonActionRunner jsonActionRunner =
|
||||
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
|
||||
DomainLockUtils domainLockUtils =
|
||||
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
|
||||
return new RegistryLockPostAction(
|
||||
jsonActionRunner,
|
||||
authResult,
|
||||
registrarAccessor,
|
||||
emailService,
|
||||
clock,
|
||||
domainLockUtils,
|
||||
outgoingAddress);
|
||||
}
|
||||
}
|
||||
+351
@@ -0,0 +1,351 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.testing.DatastoreHelper.createTlds;
|
||||
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
|
||||
import static google.registry.testing.DatastoreHelper.newDomainBase;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveHost;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_MOVED_TEMPORARILY;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.appengine.api.users.UserService;
|
||||
import com.google.appengine.api.users.UserServiceFactory;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.transaction.JpaTestRules;
|
||||
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
|
||||
import google.registry.request.auth.AuthLevel;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.security.XsrfTokenManager;
|
||||
import google.registry.testing.AppEngineRule;
|
||||
import google.registry.testing.DatastoreHelper;
|
||||
import google.registry.testing.DeterministicStringGenerator;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.testing.InjectRule;
|
||||
import google.registry.testing.UserInfo;
|
||||
import google.registry.tools.DomainLockUtils;
|
||||
import google.registry.util.StringGenerator;
|
||||
import google.registry.util.StringGenerator.Alphabets;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.joda.time.Duration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class RegistryLockVerifyActionTest {
|
||||
|
||||
private final FakeClock fakeClock = new FakeClock();
|
||||
|
||||
@Rule
|
||||
public final AppEngineRule appEngineRule =
|
||||
AppEngineRule.builder()
|
||||
.withDatastore()
|
||||
.withUserService(UserInfo.create("marla.singer@example.com", "12345"))
|
||||
.build();
|
||||
|
||||
@Rule
|
||||
public final JpaIntegrationWithCoverageRule jpaRule =
|
||||
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageRule();
|
||||
|
||||
@Rule public final InjectRule inject = new InjectRule();
|
||||
|
||||
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
private final UserService userService = UserServiceFactory.getUserService();
|
||||
private final User user = new User("marla.singer@example.com", "gmail.com", "12345");
|
||||
private final String lockId = "123456789ABCDEFGHJKLMNPQRSTUVWXY";
|
||||
private final StringGenerator stringGenerator =
|
||||
new DeterministicStringGenerator(Alphabets.BASE_58);
|
||||
|
||||
private FakeResponse response;
|
||||
private DomainBase domain;
|
||||
private AuthResult authResult;
|
||||
private RegistryLockVerifyAction action;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
createTlds("tld", "net");
|
||||
HostResource host = persistActiveHost("ns1.example.net");
|
||||
domain = persistResource(newDomainBase("example.tld", host));
|
||||
when(request.getRequestURI()).thenReturn("https://registry.example/registry-lock-verification");
|
||||
action = createAction(lockId, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_lockDomain() {
|
||||
RegistryLockDao.save(createLock());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(reloadDomain().getStatusValues()).containsExactlyElementsIn(REGISTRY_LOCK_STATUSES);
|
||||
assertThat(response.getPayload()).contains("Success: lock has been applied to example.tld");
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_UPDATE);
|
||||
assertThat(historyEntry.getRequestedByRegistrar()).isTrue();
|
||||
assertThat(historyEntry.getBySuperuser()).isFalse();
|
||||
assertThat(historyEntry.getReason())
|
||||
.isEqualTo("Lock or unlock of a domain through a RegistryLock operation");
|
||||
assertBillingEvent(historyEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_unlockDomain() {
|
||||
action = createAction(lockId, false);
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
RegistryLockDao.save(
|
||||
createLock().asBuilder().setUnlockRequestTimestamp(fakeClock.nowUtc()).build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
||||
assertThat(reloadDomain().getStatusValues()).containsNoneIn(REGISTRY_LOCK_STATUSES);
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_UPDATE);
|
||||
assertThat(historyEntry.getRequestedByRegistrar()).isTrue();
|
||||
assertThat(historyEntry.getBySuperuser()).isFalse();
|
||||
assertThat(historyEntry.getReason())
|
||||
.isEqualTo("Lock or unlock of a domain through a RegistryLock operation");
|
||||
assertBillingEvent(historyEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_adminLock_createsOnlyHistoryEntry() {
|
||||
action.authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, true));
|
||||
RegistryLockDao.save(createLock().asBuilder().isSuperuser(true).build());
|
||||
|
||||
action.run();
|
||||
HistoryEntry historyEntry = getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_UPDATE);
|
||||
assertThat(historyEntry.getRequestedByRegistrar()).isFalse();
|
||||
assertThat(historyEntry.getBySuperuser()).isTrue();
|
||||
DatastoreHelper.assertNoBillingEvents();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_badVerificationCode() {
|
||||
RegistryLockDao.save(
|
||||
createLock().asBuilder().setVerificationCode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Invalid verification code");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyVerified() {
|
||||
RegistryLockDao.save(
|
||||
createLock().asBuilder().setLockCompletionTimestamp(fakeClock.nowUtc()).build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_expired() {
|
||||
RegistryLockDao.save(createLock());
|
||||
fakeClock.advanceBy(Duration.standardHours(2));
|
||||
action.run();
|
||||
assertThat(response.getPayload())
|
||||
.contains("Failed: The pending lock has expired; please try again");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_nonAdmin_verifyingAdminLock() {
|
||||
RegistryLockDao.save(createLock().asBuilder().isSuperuser(true).build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Non-admin user cannot complete admin lock");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyUnlocked() {
|
||||
action = createAction(lockId, false);
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
||||
.setUnlockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_alreadyLocked() {
|
||||
RegistryLockDao.save(createLock());
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_notLoggedIn() {
|
||||
action.authResult = AuthResult.NOT_AUTHENTICATED;
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_MOVED_TEMPORARILY);
|
||||
assertThat(response.getHeaders()).containsKey("Location");
|
||||
assertNoDomainChanges();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_doesNotChangeLockObject() {
|
||||
// A failure when performing Datastore actions means that no actions should be taken in the
|
||||
// Cloud SQL RegistryLock object
|
||||
RegistryLock lock = createLock();
|
||||
RegistryLockDao.save(lock);
|
||||
// reload the lock to pick up creation time
|
||||
lock = RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
||||
fakeClock.advanceOneMilli();
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action.run();
|
||||
// we would have failed during the Datastore segment of the action
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
|
||||
// verify that the changes to the SQL object were rolled back
|
||||
RegistryLock afterAction =
|
||||
RegistryLockDao.getByVerificationCode(lock.getVerificationCode()).get();
|
||||
assertThat(afterAction).isEqualTo(lock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_isLockTrue_shouldBeFalse() {
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
RegistryLockDao.save(
|
||||
createLock()
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(fakeClock.nowUtc())
|
||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
||||
.build());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_isLockFalse_shouldBeTrue() {
|
||||
action = createAction(lockId, false);
|
||||
RegistryLockDao.save(createLock());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_lock_unlock_lockAgain() {
|
||||
RegistryLock lock = RegistryLockDao.save(createLock());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Success: lock has been applied to example.tld");
|
||||
String unlockVerificationCode = "some-unlock-code";
|
||||
RegistryLockDao.save(
|
||||
lock.asBuilder()
|
||||
.setVerificationCode(unlockVerificationCode)
|
||||
.setUnlockRequestTimestamp(fakeClock.nowUtc())
|
||||
.build());
|
||||
action = createAction(unlockVerificationCode, false);
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
||||
action = createAction(lockId, true);
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Invalid verification code");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_lock_lockAgain() {
|
||||
RegistryLockDao.save(createLock());
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Success: lock has been applied to example.tld");
|
||||
action = createAction(lockId, true);
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already locked");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_unlock_unlockAgain() {
|
||||
action = createAction(lockId, false);
|
||||
domain = persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
RegistryLockDao.save(
|
||||
createLock().asBuilder().setUnlockRequestTimestamp(fakeClock.nowUtc()).build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload()).contains("Success: unlock has been applied to example.tld");
|
||||
action = createAction(lockId, false);
|
||||
action.run();
|
||||
assertThat(response.getPayload()).contains("Failed: Domain example.tld is already unlocked");
|
||||
}
|
||||
|
||||
private RegistryLock createLock() {
|
||||
return new RegistryLock.Builder()
|
||||
.setDomainName("example.tld")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setRepoId("repoId")
|
||||
.setRegistrarPocId("marla.singer@example.com")
|
||||
.isSuperuser(false)
|
||||
.setVerificationCode(lockId)
|
||||
.build();
|
||||
}
|
||||
|
||||
private DomainBase reloadDomain() {
|
||||
return ofy().load().entity(domain).now();
|
||||
}
|
||||
|
||||
private void assertNoDomainChanges() {
|
||||
assertThat(reloadDomain()).isEqualTo(domain);
|
||||
}
|
||||
|
||||
private void assertBillingEvent(HistoryEntry historyEntry) {
|
||||
DatastoreHelper.assertBillingEvents(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId(domain.getForeignKey())
|
||||
.setClientId(domain.getCurrentSponsorClientId())
|
||||
.setCost(Registry.get(domain.getTld()).getServerStatusChangeCost())
|
||||
.setEventTime(fakeClock.nowUtc())
|
||||
.setBillingTime(fakeClock.nowUtc())
|
||||
.setParent(historyEntry)
|
||||
.build());
|
||||
}
|
||||
|
||||
private RegistryLockVerifyAction createAction(String lockVerificationCode, Boolean isLock) {
|
||||
response = new FakeResponse();
|
||||
RegistryLockVerifyAction action =
|
||||
new RegistryLockVerifyAction(
|
||||
fakeClock, new DomainLockUtils(stringGenerator), lockVerificationCode, isLock);
|
||||
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
|
||||
action.req = request;
|
||||
action.response = response;
|
||||
action.authResult = authResult;
|
||||
action.userService = userService;
|
||||
action.logoFilename = "logo.png";
|
||||
action.productName = "Nomulus";
|
||||
action.analyticsConfig = ImmutableMap.of("googleAnalyticsId", "sampleId");
|
||||
action.xsrfTokenManager = new XsrfTokenManager(new FakeClock(), action.userService);
|
||||
return action;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,9 @@ import static google.registry.server.Fixture.BASIC;
|
||||
import static google.registry.server.Route.route;
|
||||
import static google.registry.testing.AppEngineRule.makeRegistrar2;
|
||||
import static google.registry.testing.AppEngineRule.makeRegistrarContact2;
|
||||
import static google.registry.testing.DatastoreHelper.createTld;
|
||||
import static google.registry.testing.DatastoreHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatastoreHelper.newDomainBase;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
@@ -26,7 +28,9 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.googlecode.objectify.ObjectifyFilter;
|
||||
import google.registry.model.ofy.OfyFilter;
|
||||
import google.registry.model.registrar.Registrar.State;
|
||||
import google.registry.model.registry.RegistryLockDao;
|
||||
import google.registry.module.frontend.FrontendServlet;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.server.RegistryTestServer;
|
||||
import google.registry.testing.CertificateSamples;
|
||||
import org.junit.Rule;
|
||||
@@ -46,7 +50,8 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||
.setRoutes(
|
||||
route("/registrar", FrontendServlet.class),
|
||||
route("/registrar-ote-status", FrontendServlet.class),
|
||||
route("/registrar-settings", FrontendServlet.class))
|
||||
route("/registrar-settings", FrontendServlet.class),
|
||||
route("/registry-lock-verify", FrontendServlet.class))
|
||||
.setFilters(ObjectifyFilter.class, OfyFilter.class)
|
||||
.setFixtures(BASIC)
|
||||
.setEmail("Marla.Singer@google.com")
|
||||
@@ -370,4 +375,36 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||
Thread.sleep(500);
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registryLockVerify_success() throws Throwable {
|
||||
String lockVerificationCode = "f1be78a2-2d61-458c-80f0-9dd8f2f8625f";
|
||||
server.runInAppEngineEnvironment(
|
||||
() -> {
|
||||
createTld("tld");
|
||||
persistResource(newDomainBase("example.tld"));
|
||||
RegistryLockDao.save(
|
||||
new RegistryLock.Builder()
|
||||
.setRegistrarPocId("johndoe@theregistrar.com")
|
||||
.setRepoId("repoId")
|
||||
.setRegistrarId("TheRegistrar")
|
||||
.setVerificationCode("f1be78a2-2d61-458c-80f0-9dd8f2f8625f")
|
||||
.isSuperuser(false)
|
||||
.setDomainName("example.tld")
|
||||
.build());
|
||||
return null;
|
||||
});
|
||||
driver.get(
|
||||
server.getUrl(
|
||||
"/registry-lock-verify?isLock=true&lockVerificationCode=" + lockVerificationCode));
|
||||
driver.waitForElement(By.id("reg-content"));
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registryLockVerify_unknownLock() throws Throwable {
|
||||
driver.get(server.getUrl("/registry-lock-verify?isLock=true&lockVerificationCode=asdfasdf"));
|
||||
driver.waitForElement(By.id("reg-content"));
|
||||
driver.diffPage("page");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,3 +6,5 @@ PATH CLASS METHODS OK AUTH_METHODS
|
||||
/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC
|
||||
/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC
|
||||
/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC
|
||||
/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC
|
||||
/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY USER PUBLIC
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,65 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
create table "Registrar" (
|
||||
client_id text not null,
|
||||
allowed_tlds text[],
|
||||
billing_account_map hstore,
|
||||
billing_identifier int8,
|
||||
block_premium_names boolean not null,
|
||||
client_certificate text,
|
||||
client_certificate_hash text,
|
||||
contacts_require_syncing boolean not null,
|
||||
creation_time timestamptz,
|
||||
drive_folder_id text,
|
||||
email_address text,
|
||||
failover_client_certificate text,
|
||||
failover_client_certificate_hash text,
|
||||
fax_number text,
|
||||
iana_identifier int8,
|
||||
icann_referral_email text,
|
||||
i18n_address_city text,
|
||||
i18n_address_country_code text,
|
||||
i18n_address_state text,
|
||||
i18n_address_street_line1 text,
|
||||
i18n_address_street_line2 text,
|
||||
i18n_address_street_line3 text,
|
||||
i18n_address_zip text,
|
||||
ip_address_whitelist text[],
|
||||
last_certificate_update_time timestamptz,
|
||||
last_update_time timestamptz,
|
||||
localized_address_city text,
|
||||
localized_address_country_code text,
|
||||
localized_address_state text,
|
||||
localized_address_street_line1 text,
|
||||
localized_address_street_line2 text,
|
||||
localized_address_street_line3 text,
|
||||
localized_address_zip text,
|
||||
password_hash text,
|
||||
phone_number text,
|
||||
phone_passcode text,
|
||||
po_number text,
|
||||
rdap_base_urls text[],
|
||||
registrar_name text not null,
|
||||
registry_lock_allowed boolean not null,
|
||||
password_salt text,
|
||||
state text,
|
||||
type text not null,
|
||||
url text,
|
||||
whois_server text,
|
||||
primary key (client_id)
|
||||
);
|
||||
|
||||
create index registrar_name_idx on "Registrar" (registrar_name);
|
||||
create index registrar_iana_identifier_idx on "Registrar" (iana_identifier);
|
||||
@@ -0,0 +1,31 @@
|
||||
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
create table "RegistrarPoc" (
|
||||
email_address text not null,
|
||||
allowed_to_set_registry_lock_password boolean not null,
|
||||
fax_number text,
|
||||
gae_user_id text,
|
||||
name text,
|
||||
phone_number text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
types text[],
|
||||
visible_in_domain_whois_as_abuse boolean not null,
|
||||
visible_in_whois_as_admin boolean not null,
|
||||
visible_in_whois_as_tech boolean not null,
|
||||
primary key (email_address)
|
||||
);
|
||||
|
||||
create index registrarpoc_gae_user_id_idx on "RegistrarPoc" (gae_user_id);
|
||||
@@ -93,6 +93,71 @@
|
||||
primary key (revision_id)
|
||||
);
|
||||
|
||||
create table "Registrar" (
|
||||
client_id text not null,
|
||||
allowed_tlds text[],
|
||||
billing_account_map hstore,
|
||||
billing_identifier int8,
|
||||
block_premium_names boolean not null,
|
||||
client_certificate text,
|
||||
client_certificate_hash text,
|
||||
contacts_require_syncing boolean not null,
|
||||
creation_time timestamptz,
|
||||
drive_folder_id text,
|
||||
email_address text,
|
||||
failover_client_certificate text,
|
||||
failover_client_certificate_hash text,
|
||||
fax_number text,
|
||||
iana_identifier int8,
|
||||
icann_referral_email text,
|
||||
i18n_address_city text,
|
||||
i18n_address_country_code text,
|
||||
i18n_address_state text,
|
||||
i18n_address_street_line1 text,
|
||||
i18n_address_street_line2 text,
|
||||
i18n_address_street_line3 text,
|
||||
i18n_address_zip text,
|
||||
ip_address_whitelist text[],
|
||||
last_certificate_update_time timestamptz,
|
||||
last_update_time timestamptz,
|
||||
localized_address_city text,
|
||||
localized_address_country_code text,
|
||||
localized_address_state text,
|
||||
localized_address_street_line1 text,
|
||||
localized_address_street_line2 text,
|
||||
localized_address_street_line3 text,
|
||||
localized_address_zip text,
|
||||
password_hash text,
|
||||
phone_number text,
|
||||
phone_passcode text,
|
||||
po_number text,
|
||||
rdap_base_urls text[],
|
||||
registrar_name text not null,
|
||||
registry_lock_allowed boolean not null,
|
||||
password_salt text,
|
||||
state text,
|
||||
type text not null,
|
||||
url text,
|
||||
whois_server text,
|
||||
primary key (client_id)
|
||||
);
|
||||
|
||||
create table "RegistrarPoc" (
|
||||
email_address text not null,
|
||||
allowed_to_set_registry_lock_password boolean not null,
|
||||
fax_number text,
|
||||
gae_user_id text,
|
||||
name text,
|
||||
phone_number text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
types text[],
|
||||
visible_in_domain_whois_as_abuse boolean not null,
|
||||
visible_in_whois_as_admin boolean not null,
|
||||
visible_in_whois_as_tech boolean not null,
|
||||
primary key (email_address)
|
||||
);
|
||||
|
||||
create table "RegistryLock" (
|
||||
revision_id bigserial not null,
|
||||
domain_name text not null,
|
||||
@@ -130,6 +195,9 @@ create index IDX5mnf0wn20tno4b9do88j61klr on "Domain" (deletion_time);
|
||||
create index IDX1rcgkdd777bpvj0r94sltwd5y on "Domain" (fully_qualified_domain_name);
|
||||
create index IDXrwl38wwkli1j7gkvtywi9jokq on "Domain" (tld);
|
||||
create index premiumlist_name_idx on "PremiumList" (name);
|
||||
create index registrar_name_idx on "Registrar" (registrar_name);
|
||||
create index registrar_iana_identifier_idx on "Registrar" (iana_identifier);
|
||||
create index registrarpoc_gae_user_id_idx on "RegistrarPoc" (gae_user_id);
|
||||
create index idx_registry_lock_verification_code on "RegistryLock" (verification_code);
|
||||
create index idx_registry_lock_registrar_id on "RegistryLock" (registrar_id);
|
||||
|
||||
|
||||
@@ -159,6 +159,79 @@ CREATE SEQUENCE public."PremiumList_revision_id_seq"
|
||||
ALTER SEQUENCE public."PremiumList_revision_id_seq" OWNED BY public."PremiumList".revision_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: Registrar; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."Registrar" (
|
||||
client_id text NOT NULL,
|
||||
allowed_tlds text[],
|
||||
billing_account_map public.hstore,
|
||||
billing_identifier bigint,
|
||||
block_premium_names boolean NOT NULL,
|
||||
client_certificate text,
|
||||
client_certificate_hash text,
|
||||
contacts_require_syncing boolean NOT NULL,
|
||||
creation_time timestamp with time zone,
|
||||
drive_folder_id text,
|
||||
email_address text,
|
||||
failover_client_certificate text,
|
||||
failover_client_certificate_hash text,
|
||||
fax_number text,
|
||||
iana_identifier bigint,
|
||||
icann_referral_email text,
|
||||
i18n_address_city text,
|
||||
i18n_address_country_code text,
|
||||
i18n_address_state text,
|
||||
i18n_address_street_line1 text,
|
||||
i18n_address_street_line2 text,
|
||||
i18n_address_street_line3 text,
|
||||
i18n_address_zip text,
|
||||
ip_address_whitelist text[],
|
||||
last_certificate_update_time timestamp with time zone,
|
||||
last_update_time timestamp with time zone,
|
||||
localized_address_city text,
|
||||
localized_address_country_code text,
|
||||
localized_address_state text,
|
||||
localized_address_street_line1 text,
|
||||
localized_address_street_line2 text,
|
||||
localized_address_street_line3 text,
|
||||
localized_address_zip text,
|
||||
password_hash text,
|
||||
phone_number text,
|
||||
phone_passcode text,
|
||||
po_number text,
|
||||
rdap_base_urls text[],
|
||||
registrar_name text NOT NULL,
|
||||
registry_lock_allowed boolean NOT NULL,
|
||||
password_salt text,
|
||||
state text,
|
||||
type text NOT NULL,
|
||||
url text,
|
||||
whois_server text
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: RegistrarPoc; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."RegistrarPoc" (
|
||||
email_address text NOT NULL,
|
||||
allowed_to_set_registry_lock_password boolean NOT NULL,
|
||||
fax_number text,
|
||||
gae_user_id text,
|
||||
name text,
|
||||
phone_number text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
types text[],
|
||||
visible_in_domain_whois_as_abuse boolean NOT NULL,
|
||||
visible_in_whois_as_admin boolean NOT NULL,
|
||||
visible_in_whois_as_tech boolean NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: RegistryLock; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -317,6 +390,22 @@ ALTER TABLE ONLY public."PremiumList"
|
||||
ADD CONSTRAINT "PremiumList_pkey" PRIMARY KEY (revision_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: RegistrarPoc RegistrarPoc_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."RegistrarPoc"
|
||||
ADD CONSTRAINT "RegistrarPoc_pkey" PRIMARY KEY (email_address);
|
||||
|
||||
|
||||
--
|
||||
-- Name: Registrar Registrar_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."Registrar"
|
||||
ADD CONSTRAINT "Registrar_pkey" PRIMARY KEY (client_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: RegistryLock RegistryLock_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -405,6 +494,27 @@ CREATE INDEX idxrwl38wwkli1j7gkvtywi9jokq ON public."Domain" USING btree (tld);
|
||||
CREATE INDEX premiumlist_name_idx ON public."PremiumList" USING btree (name);
|
||||
|
||||
|
||||
--
|
||||
-- Name: registrar_iana_identifier_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX registrar_iana_identifier_idx ON public."Registrar" USING btree (iana_identifier);
|
||||
|
||||
|
||||
--
|
||||
-- Name: registrar_name_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX registrar_name_idx ON public."Registrar" USING btree (registrar_name);
|
||||
|
||||
|
||||
--
|
||||
-- Name: registrarpoc_gae_user_id_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX registrarpoc_gae_user_id_idx ON public."RegistrarPoc" USING btree (gae_user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reservedlist_name_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
@@ -115,6 +115,7 @@ spotless {
|
||||
format 'misc', {
|
||||
clearSteps()
|
||||
target '**/*.gradle'
|
||||
targetExclude '**/cloudbuild-caches/**'
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces(2)
|
||||
endWithNewline()
|
||||
|
||||
+5
-5
@@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import dagger.Lazy;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -163,9 +163,9 @@ public final class CertificateSupplierModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
static SelfSignedCertificate provideSelfSignedCertificate() {
|
||||
static SelfSignedCaCertificate provideSelfSignedCertificate() {
|
||||
try {
|
||||
return new SelfSignedCertificate();
|
||||
return SelfSignedCaCertificate.create();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public final class CertificateSupplierModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
@SelfSigned
|
||||
static Supplier<PrivateKey> provideSelfSignedPrivateKeySupplier(SelfSignedCertificate ssc) {
|
||||
static Supplier<PrivateKey> provideSelfSignedPrivateKeySupplier(SelfSignedCaCertificate ssc) {
|
||||
return Suppliers.ofInstance(ssc.key());
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ public final class CertificateSupplierModule {
|
||||
@Provides
|
||||
@SelfSigned
|
||||
static Supplier<ImmutableList<X509Certificate>> provideSelfSignedCertificatesSupplier(
|
||||
SelfSignedCertificate ssc) {
|
||||
SelfSignedCaCertificate ssc) {
|
||||
return Suppliers.ofInstance(ImmutableList.of(ssc.cert()));
|
||||
}
|
||||
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.networking.util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
|
||||
/** A self-signed certificate authority (CA) cert for use in tests. */
|
||||
// TODO(weiminyu): make this class test-only. Requires refactor in proxy and prober.
|
||||
public class SelfSignedCaCertificate {
|
||||
|
||||
private static final String DEFAULT_ISSUER_FQDN = "registry-test";
|
||||
private static final Date DEFAULT_NOT_BEFORE =
|
||||
Date.from(Instant.now().minus(Duration.ofHours(1)));
|
||||
private static final Date DEFAULT_NOT_AFTER = Date.from(Instant.now().plus(Duration.ofDays(1)));
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
|
||||
private static final KeyPairGenerator keyGen = createKeyPairGenerator();
|
||||
|
||||
private final PrivateKey privateKey;
|
||||
private final X509Certificate cert;
|
||||
|
||||
public SelfSignedCaCertificate(PrivateKey privateKey, X509Certificate cert) {
|
||||
this.privateKey = privateKey;
|
||||
this.cert = cert;
|
||||
}
|
||||
|
||||
public PrivateKey key() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public X509Certificate cert() {
|
||||
return cert;
|
||||
}
|
||||
|
||||
public static SelfSignedCaCertificate create() throws Exception {
|
||||
return create(
|
||||
keyGen.generateKeyPair(), DEFAULT_ISSUER_FQDN, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
|
||||
}
|
||||
|
||||
public static SelfSignedCaCertificate create(String fqdn) throws Exception {
|
||||
return create(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
|
||||
}
|
||||
|
||||
public static SelfSignedCaCertificate create(String fqdn, Date from, Date to) throws Exception {
|
||||
return create(keyGen.generateKeyPair(), fqdn, from, to);
|
||||
}
|
||||
|
||||
public static SelfSignedCaCertificate create(KeyPair keyPair, String fqdn, Date from, Date to)
|
||||
throws Exception {
|
||||
return new SelfSignedCaCertificate(keyPair.getPrivate(), createCaCert(keyPair, fqdn, from, to));
|
||||
}
|
||||
|
||||
static KeyPairGenerator createKeyPairGenerator() {
|
||||
try {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", PROVIDER);
|
||||
keyGen.initialize(2048, new SecureRandom());
|
||||
return keyGen;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a self-signed Certificate Authority (CA) certificate. */
|
||||
static X509Certificate createCaCert(KeyPair keyPair, String fqdn, Date from, Date to)
|
||||
throws Exception {
|
||||
X500Name owner = new X500Name("CN=" + fqdn);
|
||||
ContentSigner signer =
|
||||
new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(keyPair.getPrivate());
|
||||
X509v3CertificateBuilder builder =
|
||||
new JcaX509v3CertificateBuilder(
|
||||
owner, new BigInteger(64, RANDOM), from, to, owner, keyPair.getPublic());
|
||||
|
||||
// Mark cert as CA by adding basicConstraint with cA=true to the builder
|
||||
BasicConstraints basicConstraints = new BasicConstraints(true);
|
||||
builder.addExtension(new ASN1ObjectIdentifier("2.5.29.19"), true, basicConstraints);
|
||||
|
||||
X509CertificateHolder certHolder = builder.build(signer);
|
||||
return new JcaX509CertificateConverter().setProvider(PROVIDER).getCertificate(certHolder);
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -21,6 +21,7 @@ import static google.registry.networking.handler.SslInitializerTestUtils.signKey
|
||||
import static google.registry.networking.handler.SslInitializerTestUtils.verifySslExcpetion;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
@@ -35,7 +36,6 @@ import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.CertPathBuilderException;
|
||||
@@ -153,7 +153,7 @@ public class SslClientInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_defaultTrustManager_rejectSelfSignedCert() throws Exception {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress =
|
||||
new LocalAddress("DEFAULT_TRUST_MANAGER_REJECT_SELF_SIGNED_CERT_" + sslProvider);
|
||||
nettyRule.setUpServer(localAddress, getServerHandler(false, ssc.key(), ssc.cert()));
|
||||
@@ -177,7 +177,7 @@ public class SslClientInitializerTest {
|
||||
KeyPair keyPair = getKeyPair();
|
||||
|
||||
// Generate a self signed certificate, and use it to sign the key pair.
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||
X509Certificate cert = signKeyPair(ssc, keyPair, SSL_HOST);
|
||||
|
||||
// Set up the server to use the signed cert and private key to perform handshake;
|
||||
@@ -206,7 +206,7 @@ public class SslClientInitializerTest {
|
||||
KeyPair keyPair = getKeyPair();
|
||||
|
||||
// Generate a self signed certificate, and use it to sign the key pair.
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||
X509Certificate cert =
|
||||
signKeyPair(
|
||||
ssc,
|
||||
@@ -240,7 +240,7 @@ public class SslClientInitializerTest {
|
||||
KeyPair keyPair = getKeyPair();
|
||||
|
||||
// Generate a self signed certificate, and use it to sign the key pair.
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||
X509Certificate cert =
|
||||
signKeyPair(
|
||||
ssc,
|
||||
@@ -272,8 +272,8 @@ public class SslClientInitializerTest {
|
||||
new LocalAddress(
|
||||
"CUSTOM_TRUST_MANAGER_ACCEPT_SELF_SIGNED_CERT_CLIENT_CERT_REQUIRED_" + sslProvider);
|
||||
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCertificate clientSsc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
|
||||
|
||||
// Set up the server to require client certificate.
|
||||
nettyRule.setUpServer(localAddress, getServerHandler(true, serverSsc.key(), serverSsc.cert()));
|
||||
@@ -311,7 +311,7 @@ public class SslClientInitializerTest {
|
||||
KeyPair keyPair = getKeyPair();
|
||||
|
||||
// Generate a self signed certificate, and use it to sign the key pair.
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create();
|
||||
X509Certificate cert = signKeyPair(ssc, keyPair, "wrong.com");
|
||||
|
||||
// Set up the server to use the signed cert and private key to perform handshake;
|
||||
|
||||
+24
-28
@@ -18,15 +18,14 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -34,17 +33,13 @@ import java.util.Date;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
|
||||
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
|
||||
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
|
||||
/**
|
||||
* Utility class that provides methods used by {@link SslClientInitializerTest} and {@link
|
||||
@@ -52,16 +47,23 @@ import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
|
||||
*/
|
||||
public final class SslInitializerTestUtils {
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
private static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
|
||||
private static final KeyPairGenerator KEY_PAIR_GENERATOR = getKeyPairGenerator();
|
||||
|
||||
private SslInitializerTestUtils() {}
|
||||
|
||||
private static KeyPairGenerator getKeyPairGenerator() {
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", PROVIDER);
|
||||
keyPairGenerator.initialize(2048, new SecureRandom());
|
||||
return keyPairGenerator;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static KeyPair getKeyPair() throws Exception {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
|
||||
keyPairGenerator.initialize(2048, new SecureRandom());
|
||||
return keyPairGenerator.generateKeyPair();
|
||||
return KEY_PAIR_GENERATOR.generateKeyPair();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,26 +73,20 @@ public final class SslInitializerTestUtils {
|
||||
* @return signed public key (of the key pair) certificate
|
||||
*/
|
||||
public static X509Certificate signKeyPair(
|
||||
SelfSignedCertificate ssc, KeyPair keyPair, String hostname, Date from, Date to)
|
||||
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname, Date from, Date to)
|
||||
throws Exception {
|
||||
X500Name subjectDnName = new X500Name("CN=" + hostname);
|
||||
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
||||
X500Name issuerDnName = new X500Name(ssc.cert().getIssuerDN().getName());
|
||||
SubjectPublicKeyInfo subPubKeyInfo =
|
||||
SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
|
||||
AlgorithmIdentifier sigAlgId =
|
||||
new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSAEncryption");
|
||||
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
|
||||
|
||||
ContentSigner sigGen =
|
||||
new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
|
||||
.build(PrivateKeyFactory.createKey(ssc.key().getEncoded()));
|
||||
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(ssc.key());
|
||||
X509v3CertificateBuilder v3CertGen =
|
||||
new X509v3CertificateBuilder(
|
||||
issuerDnName, serialNumber, from, to, subjectDnName, subPubKeyInfo);
|
||||
new JcaX509v3CertificateBuilder(
|
||||
issuerDnName, serialNumber, from, to, subjectDnName, keyPair.getPublic());
|
||||
|
||||
X509CertificateHolder certificateHolder = v3CertGen.build(sigGen);
|
||||
return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder);
|
||||
return new JcaX509CertificateConverter()
|
||||
.setProvider(PROVIDER)
|
||||
.getCertificate(certificateHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,7 +96,7 @@ public final class SslInitializerTestUtils {
|
||||
* @return signed public key (of the key pair) certificate
|
||||
*/
|
||||
public static X509Certificate signKeyPair(
|
||||
SelfSignedCertificate ssc, KeyPair keyPair, String hostname) throws Exception {
|
||||
SelfSignedCaCertificate ssc, KeyPair keyPair, String hostname) throws Exception {
|
||||
return signKeyPair(
|
||||
ssc,
|
||||
keyPair,
|
||||
|
||||
+16
-16
@@ -23,6 +23,7 @@ import static google.registry.networking.handler.SslServerInitializer.CLIENT_CER
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
@@ -33,7 +34,6 @@ import io.netty.handler.ssl.OpenSsl;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.CertificateException;
|
||||
@@ -127,7 +127,7 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testSuccess_swappedInitializerWithSslHandler() throws Exception {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate ssc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
SslServerInitializer<EmbeddedChannel> sslServerInitializer =
|
||||
new SslServerInitializer<>(
|
||||
true,
|
||||
@@ -147,12 +147,12 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testSuccess_trustAnyClientCert() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("TRUST_ANY_CLIENT_CERT_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
localAddress, getServerHandler(true, false, serverSsc.key(), serverSsc.cert()));
|
||||
SelfSignedCertificate clientSsc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
|
||||
nettyRule.setUpClient(
|
||||
localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
||||
|
||||
@@ -168,13 +168,13 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_clientCertExpired() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
localAddress, getServerHandler(true, true, serverSsc.key(), serverSsc.cert()));
|
||||
SelfSignedCertificate clientSsc =
|
||||
new SelfSignedCertificate(
|
||||
SelfSignedCaCertificate clientSsc =
|
||||
SelfSignedCaCertificate.create(
|
||||
"CLIENT",
|
||||
Date.from(Instant.now().minus(Duration.ofDays(2))),
|
||||
Date.from(Instant.now().minus(Duration.ofDays(1))));
|
||||
@@ -189,13 +189,13 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_clientCertNotYetValid() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("CLIENT_CERT_EXPIRED_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
localAddress, getServerHandler(true, true, serverSsc.key(), serverSsc.cert()));
|
||||
SelfSignedCertificate clientSsc =
|
||||
new SelfSignedCertificate(
|
||||
SelfSignedCaCertificate clientSsc =
|
||||
SelfSignedCaCertificate.create(
|
||||
"CLIENT",
|
||||
Date.from(Instant.now().plus(Duration.ofDays(1))),
|
||||
Date.from(Instant.now().plus(Duration.ofDays(2))));
|
||||
@@ -210,7 +210,7 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testSuccess_doesNotRequireClientCert() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("DOES_NOT_REQUIRE_CLIENT_CERT_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
@@ -230,7 +230,7 @@ public class SslServerInitializerTest {
|
||||
@Test
|
||||
public void testSuccess_CertSignedByOtherCA() throws Exception {
|
||||
// The self-signed cert of the CA.
|
||||
SelfSignedCertificate caSsc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate caSsc = SelfSignedCaCertificate.create();
|
||||
KeyPair keyPair = getKeyPair();
|
||||
X509Certificate serverCert = signKeyPair(caSsc, keyPair, SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("CERT_SIGNED_BY_OTHER_CA_" + sslProvider);
|
||||
@@ -244,7 +244,7 @@ public class SslServerInitializerTest {
|
||||
// Serving both the server cert, and the CA cert
|
||||
serverCert,
|
||||
caSsc.cert()));
|
||||
SelfSignedCertificate clientSsc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
|
||||
nettyRule.setUpClient(
|
||||
localAddress,
|
||||
getClientHandler(
|
||||
@@ -263,7 +263,7 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_requireClientCertificate() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate(SSL_HOST);
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create(SSL_HOST);
|
||||
LocalAddress localAddress = new LocalAddress("REQUIRE_CLIENT_CERT_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
@@ -285,12 +285,12 @@ public class SslServerInitializerTest {
|
||||
|
||||
@Test
|
||||
public void testFailure_wrongHostnameInCertificate() throws Exception {
|
||||
SelfSignedCertificate serverSsc = new SelfSignedCertificate("wrong.com");
|
||||
SelfSignedCaCertificate serverSsc = SelfSignedCaCertificate.create("wrong.com");
|
||||
LocalAddress localAddress = new LocalAddress("WRONG_HOSTNAME_" + sslProvider);
|
||||
|
||||
nettyRule.setUpServer(
|
||||
localAddress, getServerHandler(true, false, serverSsc.key(), serverSsc.cert()));
|
||||
SelfSignedCertificate clientSsc = new SelfSignedCertificate();
|
||||
SelfSignedCaCertificate clientSsc = SelfSignedCaCertificate.create();
|
||||
nettyRule.setUpClient(
|
||||
localAddress, getClientHandler(serverSsc.cert(), clientSsc.key(), clientSsc.cert()));
|
||||
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import dagger.Component;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.networking.module.CertificateSupplierModule.Mode;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.security.KeyPair;
|
||||
@@ -47,7 +47,7 @@ import org.junit.runners.JUnit4;
|
||||
@RunWith(JUnit4.class)
|
||||
public class CertificateSupplierModuleTest {
|
||||
|
||||
private SelfSignedCertificate ssc;
|
||||
private SelfSignedCaCertificate ssc;
|
||||
private PrivateKey key;
|
||||
private Certificate cert;
|
||||
private TestComponent component;
|
||||
@@ -62,7 +62,7 @@ public class CertificateSupplierModuleTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ssc = new SelfSignedCertificate();
|
||||
ssc = SelfSignedCaCertificate.create();
|
||||
KeyPair keyPair = getKeyPair();
|
||||
key = keyPair.getPrivate();
|
||||
cert = signKeyPair(ssc, keyPair, "example.tld");
|
||||
|
||||
@@ -23,6 +23,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
||||
import google.registry.testing.FakeClock;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -34,7 +35,6 @@ import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.cookie.Cookie;
|
||||
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import io.netty.util.concurrent.Promise;
|
||||
import java.security.cert.X509Certificate;
|
||||
import org.junit.Before;
|
||||
@@ -123,7 +123,7 @@ public class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
testComponent = makeTestComponent(new FakeClock());
|
||||
certificate = new SelfSignedCertificate().cert();
|
||||
certificate = SelfSignedCaCertificate.create().cert();
|
||||
initializeChannel(
|
||||
ch -> {
|
||||
ch.attr(REMOTE_ADDRESS_KEY).set(CLIENT_ADDRESS);
|
||||
|
||||
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import google.registry.networking.util.SelfSignedCaCertificate;
|
||||
import google.registry.proxy.TestUtils;
|
||||
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
||||
import google.registry.proxy.metric.FrontendMetrics;
|
||||
@@ -41,7 +42,6 @@ import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.cookie.Cookie;
|
||||
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import io.netty.util.concurrent.Promise;
|
||||
import java.security.cert.X509Certificate;
|
||||
import org.junit.Before;
|
||||
@@ -114,7 +114,7 @@ public class EppServiceHandlerTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
clientCertificate = new SelfSignedCertificate().cert();
|
||||
clientCertificate = SelfSignedCaCertificate.create().cert();
|
||||
channel = setUpNewChannel(eppServiceHandler);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public class EppServiceHandlerTest {
|
||||
HELLO.getBytes(UTF_8),
|
||||
metrics);
|
||||
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
|
||||
X509Certificate clientCertificate2 = new SelfSignedCertificate().cert();
|
||||
X509Certificate clientCertificate2 = SelfSignedCaCertificate.create().cert();
|
||||
setHandshakeSuccess(channel2, clientCertificate2);
|
||||
String certHash2 = getCertificateHash(clientCertificate2);
|
||||
|
||||
|
||||
@@ -29,6 +29,14 @@ environment="$1"
|
||||
dest="$2"
|
||||
gcs_prefix="storage.googleapis.com/domain-registry-maven-repository"
|
||||
|
||||
# Let Gradle put its caches (dependency cache and build cache) in the source
|
||||
# tree. This allows sharing of the caches between steps in a Cloud Build
|
||||
# task. (See ./cloudbuild-nomulus.yaml, which calls this script in several
|
||||
# steps). If left at their default location, the caches will be lost after
|
||||
# each step.
|
||||
# Note: must be consistent with value in ./cloudbuild-nomulus.yaml
|
||||
export GRADLE_USER_HOME="./cloudbuild-caches"
|
||||
|
||||
if [ "${environment}" == tool ]
|
||||
then
|
||||
mkdir -p "${dest}"
|
||||
|
||||
@@ -12,16 +12,23 @@
|
||||
#
|
||||
# To trigger a build automatically, follow the instructions below and add a trigger:
|
||||
# https://cloud.google.com/cloud-build/docs/running-builds/automate-builds
|
||||
#
|
||||
# Note: to work around issue in Spinnaker's 'Deployment Manifest' stage,
|
||||
# variable references must avoid the ${var} format. Valid formats include
|
||||
# $var or ${"${var}"}. This file use the former. Since TAG_NAME and _ENV are
|
||||
# expanded in the copies sent to Spinnaker, we preserve the brackets around
|
||||
# them for safe pattern matching during release.
|
||||
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
|
||||
steps:
|
||||
# Pull the credential for nomulus tool.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
args:
|
||||
- gsutil
|
||||
- cp
|
||||
- gs://${PROJECT_ID}-deploy/secrets/tool-credential.json.enc
|
||||
- gs://$PROJECT_ID-deploy/secrets/tool-credential.json.enc
|
||||
- .
|
||||
# Decrypt the credential.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
entrypoint: /bin/bash
|
||||
args:
|
||||
- -c
|
||||
@@ -31,7 +38,7 @@ steps:
|
||||
--ciphertext-file=- --plaintext-file=tool-credential.json \
|
||||
--location=global --keyring=nomulus-tool-keyring --key=nomulus-tool-key
|
||||
# Deploy the Spec11 pipeline to GCS.
|
||||
- name: 'gcr.io/${PROJECT_ID}/nomulus-tool:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/nomulus-tool:latest'
|
||||
args:
|
||||
- -e
|
||||
- ${_ENV}
|
||||
@@ -39,7 +46,7 @@ steps:
|
||||
- tool-credential.json
|
||||
- deploy_spec11_pipeline
|
||||
# Deploy the invoicing pipeline to GCS.
|
||||
- name: 'gcr.io/${PROJECT_ID}/nomulus-tool:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/nomulus-tool:latest'
|
||||
args:
|
||||
- -e
|
||||
- ${_ENV}
|
||||
@@ -49,18 +56,18 @@ steps:
|
||||
# Save the deployed tag for the current environment on GCS. Because of b/137891685
|
||||
# which causes the for-loop in the next step to fail, this may not be the last step.
|
||||
# TODO(weiminyu): do this in last step.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
entrypoint: /bin/bash
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo ${TAG_NAME} | \
|
||||
gsutil cp - gs://${PROJECT_ID}-deployed-tags/nomulus.${_ENV}.tag
|
||||
gsutil cp - gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tag
|
||||
# Deploy the GAE config files.
|
||||
# First authorize the gcloud tool to use the credential json file, then
|
||||
# download and unzip the tarball that contains the relevant config files
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
entrypoint: /bin/bash
|
||||
args:
|
||||
- -c
|
||||
@@ -72,13 +79,13 @@ steps:
|
||||
else
|
||||
project_id="domain-registry-${_ENV}"
|
||||
fi
|
||||
gsutil cp gs://${PROJECT_ID}-deploy/${TAG_NAME}/${_ENV}.tar .
|
||||
gsutil cp gs://$PROJECT_ID-deploy/${TAG_NAME}/${_ENV}.tar .
|
||||
tar -xvf ${_ENV}.tar
|
||||
# Note that this currently does not work for google.com projects that
|
||||
# we use due to b/137891685. External projects are likely to work.
|
||||
for filename in cron dispatch dos index queue; do
|
||||
gcloud -q --project ${project_id} app deploy \
|
||||
default/WEB-INF/appengine-generated/${filename}.yaml
|
||||
gcloud -q --project $project_id app deploy \
|
||||
default/WEB-INF/appengine-generated/$filename.yaml
|
||||
done
|
||||
|
||||
timeout: 3600s
|
||||
|
||||
@@ -21,7 +21,15 @@ steps:
|
||||
args: ['mkdir', 'nomulus']
|
||||
# Run tests
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
args: ['./gradlew', 'test', '-PskipDockerIncompatibleTests=true']
|
||||
# Set home for Gradle caches. Must be consistent with last step below
|
||||
# and ./build_nomulus_for_env.sh
|
||||
env: [ 'GRADLE_USER_HOME=./cloudbuild-caches' ]
|
||||
args: ['./gradlew',
|
||||
'test',
|
||||
'-PskipDockerIncompatibleTests=true',
|
||||
'-PmavenUrl=https://storage.googleapis.com/domain-registry-maven-repository/maven',
|
||||
'-PpluginsUrl=https://storage.googleapis.com/domain-registry-maven-repository/plugins'
|
||||
]
|
||||
# Build the tool binary and image.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
args: ['release/build_nomulus_for_env.sh', 'tool', 'output']
|
||||
@@ -70,6 +78,9 @@ steps:
|
||||
# server/schema compatibility tests.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
entrypoint: /bin/bash
|
||||
# Set home for Gradle caches. Must be consistent with second step above
|
||||
# and ./build_nomulus_for_env.sh
|
||||
env: [ 'GRADLE_USER_HOME=./cloudbuild-caches' ]
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
|
||||
@@ -15,14 +15,22 @@
|
||||
#
|
||||
# Note that the release process hardens the tags and variables in this file:
|
||||
# - The 'latest' tag on docker images will be replaced by their image digests.
|
||||
# - The ${TAG_NAME} pattern will be replaced by the acutal release tag.
|
||||
# - The ${TAG_NAME} pattern will be replaced by the actual release tag.
|
||||
# - The ${_ENV} pattern will be replaced by the actual environment name.
|
||||
# Please refer to ./cloudbuild-release.yaml for more details.
|
||||
|
||||
# Note 2: to work around issue in Spinnaker's 'Deployment Manifest' stage,
|
||||
# variable references must avoid the ${var} format. Valid formats include
|
||||
# $var or ${"${var}"}. This file use the former. Since TAG_NAME and _ENV are
|
||||
# expanded in the copies sent to Spinnaker, we preserve the brackets around
|
||||
# them for safe pattern matching during release.
|
||||
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
|
||||
steps:
|
||||
# Download and decrypt the nomulus tool credential, which has the privilege to
|
||||
# start Cloud SQL proxy to all environments.
|
||||
# Also download and decrypt the admin_credential file, which has the cloud
|
||||
# instance name and database login name and password.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
volumes:
|
||||
- name: 'secrets'
|
||||
path: '/secrets'
|
||||
@@ -31,13 +39,13 @@ steps:
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
gsutil cp gs://${PROJECT_ID}-deploy/secrets/tool-credential.json.enc - \
|
||||
gsutil cp gs://$PROJECT_ID-deploy/secrets/tool-credential.json.enc - \
|
||||
| base64 -d \
|
||||
| gcloud kms decrypt \
|
||||
--ciphertext-file=- \
|
||||
--plaintext-file=/secrets/cloud_sql_credential.json \
|
||||
--location=global --keyring=nomulus-tool-keyring --key=nomulus-tool-key
|
||||
gsutil cp gs://${PROJECT_ID}-deploy/cloudsql-credentials/${_ENV}/admin_credential.enc - \
|
||||
gsutil cp gs://$PROJECT_ID-deploy/cloudsql-credentials/${_ENV}/admin_credential.enc - \
|
||||
| base64 -d \
|
||||
| gcloud kms decrypt \
|
||||
--ciphertext-file=- \
|
||||
@@ -45,7 +53,7 @@ steps:
|
||||
--location global --keyring=nomulus-tool-keyring \
|
||||
--key=nomulus-tool-key
|
||||
# Download the schema jar to be deployed.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
volumes:
|
||||
- name: 'flyway'
|
||||
path: '/flyway/jars'
|
||||
@@ -54,10 +62,10 @@ steps:
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
gsutil cp gs://domain-registry-dev-deploy/${TAG_NAME}/schema.jar \
|
||||
gsutil cp gs://$PROJECT_ID-deploy/${TAG_NAME}/schema.jar \
|
||||
/flyway/jars
|
||||
# Deploy SQL schema
|
||||
- name: 'gcr.io/${PROJECT_ID}/schema_deployer:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/schema_deployer:latest'
|
||||
volumes:
|
||||
- name: 'secrets'
|
||||
path: '/secrets'
|
||||
@@ -68,14 +76,14 @@ steps:
|
||||
# location. Do not use the 'artifacts' section for this since it will
|
||||
# upload an extra metadata file every time and pollute the folder.
|
||||
# TODO(weiminyu): modify this step so that TAG_NAME may be 'live'.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
entrypoint: /bin/bash
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo ${TAG_NAME} | \
|
||||
gsutil cp - gs://${PROJECT_ID}-deployed-tags/sql.${_ENV}.tag\
|
||||
gsutil cp - gs://$PROJECT_ID-deployed-tags/sql.${_ENV}.tag\
|
||||
timeout: 3600s
|
||||
options:
|
||||
machineType: 'N1_HIGHCPU_8'
|
||||
|
||||
@@ -9,16 +9,23 @@
|
||||
#
|
||||
# To trigger a build automatically, follow the instructions below and add a trigger:
|
||||
# https://cloud.google.com/cloud-build/docs/running-builds/automate-builds
|
||||
#
|
||||
# Note: to work around issue in Spinnaker's 'Deployment Manifest' stage,
|
||||
# variable references must avoid the ${var} format. Valid formats include
|
||||
# $var or ${"${var}"}. This file use the former. Since TAG_NAME is
|
||||
# expanded in the copies sent to Spinnaker, we preserve the brackets around
|
||||
# them for safe pattern matching during release.
|
||||
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
|
||||
steps:
|
||||
# Rsync the folder.
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
args:
|
||||
- gsutil
|
||||
- -m
|
||||
- rsync
|
||||
- -d
|
||||
- gs://${PROJECT_ID}-deploy/${TAG_NAME}
|
||||
- gs://${PROJECT_ID}-deploy/live
|
||||
- gs://$PROJECT_ID-deploy/${TAG_NAME}
|
||||
- gs://$PROJECT_ID-deploy/live
|
||||
timeout: 3600s
|
||||
options:
|
||||
machineType: 'N1_HIGHCPU_8'
|
||||
|
||||
@@ -11,15 +11,22 @@
|
||||
#
|
||||
# To trigger a build automatically, follow the instructions below and add a trigger:
|
||||
# https://cloud.google.com/cloud-build/docs/running-builds/automate-builds
|
||||
#
|
||||
# Note: to work around issue in Spinnaker's 'Deployment Manifest' stage,
|
||||
# variable references must avoid the ${var} format. Valid formats include
|
||||
# $var or ${"${var}"}. This file use the former. Since TAG_NAME is
|
||||
# expanded in the copies sent to Spinnaker, we preserve the brackets around
|
||||
# them for safe pattern matching during release.
|
||||
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
|
||||
steps:
|
||||
- name: 'gcr.io/${PROJECT_ID}/builder:latest'
|
||||
- name: 'gcr.io/$PROJECT_ID/builder:latest'
|
||||
args:
|
||||
- gcloud
|
||||
- container
|
||||
- images
|
||||
- add-tag
|
||||
- gcr.io/${PROJECT_ID}/${_IMAGE}:${TAG_NAME}
|
||||
- gcr.io/${PROJECT_ID}/${_IMAGE}:live
|
||||
- gcr.io/$PROJECT_ID/${_IMAGE}:${TAG_NAME}
|
||||
- gcr.io/$PROJECT_ID/${_IMAGE}:live
|
||||
timeout: 3600s
|
||||
options:
|
||||
machineType: 'N1_HIGHCPU_8'
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -157,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -193,8 +193,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -203,6 +203,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
io.grpc:grpc-netty:1.17.1
|
||||
@@ -156,10 +156,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -192,8 +192,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -202,6 +202,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
@@ -18,11 +18,11 @@ com.github.jnr:jnr-ffi:2.1.9
|
||||
com.github.jnr:jnr-posix:3.0.47
|
||||
com.github.jnr:jnr-unixsocket:0.21
|
||||
com.github.jnr:jnr-x86asm:1.0.2
|
||||
com.google.api-client:google-api-client-appengine:1.29.0
|
||||
com.google.api-client:google-api-client-appengine:1.30.7
|
||||
com.google.api-client:google-api-client-jackson2:1.27.0
|
||||
com.google.api-client:google-api-client-java6:1.27.0
|
||||
com.google.api-client:google-api-client-servlet:1.29.0
|
||||
com.google.api-client:google-api-client:1.29.2
|
||||
com.google.api-client:google-api-client-servlet:1.30.7
|
||||
com.google.api-client:google-api-client:1.30.7
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.44.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-admin-v2:0.38.0
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:0.38.0
|
||||
@@ -95,22 +95,22 @@ com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
com.google.gwt:gwt-user:2.8.2
|
||||
com.google.http-client:google-http-client-appengine:1.29.2
|
||||
com.google.http-client:google-http-client-jackson2:1.30.1
|
||||
com.google.http-client:google-http-client-appengine:1.34.0
|
||||
com.google.http-client:google-http-client-jackson2:1.32.1
|
||||
com.google.http-client:google-http-client-jackson:1.20.0
|
||||
com.google.http-client:google-http-client-protobuf:1.20.0
|
||||
com.google.http-client:google-http-client:1.30.1
|
||||
com.google.http-client:google-http-client:1.34.0
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0
|
||||
com.google.inject:guice:4.1.0
|
||||
com.google.j2objc:j2objc-annotations:1.3
|
||||
com.google.jsinterop:jsinterop-annotations:1.0.2
|
||||
com.google.monitoring-client:metrics:1.0.7
|
||||
com.google.monitoring-client:stackdriver:1.0.7
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.29.0
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.30.5
|
||||
com.google.oauth-client:google-oauth-client-java6:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.28.0
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.29.0
|
||||
com.google.oauth-client:google-oauth-client:1.29.2
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.30.5
|
||||
com.google.oauth-client:google-oauth-client:1.30.5
|
||||
com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-5
|
||||
com.google.protobuf:protobuf-java-util:3.6.1
|
||||
com.google.protobuf:protobuf-java:3.6.1
|
||||
@@ -135,7 +135,7 @@ io.dropwizard.metrics:metrics-core:3.1.2
|
||||
io.grpc:grpc-all:1.17.1
|
||||
io.grpc:grpc-alts:1.17.1
|
||||
io.grpc:grpc-auth:1.17.1
|
||||
io.grpc:grpc-context:1.19.0
|
||||
io.grpc:grpc-context:1.22.1
|
||||
io.grpc:grpc-core:1.17.1
|
||||
io.grpc:grpc-grpclb:1.17.1
|
||||
io.grpc:grpc-netty-shaded:1.17.1
|
||||
@@ -157,10 +157,10 @@ io.netty:netty-handler:4.1.30.Final
|
||||
io.netty:netty-resolver:4.1.30.Final
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.17.Final
|
||||
io.netty:netty-transport:4.1.30.Final
|
||||
io.opencensus:opencensus-api:0.21.0
|
||||
io.opencensus:opencensus-api:0.24.0
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.17.0
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.17.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.21.0
|
||||
io.opencensus:opencensus-contrib-http-util:0.24.0
|
||||
it.unimi.dsi:fastutil:6.5.16
|
||||
javax.activation:activation:1.1
|
||||
javax.activation:javax.activation-api:1.2.0
|
||||
@@ -193,8 +193,8 @@ org.apache.beam:beam-vendor-grpc-1_21_0:0.1
|
||||
org.apache.beam:beam-vendor-guava-26_0-jre:0.1
|
||||
org.apache.commons:commons-compress:1.19
|
||||
org.apache.commons:commons-lang3:3.5
|
||||
org.apache.httpcomponents:httpclient:4.5.8
|
||||
org.apache.httpcomponents:httpcore:4.4.11
|
||||
org.apache.httpcomponents:httpclient:4.5.10
|
||||
org.apache.httpcomponents:httpcore:4.4.12
|
||||
org.bouncycastle:bcpg-jdk15on:1.61
|
||||
org.bouncycastle:bcprov-jdk15on:1.61
|
||||
org.checkerframework:checker-qual:2.8.1
|
||||
@@ -203,6 +203,7 @@ org.codehaus.jackson:jackson-mapper-asl:1.9.13
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.18
|
||||
org.dom4j:dom4j:2.1.1
|
||||
org.easymock:easymock:3.0
|
||||
org.flywaydb:flyway-core:5.2.4
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user