1
0
mirror of https://github.com/google/nomulus synced 2026-05-25 01:01:57 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Ben McIlwain
eb7d779bc8 Relax premium list existence check to allow Cloud SQL migration (#428)
* Relax premium list existence check to allow Cloud SQL migration

We need to be able to simultaneously update premium lists that already exist in
Datastore and create them in Cloud SQL (because they haven't been migrated over
yet). This temporarily relaxes the existence check for Cloud SQL so that
"updates" will work even when the list doesn't yet exist there.
2020-01-06 18:09:21 -05:00
Lai Jiang
8fb12d21a2 Use the correct certificate provider type (#427)
TESTED: tested in alpha. Previous I only  tested locally and missed this
typo.
2020-01-06 16:19:50 -05:00
sarahcaseybot
5d9bf64b96 Fix IcannReportingUploadAction to upload reports from the previous month (#425)
* Fix IcannReportingUploadAction to upload reports from the previous month

getFileName now sets the file name of the report to upload to use the month before cursor time.

IcannReportingUploadAction no longer uploads the MANIFEST.txt file since it is not required based on (https://tools.ietf.org/html/draft-lozano-icann-registry-interfaces-07#page-9) and the previous implementation of this action did not upload it.

Deletes the ICANN_UPLOAD_MANIFEST cursor since it is no loner needed.

* Add the ICANN_UPLOAD_MANIFEST cursor back
2020-01-06 15:59:01 -05:00
Lai Jiang
76603812e3 Create kzip file for Kythe cross-referencing (#424)
This is set up per b/141716384.

TESTED=Tested on alpha and successfully uploaded the merged kzip file to
GCS.
2020-01-03 16:57:39 -05:00
Shicong Huang
a28754dc5d Add dual read claims list (#413)
* Add dual read claims list

* Improve warning log and use longer duration for cache

* Extract the comparison logic to a method

* Move cache to DAO
2020-01-03 10:59:34 -05:00
Weimin Yu
d6bf6f375e Fix flakiness in JodaMoneyConverterTest (#421)
* Fix flakiness in JodaMoneyConverterTest

JpdaMoneyConverterTest relies on Hibernate to deploy its schema.
This introduces an extra jdbc connection in the middle of a test
suite, and may break the connection count checks between tests made
by JpaTransactionManagerRule.

This change updated HibernateSchemaExporter to include Hibernate
proprietary mappings in META-INF/orm.xml.

This change also disabled Hibernate schema push for all tests,
and enabled sql statement logging.
2020-01-02 11:51:20 -05:00
Ben McIlwain
8f67c4b9cf Support premium list updating in Cloud SQL (#422)
* Support premium list updating in Cloud SQL

This also removes the requirement to specify --also_cloud_sql in nomulus premium
list tooling, instead always persisting to Cloud SQL. It removes a non-USD
premium label in the global test premium list (the Cloud SQL schema doesn't
support a mix of currency units in a single premium list). And it adds a method
to PremiumListDao to grab the most recent version of a given list.

* Merge branch 'master' into premium-lists-always-cloud-sql

* Revert test change

* Create new PremiumListUtils class and refactor out existing method

* Fix tests and update an existing premium price
2020-01-02 11:30:58 -05:00
37 changed files with 504 additions and 332 deletions

View File

@@ -179,6 +179,16 @@ allprojects {
mavenCentral()
}
}
if (rootProject.enableCrossReferencing.toBoolean()) {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.fork = true
options.forkOptions.executable =
"${project.rootDir}/kythe/extractors/javac-wrapper.sh"
}
}
}
}
task runPresubmits(type: Exec) {

View File

@@ -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.30.6
com.google.api-client:google-api-client-appengine:1.29.0
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.30.6
com.google.api-client:google-api-client:1.30.6
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
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.32.1
com.google.http-client:google-http-client-jackson2:1.32.1
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-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.32.1
com.google.http-client:google-http-client:1.30.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.6
com.google.monitoring-client:stackdriver:1.0.6
com.google.oauth-client:google-oauth-client-appengine:1.30.4
com.google.oauth-client:google-oauth-client-appengine:1.29.0
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.30.4
com.google.oauth-client:google-oauth-client:1.30.4
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
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.22.1
io.grpc:grpc-context:1.19.0
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.24.0
io.opencensus:opencensus-api:0.21.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.24.0
io.opencensus:opencensus-contrib-http-util:0.21.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.10
org.apache.httpcomponents:httpcore:4.4.12
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.8.1

View File

@@ -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.30.6
com.google.api-client:google-api-client-appengine:1.29.0
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.30.6
com.google.api-client:google-api-client:1.30.6
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
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.32.1
com.google.http-client:google-http-client-jackson2:1.32.1
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-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.32.1
com.google.http-client:google-http-client:1.30.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.6
com.google.monitoring-client:stackdriver:1.0.6
com.google.oauth-client:google-oauth-client-appengine:1.30.4
com.google.oauth-client:google-oauth-client-appengine:1.29.0
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.30.4
com.google.oauth-client:google-oauth-client:1.30.4
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
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.22.1
io.grpc:grpc-context:1.19.0
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.24.0
io.opencensus:opencensus-api:0.21.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.24.0
io.opencensus:opencensus-contrib-http-util:0.21.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.10
org.apache.httpcomponents:httpcore:4.4.12
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.8.1

View File

@@ -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.30.6
com.google.api-client:google-api-client-appengine:1.29.0
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.30.6
com.google.api-client:google-api-client:1.30.6
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
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.32.1
com.google.http-client:google-http-client-jackson2:1.32.1
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-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.32.1
com.google.http-client:google-http-client:1.30.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.6
com.google.monitoring-client:stackdriver:1.0.6
com.google.oauth-client:google-oauth-client-appengine:1.30.4
com.google.oauth-client:google-oauth-client-appengine:1.29.0
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.30.4
com.google.oauth-client:google-oauth-client:1.30.4
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
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.22.1
io.grpc:grpc-context:1.19.0
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.24.0
io.opencensus:opencensus-api:0.21.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.24.0
io.opencensus:opencensus-contrib-http-util:0.21.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.10
org.apache.httpcomponents:httpcore:4.4.12
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.8.1

View File

@@ -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.30.6
com.google.api-client:google-api-client-appengine:1.29.0
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.30.6
com.google.api-client:google-api-client:1.30.6
com.google.api-client:google-api-client-servlet:1.29.0
com.google.api-client:google-api-client:1.29.2
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.32.1
com.google.http-client:google-http-client-jackson2:1.32.1
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-jackson:1.20.0
com.google.http-client:google-http-client-protobuf:1.20.0
com.google.http-client:google-http-client:1.32.1
com.google.http-client:google-http-client:1.30.1
com.google.inject.extensions:guice-multibindings:4.1.0
com.google.inject:guice:4.1.0
com.google.j2objc:j2objc-annotations:1.3
com.google.jsinterop:jsinterop-annotations:1.0.2
com.google.monitoring-client:metrics:1.0.6
com.google.monitoring-client:stackdriver:1.0.6
com.google.oauth-client:google-oauth-client-appengine:1.30.4
com.google.oauth-client:google-oauth-client-appengine:1.29.0
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.30.4
com.google.oauth-client:google-oauth-client:1.30.4
com.google.oauth-client:google-oauth-client-servlet:1.29.0
com.google.oauth-client:google-oauth-client:1.29.2
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.22.1
io.grpc:grpc-context:1.19.0
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.24.0
io.opencensus:opencensus-api:0.21.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.24.0
io.opencensus:opencensus-contrib-http-util:0.21.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.10
org.apache.httpcomponents:httpcore:4.4.12
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.bouncycastle:bcpg-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.8.1

View File

@@ -32,7 +32,15 @@ public class CacheUtils {
* lists downloaded from the TMCH get updated in Datastore and the caches need to be refreshed.)
*/
public static <T> Supplier<T> memoizeWithShortExpiration(Supplier<T> original) {
Duration expiration = getSingletonCacheRefreshDuration();
return tryMemoizeWithExpiration(getSingletonCacheRefreshDuration(), original);
}
/**
* Memoize a supplier with the given expiration. If the expiration is zero(likely happens in a
* unit test), it returns the original supplier.
*/
public static <T> Supplier<T> tryMemoizeWithExpiration(
Duration expiration, Supplier<T> original) {
return expiration.isEqual(ZERO)
? original
: memoizeWithExpiration(original, expiration.getMillis(), MILLISECONDS);

View File

@@ -87,7 +87,9 @@ public class Cursor extends ImmutableObject {
/** Cursor for tracking monthly uploads of ICANN activity reports. */
ICANN_UPLOAD_ACTIVITY(Registry.class),
/** Cursor for tracking monthly upload of MANIFEST.txt to ICANN. */
// TODO(sarahbot) Delete this cursor once all data in the database that refers to it is removed.
/** Cursor for tracking monthly uploads of MANIFEST.txt to ICANN. No longer used. */
@Deprecated
ICANN_UPLOAD_MANIFEST(EntityGroupRoot.class);
/** See the definition of scope on {@link #getScopeClass}. */

View File

@@ -27,6 +27,10 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.collect.Maps;
import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.EmbedMap;
@@ -40,6 +44,8 @@ import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason;
import google.registry.model.annotations.VirtualEntity;
import google.registry.model.common.CrossTldSingleton;
import google.registry.schema.tmch.ClaimsList;
import google.registry.schema.tmch.ClaimsListDao;
import google.registry.util.CollectionUtils;
import google.registry.util.Concurrent;
import google.registry.util.Retrier;
@@ -71,6 +77,8 @@ import org.joda.time.DateTime;
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public class ClaimsListShard extends ImmutableObject {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
/** The number of claims list entries to store per shard. */
private static final int SHARD_SIZE = 10000;
@@ -112,8 +120,7 @@ public class ClaimsListShard extends ImmutableObject {
Concurrent.transform(
shardKeys,
key ->
tm()
.transactNewReadOnly(
tm().transactNewReadOnly(
() -> {
ClaimsListShard claimsListShard = ofy().load().key(key).now();
checkState(
@@ -142,9 +149,52 @@ public class ClaimsListShard extends ImmutableObject {
}
}
}
return create(creationTime, ImmutableMap.copyOf(combinedLabelsToKeys));
ClaimsListShard datastoreList =
create(creationTime, ImmutableMap.copyOf(combinedLabelsToKeys));
// Also load the list from Cloud SQL, compare the two lists, and log if different.
try {
loadAndCompareCloudSqlList(datastoreList);
} catch (Throwable t) {
logger.atSevere().withCause(t).log("Error comparing reserved lists.");
}
return datastoreList;
};
private static final void loadAndCompareCloudSqlList(ClaimsListShard datastoreList) {
Optional<ClaimsList> maybeCloudSqlList = ClaimsListDao.getLatestRevision();
if (maybeCloudSqlList.isPresent()) {
ClaimsList cloudSqlList = maybeCloudSqlList.get();
MapDifference<String, String> diff =
Maps.difference(datastoreList.labelsToKeys, cloudSqlList.getLabelsToKeys());
if (!diff.areEqual()) {
if (diff.entriesDiffering().size() > 10) {
logger.atWarning().log(
String.format(
"Unequal claims lists detected, Cloud SQL list with revision id %d has %d"
+ " different records than the current Datastore list.",
cloudSqlList.getRevisionId(), diff.entriesDiffering().size()));
} else {
StringBuilder diffMessage = new StringBuilder("Unequal claims lists detected:\n");
diff.entriesDiffering().entrySet().stream()
.forEach(
entry -> {
String label = entry.getKey();
ValueDifference<String> valueDiff = entry.getValue();
diffMessage.append(
String.format(
"Domain label %s has key %s in Datastore and key %s in Cloud"
+ " SQL.\n",
label, valueDiff.leftValue(), valueDiff.rightValue()));
});
logger.atWarning().log(diffMessage.toString());
}
}
} else {
logger.atWarning().log("Claims list in Cloud SQL is empty.");
}
}
/**
* A cached supplier that fetches the claims list shards from Datastore and recombines them into a
* single {@link ClaimsListShard} object.

View File

@@ -32,6 +32,9 @@ import org.hibernate.tool.schema.TargetType;
/** Utility class to export DDL script for given {@link javax.persistence.Entity} classes. */
public class HibernateSchemaExporter {
// Hibernate proprietary mappings.
private static final String HIBERNATE_MAPPING_RESOURCES = "META-INF/orm.xml";
private final String jdbcUrl;
private final String username;
private final String password;
@@ -63,6 +66,7 @@ public class HibernateSchemaExporter {
try (StandardServiceRegistry registry =
new StandardServiceRegistryBuilder().applySettings(settings).build()) {
MetadataSources metadata = new MetadataSources(registry);
metadata.addResource(HIBERNATE_MAPPING_RESOURCES);
// Note that we need to also add all converters to the Hibernate context because
// the entity class may use the customized type.

View File

@@ -20,7 +20,6 @@ import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.model.transaction.TransactionManagerFactory.tm;
import static google.registry.reporting.icann.IcannReportingModule.MANIFEST_FILE_NAME;
import static google.registry.reporting.icann.IcannReportingModule.PARAM_SUBDIR;
import static google.registry.request.Action.Method.POST;
import static javax.servlet.http.HttpServletResponse.SC_OK;
@@ -65,8 +64,9 @@ import org.joda.time.Duration;
* Action that uploads the monthly activity/transactions reports from GCS to ICANN via an HTTP PUT.
*
* <p>This should be run after {@link IcannReportingStagingAction}, which writes out the month's
* reports and a MANIFEST.txt file. This action reads the filenames from the MANIFEST.txt, and
* attempts to upload every file in the manifest to ICANN's endpoint.
* reports and a MANIFEST.txt file. This action checks each ICANN_UPLOAD_TX and
* ICANN_UPLOAD_ACTIVITY cursor and uploads the corresponding report if the cursor time is before
* now.
*
* <p>Parameters:
*
@@ -181,32 +181,22 @@ public final class IcannReportingUploadAction implements Runnable {
// Set cursor to first day of next month if the upload succeeded
if (success) {
Cursor newCursor;
if (cursorType.equals(CursorType.ICANN_UPLOAD_MANIFEST)) {
newCursor =
Cursor.createGlobal(
cursorType, cursorTime.withTimeAtStartOfDay().withDayOfMonth(1).plusMonths(1));
} else {
newCursor =
Cursor.create(
cursorType,
cursorTime.withTimeAtStartOfDay().withDayOfMonth(1).plusMonths(1),
Registry.get(tldStr));
}
Cursor newCursor =
Cursor.create(
cursorType,
cursorTime.withTimeAtStartOfDay().withDayOfMonth(1).plusMonths(1),
Registry.get(tldStr));
tm().transact(() -> ofy().save().entity(newCursor));
}
}
private String getFileName(CursorType cursorType, DateTime cursorTime, String tld) {
if (cursorType.equals(CursorType.ICANN_UPLOAD_MANIFEST)) {
return MANIFEST_FILE_NAME;
}
return String.format(
"%s%s%d%02d.csv",
tld,
(cursorType.equals(CursorType.ICANN_UPLOAD_ACTIVITY) ? "-activity-" : "-transactions-"),
cursorTime.year().get(),
cursorTime.monthOfYear().get());
cursorTime.withDayOfMonth(1).minusMonths(1).monthOfYear().get());
}
/** Returns a map of each cursor to the CursorType and tld. */
@@ -222,7 +212,6 @@ public final class IcannReportingUploadAction implements Runnable {
ImmutableSet.Builder<Key<Cursor>> keys = new ImmutableSet.Builder<>();
keys.addAll(activityKeyMap.keySet());
keys.addAll(transactionKeyMap.keySet());
keys.add(Cursor.createGlobalKey(CursorType.ICANN_UPLOAD_MANIFEST));
Map<Key<Cursor>, Cursor> cursorMap = ofy().load().keys(keys.build());
ImmutableMap.Builder<Cursor, CursorInfo> cursors = new ImmutableMap.Builder<>();
@@ -230,11 +219,6 @@ public final class IcannReportingUploadAction implements Runnable {
activityKeyMap, CursorType.ICANN_UPLOAD_ACTIVITY, cursorMap, cursors);
defaultNullCursorsToNextMonthAndAddToMap(
transactionKeyMap, CursorType.ICANN_UPLOAD_TX, cursorMap, cursors);
Cursor manifestCursor =
cursorMap.getOrDefault(
Cursor.createGlobalKey(CursorType.ICANN_UPLOAD_MANIFEST),
Cursor.createGlobal(CursorType.ICANN_UPLOAD_MANIFEST, clock.nowUtc().minusDays(1)));
cursors.put(manifestCursor, CursorInfo.create(CursorType.ICANN_UPLOAD_MANIFEST, null));
return cursors.build();
}
@@ -259,7 +243,14 @@ public final class IcannReportingUploadAction implements Runnable {
// report staged for upload.
Cursor cursor =
cursorMap.getOrDefault(
key, Cursor.create(type, clock.nowUtc().minusDays(1), registry));
key,
Cursor.create(
type,
clock.nowUtc().withDayOfMonth(1).withTimeAtStartOfDay().plusMonths(1),
registry));
if (!cursorMap.containsValue(cursor)) {
tm().transact(() -> ofy().save().entity(cursor));
}
cursors.put(cursor, CursorInfo.create(type, registry.getTldStr()));
});
}

View File

@@ -66,10 +66,15 @@ public class PremiumListDao {
jpaTm()
.transact(
() -> {
checkArgument(
checkExists(premiumList.getName()),
"Can't update non-existent premium list '%s'",
premiumList.getName());
// This check is currently disabled because, during the Cloud SQL migration, we need
// to be able to update premium lists in Datastore while simultaneously creating their
// first revision in Cloud SQL (i.e. if they haven't been migrated over yet).
// TODO(b/147246613): Reinstate this once all premium lists are migrated to Cloud SQL,
// and re-enable the test update_throwsWhenListDoesntExist().
// checkArgument(
// checkExists(premiumList.getName()),
// "Can't update non-existent premium list '%s'",
// premiumList.getName());
jpaTm().getEntityManager().persist(premiumList);
});
}
@@ -80,7 +85,7 @@ public class PremiumListDao {
* <p>Note that this does not load <code>PremiumList.labelsToPrices</code>! If you need to check
* prices, use {@link #getPremiumPrice}.
*/
static Optional<PremiumList> getLatestRevision(String premiumListName) {
public static Optional<PremiumList> getLatestRevision(String premiumListName) {
return jpaTm()
.transact(
() ->

View File

@@ -0,0 +1,61 @@
// 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.schema.tld;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import google.registry.model.registry.label.PremiumList.PremiumListEntry;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import org.joda.money.CurrencyUnit;
/** Static utility methods for {@link PremiumList}. */
public class PremiumListUtils {
public static PremiumList parseToPremiumList(String name, String inputData) {
List<String> inputDataPreProcessed =
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
ImmutableMap<String, PremiumListEntry> prices =
new google.registry.model.registry.label.PremiumList.Builder()
.setName(name)
.build()
.parse(inputDataPreProcessed);
ImmutableSet<CurrencyUnit> currencies =
prices.values().stream()
.map(e -> e.getValue().getCurrencyUnit())
.distinct()
.collect(toImmutableSet());
checkArgument(
currencies.size() == 1,
"The Cloud SQL schema requires exactly one currency, but got: %s",
ImmutableSortedSet.copyOf(currencies));
CurrencyUnit currency = Iterables.getOnlyElement(currencies);
Map<String, BigDecimal> priceAmounts =
Maps.transformValues(prices, ple -> ple.getValue().getAmount());
return google.registry.schema.tld.PremiumList.create(name, currency, priceAmounts);
}
private PremiumListUtils() {}
}

View File

@@ -14,9 +14,14 @@
package google.registry.schema.tmch;
import static google.registry.config.RegistryConfig.getDomainLabelListCacheDuration;
import static google.registry.model.CacheUtils.tryMemoizeWithExpiration;
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
import com.google.common.base.Supplier;
import com.google.common.flogger.FluentLogger;
import google.registry.util.NonFinalForTesting;
import java.util.Optional;
import javax.persistence.EntityManager;
/** Data access object for {@link ClaimsList}. */
@@ -24,6 +29,11 @@ public class ClaimsListDao {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
/** In-memory cache for claims list. */
@NonFinalForTesting
private static Supplier<Optional<ClaimsList>> cacheClaimsList =
tryMemoizeWithExpiration(getDomainLabelListCacheDuration(), ClaimsListDao::getLatestRevision);
private static void save(ClaimsList claimsList) {
jpaTm().transact(() -> jpaTm().getEntityManager().persist(claimsList));
}
@@ -47,10 +57,12 @@ public class ClaimsListDao {
}
/**
* Returns the current revision of the {@link ClaimsList} in Cloud SQL. Throws exception if there
* is no claims in the table.
* Returns the most recent revision of the {@link ClaimsList} in Cloud SQL, if it exists.
* TODO(shicong): Change this method to package level access after dual-read phase.
* ClaimsListShard uses this method to retrieve claims list in Cloud SQL for the comparison, and
* ClaimsListShard is not in this package.
*/
public static ClaimsList getCurrent() {
public static Optional<ClaimsList> getLatestRevision() {
return jpaTm()
.transact(
() -> {
@@ -63,9 +75,15 @@ public class ClaimsListDao {
+ " :revisionId",
ClaimsList.class)
.setParameter("revisionId", revisionId)
.getSingleResult();
.getResultStream()
.findFirst();
});
}
/** Returns the most recent revision of the {@link ClaimsList}, from cache. */
public static Optional<ClaimsList> getLatestRevisionCached() {
return cacheClaimsList.get();
}
private ClaimsListDao() {}
}

View File

@@ -16,7 +16,6 @@ package google.registry.tools;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.ALSO_CLOUD_SQL_PARAM;
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.INPUT_PARAM;
import static google.registry.tools.server.CreateOrUpdatePremiumListAction.NAME_PARAM;
import static google.registry.util.ListNamingUtils.convertFilePathToName;
@@ -58,12 +57,6 @@ abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand
required = true)
Path inputFile;
@Parameter(
names = {"--also_cloud_sql"},
description =
"Persist premium list to Cloud SQL in addition to Datastore; defaults to false.")
boolean alsoCloudSql;
protected AppEngineConnection connection;
protected int inputLineCount;
@@ -97,7 +90,6 @@ abstract class CreateOrUpdatePremiumListCommand extends ConfirmingCommand
public String execute() throws Exception {
ImmutableMap.Builder<String, String> params = new ImmutableMap.Builder<>();
params.put(NAME_PARAM, name);
params.put(ALSO_CLOUD_SQL_PARAM, Boolean.toString(alsoCloudSql));
String inputFileContents = new String(Files.readAllBytes(inputFile), UTF_8);
String requestBody =
Joiner.on('&').withKeyValueSeparator("=").join(

View File

@@ -14,26 +14,13 @@
package google.registry.tools.server;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.flogger.LazyArgs.lazy;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.flogger.FluentLogger;
import google.registry.model.registry.label.PremiumList;
import google.registry.model.registry.label.PremiumList.PremiumListEntry;
import google.registry.request.JsonResponse;
import google.registry.request.Parameter;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.joda.money.CurrencyUnit;
/** Abstract base class for actions that update premium lists. */
public abstract class CreateOrUpdatePremiumListAction implements Runnable {
@@ -44,7 +31,6 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
public static final String NAME_PARAM = "name";
public static final String INPUT_PARAM = "inputData";
public static final String ALSO_CLOUD_SQL_PARAM = "alsoCloudSql";
@Inject JsonResponse response;
@@ -56,10 +42,6 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
@Parameter(INPUT_PARAM)
String inputData;
@Inject
@Parameter(ALSO_CLOUD_SQL_PARAM)
boolean alsoCloudSql;
@Override
public void run() {
try {
@@ -76,40 +58,15 @@ public abstract class CreateOrUpdatePremiumListAction implements Runnable {
return;
}
if (alsoCloudSql) {
try {
saveToCloudSql();
} catch (Throwable e) {
logger.atSevere().withCause(e).log(
"Unexpected error saving premium list to Cloud SQL from nomulus tool command");
response.setPayload(ImmutableMap.of("error", e.toString(), "status", "error"));
return;
}
try {
saveToCloudSql();
} catch (Throwable e) {
logger.atSevere().withCause(e).log(
"Unexpected error saving premium list to Cloud SQL from nomulus tool command");
response.setPayload(ImmutableMap.of("error", e.toString(), "status", "error"));
}
}
google.registry.schema.tld.PremiumList parseInputToPremiumList() {
List<String> inputDataPreProcessed =
Splitter.on('\n').omitEmptyStrings().splitToList(inputData);
ImmutableMap<String, PremiumListEntry> prices =
new PremiumList.Builder().setName(name).build().parse(inputDataPreProcessed);
ImmutableSet<CurrencyUnit> currencies =
prices.values().stream()
.map(e -> e.getValue().getCurrencyUnit())
.distinct()
.collect(toImmutableSet());
checkArgument(
currencies.size() == 1,
"The Cloud SQL schema requires exactly one currency, but got: %s",
ImmutableSortedSet.copyOf(currencies));
CurrencyUnit currency = Iterables.getOnlyElement(currencies);
Map<String, BigDecimal> priceAmounts =
Maps.transformValues(prices, ple -> ple.getValue().getAmount());
return google.registry.schema.tld.PremiumList.create(name, currency, priceAmounts);
}
/** Logs the premium list data at INFO, truncated if too long. */
void logInputData() {
logger.atInfo().log(

View File

@@ -19,6 +19,7 @@ import static google.registry.model.registry.Registries.assertTldExists;
import static google.registry.model.registry.label.PremiumListUtils.doesPremiumListExist;
import static google.registry.model.registry.label.PremiumListUtils.savePremiumListAndEntries;
import static google.registry.request.Action.Method.POST;
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
@@ -81,7 +82,7 @@ public class CreatePremiumListAction extends CreateOrUpdatePremiumListAction {
logger.atInfo().log("Saving premium list to Cloud SQL for TLD %s", name);
// TODO(mcilwain): Call logInputData() here once Datastore persistence is removed.
google.registry.schema.tld.PremiumList premiumList = parseInputToPremiumList();
google.registry.schema.tld.PremiumList premiumList = parseToPremiumList(name, inputData);
PremiumListDao.saveNew(premiumList);
String message =

View File

@@ -60,12 +60,6 @@ public class ToolsServerModule {
return extractRequiredParameter(req, CreatePremiumListAction.INPUT_PARAM);
}
@Provides
@Parameter("alsoCloudSql")
static boolean provideAlsoCloudSql(HttpServletRequest req) {
return extractBooleanParameter(req, CreatePremiumListAction.ALSO_CLOUD_SQL_PARAM);
}
@Provides
@Parameter("premiumListName")
static String provideName(HttpServletRequest req) {

View File

@@ -17,6 +17,7 @@ package google.registry.tools.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.registry.label.PremiumListUtils.savePremiumListAndEntries;
import static google.registry.request.Action.Method.POST;
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
@@ -24,6 +25,7 @@ import com.google.common.flogger.FluentLogger;
import google.registry.model.registry.label.PremiumList;
import google.registry.request.Action;
import google.registry.request.auth.Auth;
import google.registry.schema.tld.PremiumListDao;
import java.util.List;
import java.util.Optional;
import javax.inject.Inject;
@@ -68,10 +70,17 @@ public class UpdatePremiumListAction extends CreateOrUpdatePremiumListAction {
response.setPayload(ImmutableMap.of("status", "success", "message", message));
}
// TODO(mcilwain): Implement this in a subsequent PR.
@Override
protected void saveToCloudSql() {
throw new UnsupportedOperationException(
"Updating of premium lists in Cloud SQL is not supported yet");
logger.atInfo().log("Updating premium list '%s' in Cloud SQL.", name);
// TODO(mcilwain): Add logInputData() call here once DB migration is complete.
google.registry.schema.tld.PremiumList premiumList = parseToPremiumList(name, inputData);
PremiumListDao.update(premiumList);
String message =
String.format(
"Updated premium list '%s' with %d entries.",
premiumList.getName(), premiumList.getLabelsToPrices().size());
logger.atInfo().log(message);
// TODO(mcilwain): Call response.setPayload() here once DB migration is complete.
}
}

View File

@@ -119,6 +119,9 @@ abstract class JpaTransactionManagerRule extends ExternalResource {
// If there are user properties, create a new properties object with these added.
ImmutableMap.Builder builder = properties.builder();
builder.putAll(userProperties);
// Forbid Hibernate push to stay consistent with flyway-based schema management.
builder.put(Environment.HBM2DDL_AUTO, "none");
builder.put(Environment.SHOW_SQL, "true");
properties = builder.build();
}
assertNormalActiveConnection();

View File

@@ -35,7 +35,6 @@ import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKeyColumn;
import javax.persistence.PostLoad;
import org.hibernate.cfg.Environment;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.junit.Rule;
@@ -67,7 +66,6 @@ public class JodaMoneyConverterTest {
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
.withEntityClass(TestEntity.class, ComplexTestEntity.class)
.withProperty(Environment.HBM2DDL_AUTO, "update")
.buildUnitTestRule();
@Test
@@ -82,7 +80,7 @@ public class JodaMoneyConverterTest {
jpaTm()
.getEntityManager()
.createNativeQuery(
"SELECT amount, currency FROM TestEntity WHERE name = 'id'")
"SELECT amount, currency FROM \"TestEntity\" WHERE name = 'id'")
.getResultList());
assertThat(result.size()).isEqualTo(1);
assertThat(Arrays.asList((Object[]) result.get(0)))
@@ -113,7 +111,7 @@ public class JodaMoneyConverterTest {
.getEntityManager()
.createNativeQuery(
"SELECT my_amount, my_currency, your_amount, your_currency FROM"
+ " ComplexTestEntity WHERE name = 'id'")
+ " \"ComplexTestEntity\" WHERE name = 'id'")
.getResultList());
assertThat(result.size()).isEqualTo(1);
assertThat(Arrays.asList((Object[]) result.get(0)))
@@ -127,7 +125,7 @@ public class JodaMoneyConverterTest {
jpaTm()
.getEntityManager()
.createNativeQuery(
"SELECT map_amount, map_currency FROM MoneyMap"
"SELECT map_amount, map_currency FROM \"MoneyMap\""
+ " WHERE entity_name = 'id' AND map_key = 'dos'")
.getResultList());
ComplexTestEntity persisted =
@@ -148,7 +146,9 @@ public class JodaMoneyConverterTest {
assertThat(persisted.moneyMap).containsExactlyEntriesIn(moneyMap);
}
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
// Override entity name to exclude outer-class name in table name. Not necessary if class is not
// inner class. The double quotes are added to conform to our schema generation convention.
@Entity(name = "\"TestEntity\"")
public static class TestEntity extends ImmutableObject {
@Id String name = "id";
@@ -162,7 +162,8 @@ public class JodaMoneyConverterTest {
}
}
@Entity(name = "ComplexTestEntity") // Override entity name to avoid the nested class reference.
// See comments on the annotation for TestEntity above for reason.
@Entity(name = "\"ComplexTestEntity\"")
// This entity is used to test column override for embedded fields and collections.
public static class ComplexTestEntity extends ImmutableObject {

View File

@@ -64,9 +64,6 @@ public class IcannReportingUploadActionTest {
private static final byte[] PAYLOAD_SUCCESS = "test,csv\n13,37".getBytes(UTF_8);
private static final byte[] PAYLOAD_FAIL = "ahah,csv\n12,34".getBytes(UTF_8);
private static final byte[] MANIFEST_PAYLOAD =
"tld-transactions-200606.csv\ntld-activity-200606.csv\nfoo-transactions-200606.csv\nfoo-activity-200606.csv\n"
.getBytes(UTF_8);
private final IcannHttpReporter mockReporter = mock(IcannHttpReporter.class);
private final SendEmailService emailService = mock(SendEmailService.class);
private final FakeResponse response = new FakeResponse();
@@ -111,30 +108,23 @@ public class IcannReportingUploadActionTest {
gcsService,
new GcsFilename("basin/icann/monthly/2006-06", "foo-activity-200606.csv"),
PAYLOAD_SUCCESS);
writeGcsFile(
gcsService,
new GcsFilename("basin/icann/monthly/2006-06", "MANIFEST.txt"),
MANIFEST_PAYLOAD);
when(mockReporter.send(PAYLOAD_SUCCESS, "tld-transactions-200606.csv")).thenReturn(true);
when(mockReporter.send(PAYLOAD_SUCCESS, "foo-transactions-200606.csv")).thenReturn(true);
when(mockReporter.send(PAYLOAD_FAIL, "tld-activity-200606.csv")).thenReturn(false);
when(mockReporter.send(PAYLOAD_SUCCESS, "foo-activity-200606.csv")).thenReturn(true);
when(mockReporter.send(MANIFEST_PAYLOAD, "MANIFEST.txt")).thenReturn(true);
clock.setTo(DateTime.parse("2006-06-06T00:30:00Z"));
clock.setTo(DateTime.parse("2006-07-05T00:30:00Z"));
persistResource(
Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-06-06TZ"), Registry.get("tld")));
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-07-01TZ"), Registry.get("tld")));
persistResource(
Cursor.create(
CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-06-06TZ"), Registry.get("tld")));
persistResource(
Cursor.createGlobal(CursorType.ICANN_UPLOAD_MANIFEST, DateTime.parse("2006-07-06TZ")));
CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-07-01TZ"), Registry.get("tld")));
persistResource(
Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-06-06TZ"), Registry.get("foo")));
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-07-01TZ"), Registry.get("foo")));
persistResource(
Cursor.create(
CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-06-06TZ"), Registry.get("foo")));
CursorType.ICANN_UPLOAD_TX, DateTime.parse("2006-07-01TZ"), Registry.get("foo")));
loggerToIntercept.addHandler(logHandler);
}
@@ -176,7 +166,7 @@ public class IcannReportingUploadActionTest {
.load()
.key(Cursor.createKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")))
.now();
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ"));
}
@Test
@@ -195,24 +185,6 @@ public class IcannReportingUploadActionTest {
new InternetAddress("sender@example.com")));
}
@Test
public void testSuccess_uploadManifest() throws Exception {
persistResource(
Cursor.createGlobal(CursorType.ICANN_UPLOAD_MANIFEST, DateTime.parse("2006-06-06TZ")));
IcannReportingUploadAction action = createAction();
action.run();
ofy().clearSessionCache();
Cursor cursor =
ofy().load().key(Cursor.createGlobalKey(CursorType.ICANN_UPLOAD_MANIFEST)).now();
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
verify(mockReporter).send(PAYLOAD_FAIL, "tld-activity-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "foo-activity-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "foo-transactions-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "tld-transactions-200606.csv");
verify(mockReporter).send(MANIFEST_PAYLOAD, "MANIFEST.txt");
verifyNoMoreInteractions(mockReporter);
}
@Test
public void testSuccess_withRetry() throws Exception {
IcannReportingUploadAction action = createAction();
@@ -262,7 +234,7 @@ public class IcannReportingUploadActionTest {
.load()
.key(Cursor.createKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("tld")))
.now();
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-06-06TZ"));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
}
@Test
@@ -276,7 +248,7 @@ public class IcannReportingUploadActionTest {
.load()
.key(Cursor.createKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("foo")))
.now();
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-06-06TZ"));
assertThat(cursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
verifyNoMoreInteractions(mockReporter);
}
@@ -323,8 +295,8 @@ public class IcannReportingUploadActionTest {
public void testWarning_fileNotStagedYet() throws Exception {
persistResource(
Cursor.create(
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-07-01TZ"), Registry.get("foo")));
clock.setTo(DateTime.parse("2006-07-01T00:30:00Z"));
CursorType.ICANN_UPLOAD_ACTIVITY, DateTime.parse("2006-08-01TZ"), Registry.get("foo")));
clock.setTo(DateTime.parse("2006-08-01T00:30:00Z"));
IcannReportingUploadAction action = createAction();
action.subdir = "icann/monthly/2006-07";
action.run();
@@ -349,39 +321,25 @@ public class IcannReportingUploadActionTest {
}
@Test
public void testSuccess_nullCursors() throws Exception {
public void testSuccess_nullCursorsInitiatedToFirstOfNextMonth() throws Exception {
createTlds("new");
writeGcsFile(
gcsService,
new GcsFilename("basin/icann/monthly/2006-06", "new-transactions-200606.csv"),
PAYLOAD_SUCCESS);
writeGcsFile(
gcsService,
new GcsFilename("basin/icann/monthly/2006-06", "new-activity-200606.csv"),
PAYLOAD_SUCCESS);
when(mockReporter.send(PAYLOAD_SUCCESS, "new-transactions-200606.csv")).thenReturn(true);
when(mockReporter.send(PAYLOAD_SUCCESS, "new-activity-200606.csv")).thenReturn(true);
IcannReportingUploadAction action = createAction();
action.run();
verify(mockReporter).send(PAYLOAD_SUCCESS, "foo-activity-200606.csv");
verify(mockReporter).send(PAYLOAD_FAIL, "tld-activity-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "new-activity-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "foo-transactions-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "tld-transactions-200606.csv");
verify(mockReporter).send(PAYLOAD_SUCCESS, "new-transactions-200606.csv");
verifyNoMoreInteractions(mockReporter);
verify(emailService)
.sendEmail(
EmailMessage.create(
"ICANN Monthly report upload summary: 5/6 succeeded",
"ICANN Monthly report upload summary: 3/4 succeeded",
"Report Filename - Upload status:\n"
+ "foo-activity-200606.csv - SUCCESS\n"
+ "new-activity-200606.csv - SUCCESS\n"
+ "tld-activity-200606.csv - FAILURE\n"
+ "foo-transactions-200606.csv - SUCCESS\n"
+ "new-transactions-200606.csv - SUCCESS\n"
+ "tld-transactions-200606.csv - SUCCESS",
new InternetAddress("recipient@example.com"),
new InternetAddress("sender@example.com")));
@@ -391,10 +349,10 @@ public class IcannReportingUploadActionTest {
.load()
.key(Cursor.createKey(CursorType.ICANN_UPLOAD_ACTIVITY, Registry.get("new")))
.now();
assertThat(newActivityCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
assertThat(newActivityCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ"));
Cursor newTransactionCursor =
ofy().load().key(Cursor.createKey(CursorType.ICANN_UPLOAD_TX, Registry.get("new"))).now();
assertThat(newTransactionCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-07-01TZ"));
assertThat(newTransactionCursor.getCursorTime()).isEqualTo(DateTime.parse("2006-08-01TZ"));
}
}

View File

@@ -18,10 +18,13 @@ import google.registry.model.registry.RegistryLockDaoTest;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.schema.cursor.CursorDaoTest;
import google.registry.schema.tld.PremiumListDaoTest;
import google.registry.schema.tld.PremiumListUtilsTest;
import google.registry.schema.tld.ReservedListDaoTest;
import google.registry.schema.tmch.ClaimsListDaoTest;
import google.registry.tools.CreateReservedListCommandTest;
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 org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -41,10 +44,13 @@ import org.junit.runners.Suite.SuiteClasses;
ClaimsListDaoTest.class,
CreateReservedListCommandTest.class,
CursorDaoTest.class,
CreatePremiumListActionTest.class,
PremiumListDaoTest.class,
PremiumListUtilsTest.class,
RegistryLockDaoTest.class,
RegistryLockGetActionTest.class,
ReservedListDaoTest.class,
UpdatePremiumListActionTest.class,
UpdateReservedListCommandTest.class
})
public class SqlIntegrationTestSuite {}

View File

@@ -32,9 +32,10 @@ import google.registry.model.transaction.JpaTestRules;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.testing.AppEngineRule;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -66,13 +67,9 @@ public class PremiumListDaoTest {
jpaTm()
.transact(
() -> {
PremiumList persistedList =
jpaTm()
.getEntityManager()
.createQuery(
"SELECT pl FROM PremiumList pl WHERE pl.name = :name", PremiumList.class)
.setParameter("name", "testname")
.getSingleResult();
Optional<PremiumList> persistedListOpt = PremiumListDao.getLatestRevision("testname");
assertThat(persistedListOpt).isPresent();
PremiumList persistedList = persistedListOpt.get();
assertThat(persistedList.getLabelsToPrices()).containsExactlyEntriesIn(TEST_PRICES);
assertThat(persistedList.getCreationTimestamp())
.isEqualTo(jpaRule.getTxnClock().nowUtc());
@@ -81,26 +78,40 @@ public class PremiumListDaoTest {
@Test
public void update_worksSuccessfully() {
PremiumListDao.saveNew(
PremiumListDao.saveNew(PremiumList.create("testname", CurrencyUnit.USD, TEST_PRICES));
Optional<PremiumList> persistedList = PremiumListDao.getLatestRevision("testname");
assertThat(persistedList).isPresent();
long firstRevisionId = persistedList.get().getRevisionId();
PremiumListDao.update(
PremiumList.create(
"testname", USD, ImmutableMap.of("firstversion", BigDecimal.valueOf(123.45))));
PremiumListDao.update(PremiumList.create("testname", USD, TEST_PRICES));
"testname",
CurrencyUnit.USD,
ImmutableMap.of(
"update",
BigDecimal.valueOf(55343.12),
"new",
BigDecimal.valueOf(0.01),
"silver",
BigDecimal.valueOf(30.03))));
jpaTm()
.transact(
() -> {
List<PremiumList> persistedLists =
jpaTm()
.getEntityManager()
.createQuery(
"SELECT pl FROM PremiumList pl WHERE pl.name = :name ORDER BY"
+ " pl.revisionId",
PremiumList.class)
.setParameter("name", "testname")
.getResultList();
assertThat(persistedLists).hasSize(2);
assertThat(persistedLists.get(1).getLabelsToPrices())
.containsExactlyEntriesIn(TEST_PRICES);
assertThat(persistedLists.get(1).getCreationTimestamp())
Optional<PremiumList> updatedListOpt = PremiumListDao.getLatestRevision("testname");
assertThat(updatedListOpt).isPresent();
PremiumList updatedList = updatedListOpt.get();
assertThat(updatedList.getLabelsToPrices())
.containsExactlyEntriesIn(
ImmutableMap.of(
"update",
BigDecimal.valueOf(55343.12),
"new",
BigDecimal.valueOf(0.01),
"silver",
BigDecimal.valueOf(30.03)));
assertThat(updatedList.getCreationTimestamp())
.isEqualTo(jpaRule.getTxnClock().nowUtc());
assertThat(updatedList.getRevisionId()).isGreaterThan(firstRevisionId);
assertThat(updatedList.getCreationTimestamp())
.isEqualTo(jpaRule.getTxnClock().nowUtc());
});
}
@@ -115,8 +126,10 @@ public class PremiumListDaoTest {
assertThat(thrown).hasMessageThat().isEqualTo("Premium list 'testlist' already exists");
}
// TODO(b/147246613): Un-ignore this.
@Test
public void update_throwsWhenPremiumListDoesntExist() {
@Ignore
public void update_throwsWhenListDoesntExist() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,

View File

@@ -1,4 +1,4 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
// 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.
@@ -12,43 +12,35 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools.server;
package google.registry.schema.tld;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
import static google.registry.testing.JUnitBackports.assertThrows;
import google.registry.schema.tld.PremiumList;
import google.registry.model.transaction.JpaTestRules;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeJsonResponse;
import java.math.BigDecimal;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link CreateOrUpdatePremiumListAction}. */
/** Unit tests for {@link PremiumListUtils}. */
@RunWith(JUnit4.class)
public class CreateOrUpdatePremiumListActionTest {
public class PremiumListUtilsTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
private CreatePremiumListAction action;
private FakeJsonResponse response;
@Before
public void init() {
action = new CreatePremiumListAction();
response = new FakeJsonResponse();
action.response = response;
action.name = "testlist";
}
@Rule
public final JpaIntegrationTestRule jpaRule =
new JpaTestRules.Builder().buildIntegrationTestRule();
@Test
public void parseInputToPremiumList_works() {
action.inputData = "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,USD 10\n";
PremiumList premiumList = action.parseInputToPremiumList();
PremiumList premiumList =
parseToPremiumList("testlist", "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,USD 10\n");
assertThat(premiumList.getName()).isEqualTo("testlist");
assertThat(premiumList.getLabelsToPrices())
.containsExactly("foo", twoDigits(99.50), "bar", twoDigits(30), "baz", twoDigits(10));
@@ -56,9 +48,12 @@ public class CreateOrUpdatePremiumListActionTest {
@Test
public void parseInputToPremiumList_throwsOnInconsistentCurrencies() {
action.inputData = "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,JPY 990\n";
IllegalArgumentException thrown =
assertThrows(IllegalArgumentException.class, () -> action.parseInputToPremiumList());
assertThrows(
IllegalArgumentException.class,
() ->
parseToPremiumList(
"testlist", "foo,USD 99.50\n" + "bar,USD 30\n" + "baz,JPY 990\n"));
assertThat(thrown)
.hasMessageThat()
.isEqualTo("The Cloud SQL schema requires exactly one currency, but got: [JPY, USD]");

View File

@@ -15,13 +15,11 @@
package google.registry.schema.tmch;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.common.collect.ImmutableMap;
import google.registry.model.transaction.JpaTestRules;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.testing.FakeClock;
import javax.persistence.NoResultException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,7 +40,7 @@ public class ClaimsListDaoTest {
ClaimsList claimsList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsListDao.trySave(claimsList);
ClaimsList insertedClaimsList = ClaimsListDao.getCurrent();
ClaimsList insertedClaimsList = ClaimsListDao.getLatestRevision().get();
assertClaimsListEquals(claimsList, insertedClaimsList);
assertThat(insertedClaimsList.getCreationTimestamp()).isEqualTo(jpaRule.getTxnClock().nowUtc());
}
@@ -52,7 +50,7 @@ public class ClaimsListDaoTest {
ClaimsList claimsList =
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
ClaimsListDao.trySave(claimsList);
ClaimsList insertedClaimsList = ClaimsListDao.getCurrent();
ClaimsList insertedClaimsList = ClaimsListDao.getLatestRevision().get();
assertClaimsListEquals(claimsList, insertedClaimsList);
// Save ClaimsList with existing revisionId should fail because revisionId is the primary key.
ClaimsListDao.trySave(insertedClaimsList);
@@ -62,14 +60,14 @@ public class ClaimsListDaoTest {
public void trySave_claimsListWithNoEntries() {
ClaimsList claimsList = ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of());
ClaimsListDao.trySave(claimsList);
ClaimsList insertedClaimsList = ClaimsListDao.getCurrent();
ClaimsList insertedClaimsList = ClaimsListDao.getLatestRevision().get();
assertClaimsListEquals(claimsList, insertedClaimsList);
assertThat(insertedClaimsList.getLabelsToKeys()).isEmpty();
}
@Test
public void getCurrent_throwsNoResultExceptionIfTableIsEmpty() {
assertThrows(NoResultException.class, ClaimsListDao::getCurrent);
public void getCurrent_returnsEmptyListIfTableIsEmpty() {
assertThat(ClaimsListDao.getLatestRevision().isPresent()).isFalse();
}
@Test
@@ -80,7 +78,7 @@ public class ClaimsListDaoTest {
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label3", "key3", "label4", "key4"));
ClaimsListDao.trySave(oldClaimsList);
ClaimsListDao.trySave(newClaimsList);
assertClaimsListEquals(newClaimsList, ClaimsListDao.getCurrent());
assertClaimsListEquals(newClaimsList, ClaimsListDao.getLatestRevision().get());
}
private void assertClaimsListEquals(ClaimsList left, ClaimsList right) {

View File

@@ -16,9 +16,13 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.persistPremiumList;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.JUnitBackports.assertThrows;
import com.beust.jcommander.ParameterException;
import google.registry.model.registry.Registry;
import google.registry.model.registry.label.PremiumList;
import google.registry.testing.DeterministicStringGenerator;
import org.junit.Before;
import org.junit.Test;
@@ -91,7 +95,14 @@ public class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomain
}
@Test
public void testSuccess_premiumDomain() throws Exception {
public void testSuccess_premiumJpyDomain() throws Exception {
createTld("baar");
persistPremiumList("baar", "parajiumu,JPY 96083");
persistResource(
Registry.get("baar")
.asBuilder()
.setPremiumList(PremiumList.getUncached("baar").get())
.build());
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
@@ -99,10 +110,10 @@ public class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomain
"--techs=crr-tech",
"--period=3",
"--force_premiums",
"parajiumu.tld");
"parajiumu.baar");
eppVerifier.verifySent("domain_create_parajiumu_3yrs.xml");
assertInStdout(
"parajiumu.tld is premium at JPY 96083 per year; "
"parajiumu.baar is premium at JPY 96083 per year; "
+ "sending total cost for 3 year(s) of JPY 288249.");
}

View File

@@ -67,13 +67,7 @@ public class CreatePremiumListCommandTest<C extends CreatePremiumListCommand>
verifySentParams(
connection,
servletPath,
ImmutableMap.of(
"name",
"foo",
"inputData",
generateInputData(premiumTermsPath),
"alsoCloudSql",
"false"));
ImmutableMap.of("name", "foo", "inputData", generateInputData(premiumTermsPath)));
}
@Test
@@ -84,28 +78,7 @@ public class CreatePremiumListCommandTest<C extends CreatePremiumListCommand>
connection,
servletPath,
ImmutableMap.of(
"name",
"example_premium_terms",
"inputData",
generateInputData(premiumTermsPath),
"alsoCloudSql",
"false"));
}
@Test
public void testRun_alsoCloudSql() throws Exception {
runCommandForced("-i=" + premiumTermsPath, "-n=foo", "--also_cloud_sql");
assertInStdout("Successfully");
verifySentParams(
connection,
servletPath,
ImmutableMap.of(
"name",
"foo",
"inputData",
generateInputData(premiumTermsPath),
"alsoCloudSql",
"true"));
"name", "example_premium_terms", "inputData", generateInputData(premiumTermsPath)));
}
@Test

View File

@@ -57,13 +57,7 @@ public class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
verifySentParams(
connection,
servletPath,
ImmutableMap.of(
"name",
"foo",
"inputData",
generateInputData(premiumTermsPath),
"alsoCloudSql",
"false"));
ImmutableMap.of("name", "foo", "inputData", generateInputData(premiumTermsPath)));
}
@Test
@@ -74,11 +68,6 @@ public class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
connection,
servletPath,
ImmutableMap.of(
"name",
"example_premium_terms",
"inputData",
generateInputData(premiumTermsPath),
"alsoCloudSql",
"false"));
"name", "example_premium_terms", "inputData", generateInputData(premiumTermsPath)));
}
}

View File

@@ -24,6 +24,8 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
import google.registry.model.registry.Registry;
import google.registry.model.registry.label.PremiumList;
import google.registry.model.transaction.JpaTestRules;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeJsonResponse;
import org.joda.money.Money;
@@ -39,6 +41,10 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class CreatePremiumListActionTest {
@Rule
public final JpaIntegrationTestRule jpaRule =
new JpaTestRules.Builder().buildIntegrationTestRule();
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
CreatePremiumListAction action;
FakeJsonResponse response;

View File

@@ -17,14 +17,22 @@ package google.registry.tools.server;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.model.registry.label.PremiumListUtils.getPremiumPrice;
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.schema.tld.PremiumListUtils.parseToPremiumList;
import static google.registry.testing.DatastoreHelper.createTlds;
import static google.registry.testing.DatastoreHelper.loadPremiumListEntries;
import static google.registry.util.ResourceUtils.readResourceUtf8;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import google.registry.model.registry.Registry;
import google.registry.model.registry.label.PremiumList;
import google.registry.model.transaction.JpaTestRules;
import google.registry.model.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.schema.tld.PremiumListDao;
import google.registry.testing.AppEngineRule;
import google.registry.testing.DatastoreHelper;
import google.registry.testing.FakeJsonResponse;
import java.math.BigDecimal;
import org.joda.money.Money;
import org.junit.Before;
import org.junit.Rule;
@@ -38,10 +46,11 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class UpdatePremiumListActionTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
public final JpaIntegrationTestRule jpaRule =
new JpaTestRules.Builder().buildIntegrationTestRule();
UpdatePremiumListAction action;
FakeJsonResponse response;
@@ -75,6 +84,9 @@ public class UpdatePremiumListActionTest {
@Test
public void test_success() {
PremiumListDao.saveNew(
parseToPremiumList(
"foo", readResourceUtf8(DatastoreHelper.class, "default_premium_list_testdata.csv")));
action.name = "foo";
action.inputData = "rich,USD 75\nricher,USD 5000\npoor, USD 0.99";
action.run();
@@ -85,5 +97,19 @@ public class UpdatePremiumListActionTest {
assertThat(getPremiumPrice("richer", registry)).hasValue(Money.parse("USD 5000"));
assertThat(getPremiumPrice("poor", registry)).hasValue(Money.parse("USD 0.99"));
assertThat(getPremiumPrice("diamond", registry)).isEmpty();
jpaTm()
.transact(
() -> {
google.registry.schema.tld.PremiumList persistedList =
PremiumListDao.getLatestRevision("foo").get();
assertThat(persistedList.getLabelsToPrices())
.containsEntry("rich", new BigDecimal("75.00"));
assertThat(persistedList.getLabelsToPrices())
.containsEntry("richer", new BigDecimal("5000.00"));
assertThat(persistedList.getLabelsToPrices())
.containsEntry("poor", BigDecimal.valueOf(0.99));
assertThat(persistedList.getLabelsToPrices()).doesNotContainKey("diamond");
});
}
}

View File

@@ -10,4 +10,3 @@ palladium,USD 877
aluminum,USD 11
copper,USD 15
brass,USD 20
parajiumu,JPY 96083
1 rich USD 100
10 aluminum USD 11
11 copper USD 15
12 brass USD 20
parajiumu JPY 96083

View File

@@ -4,7 +4,7 @@
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>parajiumu.tld</domain:name>
<domain:name>parajiumu.baar</domain:name>
<domain:period unit="y">3</domain:period>
<domain:registrant>crr-admin</domain:registrant>
<domain:contact type="admin">crr-admin</domain:contact>

View File

@@ -7,6 +7,7 @@ uploaderMultithreadedUpload=
verboseTestOutput=false
flowDocsFile=
enableDependencyLocking=true
enableCrossReferencing=false
# Comma separated list of test patterns, if specified run only these.
testFilter=

View File

@@ -333,7 +333,7 @@ public class ProxyModule {
if (env == Environment.LOCAL) {
return Mode.SELF_SIGNED;
} else {
return Mode.P12_FILE;
return Mode.PEM_FILE;
}
}

View File

@@ -0,0 +1,61 @@
# To run the build locally, install cloud-build-local first.
# See: https://cloud.google.com/cloud-build/docs/build-debug-locally
# In the root of a nomulus source tree, run:
# cloud-build-local --config=cloudbuild-kythe.yaml --dryrun=false \
# --substitutions _KYTHE_VERSION=[kythe_version],COMMIT_HASH=[hash] .
# This will download kythe version ${kythe_version} (must be higher than
# v0.0.39 and build a ${hash}.kzip file for Kythe to enable cross referencing.
#
# To manually trigger a build on GCB, run:
# gcloud builds submit --config cloudbuild-kythe.yaml --substitutions \
# _KYTHE_VERSION[kythe_version] .
#
# To trigger a build automatically, follow the instructions below and add a trigger:
# https://cloud.google.com/cloud-build/docs/running-builds/automate-builds
steps:
# Download Kythe
- name: 'openjdk:11'
entrypoint: /bin/bash
args:
- -c
- |
wget -q \
https://github.com/kythe/kythe/releases/download/${_KYTHE_VERSION}/kythe-${_KYTHE_VERSION}.tar.gz
tar xvf kythe-${_KYTHE_VERSION}.tar.gz
rm kythe-${_KYTHE_VERSION}.tar.gz
mv kythe-${_KYTHE_VERSION} kythe
# Build Nomulus with the Kythe wrapper
- name: 'openjdk:11'
entrypoint: /bin/bash
args:
- -c
- |
export REAL_JAVAC=$(which javac)
export JAVAC_EXTRACTOR_JAR="$${PWD}/kythe/extractors/javac_extractor.jar"
export KYTHE_VNAMES="$${PWD}/vnames.json"
export KYTHE_ROOT_DIRECTORY="$${PWD}"
export KYTHE_OUTPUT_DIRECTORY="$${PWD}/kythe_output"
mkdir -p $${KYTHE_OUTPUT_DIRECTORY}
mkdir -p $${KYTHE_OUTPUT_DIRECTORY}/merged
./gradlew clean testClasses -x compileProdJS \
-Dno_werror=true -PenableCrossReferencing=true
# Merge kzip files
- name: 'openjdk:11'
entrypoint: /bin/bash
args:
- -c
- |
export KYTHE_OUTPUT_DIRECTORY="$${PWD}/kythe_output"
./kythe/tools/kzip merge \
--output $${KYTHE_OUTPUT_DIRECTORY}/merged/${COMMIT_SHA}.kzip \
$${KYTHE_OUTPUT_DIRECTORY}/*.kzip
artifacts:
objects:
location: 'gs://${PROJECT_ID}-codesearch'
paths:
- 'kythe_output/merged/${COMMIT_SHA}.kzip'
timeout: 3600s
options:
machineType: 'N1_HIGHCPU_8'

View File

@@ -29,7 +29,9 @@ public abstract class EmailMessage {
public abstract String body();
public abstract ImmutableList<InternetAddress> recipients();
public abstract InternetAddress from();
public abstract ImmutableList<InternetAddress> bccs();
public abstract Optional<MediaType> contentType();
public abstract Optional<Attachment> attachment();
@@ -55,11 +57,14 @@ public abstract class EmailMessage {
public abstract Builder setBody(String body);
public abstract Builder setRecipients(Collection<InternetAddress> recipients);
public abstract Builder setFrom(InternetAddress from);
public abstract Builder setBccs(Collection<InternetAddress> bccs);
public abstract Builder setContentType(MediaType contentType);
public abstract Builder setAttachment(Attachment attachment);
abstract ImmutableList.Builder<InternetAddress> recipientsBuilder();
abstract ImmutableList.Builder<InternetAddress> bccsBuilder();
public Builder addRecipient(InternetAddress value) {

25
vnames.json Normal file
View File

@@ -0,0 +1,25 @@
[
{
"pattern": "(build/[^/]+)/(.*)",
"vname": {
"corpus": "github.com/google/nomulus",
"path": "@2@",
"root": "@1@"
}
},
{
"pattern": ".*/.gradle/caches/(.*)",
"vname": {
"corpus": "github.com/google/nomulus",
"path": "@1@",
"root": ".gradle/caches"
}
},
{
"pattern": "(.*)",
"vname": {
"corpus": "github.com/google/nomulus",
"path": "@1@"
}
}
]