mirror of
https://github.com/google/nomulus
synced 2026-06-09 16:33:02 +00:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77f998ee4b | |||
| c93248ec10 | |||
| 3ac179aead | |||
| 92f2f3274e | |||
| 57975898d5 | |||
| 86fefa9a03 | |||
| d143cc83a0 | |||
| df5f450435 | |||
| 89a44f176c | |||
| d2319b13fa | |||
| 77259f368d | |||
| 27b81ba898 | |||
| c7478fc52b | |||
| a68b1a12fd | |||
| ce791e8b97 | |||
| cf3f9603f7 | |||
| 4fd32c8b5c | |||
| 3488f95990 | |||
| 8e00f85f60 | |||
| 3cc8d83396 | |||
| 0a779612f6 | |||
| 545a03618b | |||
| bcdacc88d3 | |||
| 56b10ea136 | |||
| 9479e1e8b9 | |||
| 110bd9c057 | |||
| 2ae5aba7ff | |||
| b878e5acc1 | |||
| 4d0409c924 | |||
| 0292887cb9 | |||
| 464f6ba90a | |||
| 0ab0a8c2e6 | |||
| 2cc4e5fa94 | |||
| 47a890253e | |||
| b452b0628d | |||
| 5dfd96d26d | |||
| e2a673d914 | |||
| bf29d159f9 | |||
| e17cb52bf7 | |||
| 7352f9b4a6 | |||
| 5da48184f9 | |||
| 5bd2ccd210 | |||
| 8fd5ab2bec | |||
| 30f6113b05 | |||
| bd48041961 | |||
| 39ceda628c | |||
| 0e9b75e5e9 | |||
| c1207464d8 | |||
| 62eab98921 | |||
| 633dd887f4 | |||
| 650f1fdd52 | |||
| b0f6a498fd | |||
| 77590dcd8e | |||
| 29e4d8de05 | |||
| 242a560f20 | |||
| 3903abd9de | |||
| 8371cb838c | |||
| 8dd6797614 | |||
| 730f108e13 | |||
| e5bafddd2f | |||
| 82f51accbd | |||
| 6536631857 | |||
| 1be92968bf | |||
| 0564b207f2 | |||
| 8afc4f4d3d | |||
| 888bc158fe |
@@ -4,3 +4,6 @@ python/
|
||||
.*/
|
||||
repos/**
|
||||
**/.idea/
|
||||
*.jar
|
||||
!third_party/**/*.jar
|
||||
!/gradle/wrapper/**/*.jar
|
||||
|
||||
@@ -100,3 +100,9 @@ nomulus.iws
|
||||
node_modules/**
|
||||
!node_modules/soyutils_usegoog.js
|
||||
/repos/
|
||||
|
||||
# Compiled JS/CSS code
|
||||
core/**/registrar_bin*.js
|
||||
core/**/registrar_dbg*.js
|
||||
core/**/registrar_bin*.css
|
||||
core/**/registrar_dbg*.css
|
||||
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
# Copyright 2018 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.
|
||||
#
|
||||
# Collecting report files from a travis build to GCS requires setting the
|
||||
# "CREDZ" and "REPORT_GCS_BUCKET" environment variables in your travis
|
||||
# repository.
|
||||
#
|
||||
# The report destination can be any GCS path (e.g. "gcs://bucket-name/path").
|
||||
# You'll want to select "Display value in build log", otherwise travis will
|
||||
# hide the bucket name in the URL that is displayed.
|
||||
#
|
||||
# The CREDZ variable should be the contents of a json credentials file for
|
||||
# a service account with write access to the bucket, escaped for bash shell
|
||||
# usage (usually just wrapping it in single quotes should suffice).
|
||||
|
||||
language: java
|
||||
jdk:
|
||||
# Our builds fail against Oracle Java for reasons yet unknown.
|
||||
- openjdk8
|
||||
|
||||
# Caching options suggested by a random article.
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -f $HOME/.gradle/caches/*/plugin-resolution/
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
- $HOME/google-cloud-sdk/
|
||||
|
||||
# WebDriver tests need Chrome and ChromeDriver provisioned by the docker image
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
# Disable fancy status information (looks bad on travis and exceeds logfile
|
||||
# quota)
|
||||
- TERM=dumb
|
||||
# Do not prompt for user input when using any SDK methods.
|
||||
- CLOUDSDK_CORE_DISABLE_PROMPTS=1
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -d $HOME/google-cloud-sdk/bin ]
|
||||
then
|
||||
# The install script errors if this directory already exists,
|
||||
# but Travis already creates it when we mark it as cached.
|
||||
rm -rf $HOME/google-cloud-sdk
|
||||
# The install script is overly verbose, which sometimes causes
|
||||
# problems on Travis, so ignore stdout.
|
||||
curl https://sdk.cloud.google.com | bash
|
||||
fi
|
||||
# This line is critical. We setup the SDK to take precedence in our
|
||||
# environment over the old SDK that is already on the machine.
|
||||
- source $HOME/google-cloud-sdk/path.bash.inc
|
||||
- gcloud components install app-engine-java
|
||||
- gcloud version
|
||||
|
||||
# Specialize gradle build to use an up-to-date gradle and the /gradle
|
||||
# directory.
|
||||
# The "travis_wait 45" lets our build spend up to 45 minutes without writing
|
||||
# output, instead of the default 10.
|
||||
# See notes on the CREDZ and REPORT_GCS_BUCKET environment variable in the
|
||||
# comments at the top of the file.
|
||||
script: echo "$CREDZ" >credz.json && chmod 755 ./gradlew && travis_wait 45 ./gradlew build --continue -P uploaderDestination="$REPORT_GCS_DESTINATION" -P uploaderCredentialsFile=credz.json -P uploaderMultithreadedUpload=yes -P mavenUrl=https://storage.googleapis.com/domain-registry-maven-repository/maven -P pluginsUrl=https://storage.googleapis.com/domain-registry-maven-repository/plugins
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Nomulus
|
||||
|
||||
| Internal Build | FOSS Build | License | Code Search |
|
||||
|----------------|------------|---------|-------------|
|
||||
|[](https://storage.googleapis.com/domain-registry-kokoro/index.html)|[](https://travis-ci.org/google/nomulus)|[](https://github.com/jianglai/nomulus/blob/master/LICENSE)|[](https://sourcegraph.com/github.com/google/nomulus)|
|
||||
| Internal Build | FOSS Build | LGTM | License | Code Search |
|
||||
|----------------|------------|------|---------|-------------|
|
||||
|[](https://storage.googleapis.com/domain-registry-kokoro/internal/index.html)|[](https://storage.googleapis.com/domain-registry-kokoro/foss/index.html)|[](https://lgtm.com/projects/g/google/nomulus/alerts/)|[](https://github.com/google/nomulus/blob/master/LICENSE)|[](https://sourcegraph.com/github.com/google/nomulus)|
|
||||
|
||||

|
||||
|
||||
|
||||
+13
-20
@@ -12,25 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
def environments = ['production', 'sandbox', 'alpha', 'crash']
|
||||
|
||||
def projects = ['production': 'domain-registry',
|
||||
'sandbox' : 'domain-registry-sandbox',
|
||||
'alpha' : 'domain-registry-alpha',
|
||||
'crash' : 'domain-registry-crash']
|
||||
|
||||
|
||||
def environment = rootProject.findProperty("environment")
|
||||
if (environment == null) {
|
||||
environment = 'production'
|
||||
}
|
||||
def gcpProject = projects[environment]
|
||||
if (gcpProject == null) {
|
||||
throw new GradleException("-Penvironment must be one of ${environments}.")
|
||||
}
|
||||
|
||||
apply from: "${rootDir.path}/projects.gradle"
|
||||
apply plugin: 'war'
|
||||
|
||||
def environment = rootProject.environment
|
||||
def gcpProject = rootProject.gcpProject
|
||||
|
||||
// Set this directory before applying the appengine plugin so that the
|
||||
// plugin will recognize this as an app-engine standard app (and also
|
||||
// obtains the appengine-web.xml from the correct location)
|
||||
@@ -75,7 +62,13 @@ if (project.path == ":services:default") {
|
||||
|
||||
appengine {
|
||||
deploy {
|
||||
project = gcpProject
|
||||
// appengineDeployAll task requires the version to be set. So,
|
||||
// this config lets gcloud select a version name when deploying
|
||||
// to alpha or sandbox from our workstation.
|
||||
if (!rootProject.prodOrSandboxEnv) {
|
||||
version = 'GCLOUD_CONFIG'
|
||||
}
|
||||
projectId = gcpProject
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +76,6 @@ dependencies {
|
||||
compile project(':core')
|
||||
}
|
||||
|
||||
rootProject.deploy.dependsOn appengineDeploy
|
||||
rootProject.deploy.dependsOn appengineDeployAll
|
||||
rootProject.stage.dependsOn appengineStage
|
||||
appengineDeploy.dependsOn rootProject.verifyDeployment
|
||||
appengineDeployAll.dependsOn rootProject.verifyDeployment
|
||||
|
||||
+76
-12
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
buildscript {
|
||||
if (project.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
resolutionStrategy.activateDependencyLocking()
|
||||
@@ -21,7 +21,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.3.3'
|
||||
classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.0.1'
|
||||
classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.6.1"
|
||||
classpath 'org.sonatype.aether:aether-api:1.13.1'
|
||||
classpath 'org.sonatype.aether:aether-impl:1.13.1'
|
||||
@@ -44,6 +44,12 @@ plugins {
|
||||
|
||||
id 'idea'
|
||||
id 'com.diffplug.gradle.spotless' version '3.18.0'
|
||||
|
||||
id 'jacoco'
|
||||
}
|
||||
|
||||
wrapper {
|
||||
distributionType = Wrapper.DistributionType.ALL
|
||||
}
|
||||
|
||||
apply plugin: google.registry.gradle.plugin.ReportUploaderPlugin
|
||||
@@ -71,6 +77,19 @@ reportUploader {
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
apply from: 'dependency_lic.gradle'
|
||||
|
||||
// Custom task to run checkLicense in buildSrc, which is not triggered
|
||||
// by root project tasks. A shell task is used because buildSrc tasks
|
||||
// cannot be referenced in the same way as tasks from a regular included
|
||||
// build.
|
||||
task checkBuildSrcLicense(type:Exec) {
|
||||
workingDir "${rootDir}/buildSrc"
|
||||
commandLine '../gradlew', 'checkLicense'
|
||||
}
|
||||
tasks.checkLicense.dependsOn(tasks.checkBuildSrcLicense)
|
||||
tasks.build.dependsOn(tasks.checkLicense)
|
||||
|
||||
// Provide defaults for all of the project properties.
|
||||
|
||||
// showAllOutput: boolean. If true, dump all test output during the build.
|
||||
@@ -92,10 +111,10 @@ task deploy {
|
||||
|
||||
task verifyDeployment {
|
||||
group = 'deployment'
|
||||
description = 'Ensure that one can only deploy to alpha.'
|
||||
description = 'Ensure that one cannot deploy to production or sandbox.'
|
||||
doFirst {
|
||||
if (rootProject.findProperty("environment") != 'alpha') {
|
||||
throw new GradleException("Can only deploy to alpha.");
|
||||
if (rootProject.prodOrSandboxEnv) {
|
||||
throw new GradleException("Cannot deploy to production or sandbox.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,16 +171,17 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
buildscript {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
resolutionStrategy.activateDependencyLocking()
|
||||
}
|
||||
}
|
||||
// Lock application dependencies.
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
// Lock application dependencies except for the gradle-license-report
|
||||
// plugin. See dependency_lic.gradle for more information.
|
||||
configurations.findAll { it.name != 'dependencyLicenseReport' }.each {
|
||||
it.resolutionStrategy.activateDependencyLocking()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,9 +238,7 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
if (project.name == 'util') return
|
||||
if (project.name == 'proxy') return
|
||||
if (project.name == 'core') return
|
||||
if (['util', 'proxy', 'core', 'prober'].contains(project.name)) return
|
||||
|
||||
test {
|
||||
testLogging.showStandardStreams = Boolean.parseBoolean(showAllOutput)
|
||||
@@ -237,3 +255,49 @@ subprojects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task checkDependenciesDotGradle {
|
||||
def buildSrcDepsFile = File.createTempFile('buildSrc', 'deps')
|
||||
buildSrcDepsFile.deleteOnExit()
|
||||
dependsOn createGetBuildSrcDirectDepsTask(buildSrcDepsFile)
|
||||
|
||||
doLast {
|
||||
Set<String> depsInUse = []
|
||||
allprojects {
|
||||
configurations.all {
|
||||
it.dependencies.findAll { it.group != null }.each {
|
||||
// Note: .toString() is required since GString should
|
||||
// not be mixed with Java Strings.
|
||||
depsInUse.add("${it.group}:${it.name}".toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buildSrcDepsFile.exists()) {
|
||||
depsInUse.addAll(buildSrcDepsFile.readLines())
|
||||
}
|
||||
def unusedDeps =
|
||||
rootProject.dependencyMap.keySet()
|
||||
.findAll { !depsInUse.contains(it) }
|
||||
.toSorted()
|
||||
|
||||
if (unusedDeps.isEmpty()) {
|
||||
return
|
||||
}
|
||||
logger.error(
|
||||
"Unused dependencies in dependencies.gradle:\n${unusedDeps.toListString()}")
|
||||
throw new IllegalStateException(
|
||||
"The dependencies.gradle file should only contain direct dependencies.")
|
||||
}
|
||||
}
|
||||
tasks.build.dependsOn(tasks.checkDependenciesDotGradle)
|
||||
|
||||
def createGetBuildSrcDirectDepsTask(outputFileName) {
|
||||
return tasks
|
||||
.create(
|
||||
"getBuildSrcDeps_${java.util.UUID.randomUUID()}".toString(),
|
||||
Exec) {
|
||||
workingDir "${rootDir}/buildSrc"
|
||||
commandLine '../gradlew', 'exportDenpendencies',
|
||||
"-PdependencyExportFile=${outputFileName}"
|
||||
}
|
||||
}
|
||||
|
||||
+21
-2
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
buildscript {
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (project.enableDependencyLocking.toBoolean()) {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
resolutionStrategy.activateDependencyLocking()
|
||||
@@ -32,7 +32,7 @@ plugins {
|
||||
id 'com.diffplug.gradle.spotless' version '3.18.0'
|
||||
}
|
||||
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
// Lock application dependencies.
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
@@ -52,6 +52,7 @@ repositories {
|
||||
}
|
||||
|
||||
apply from: '../dependencies.gradle'
|
||||
apply from: '../dependency_lic.gradle'
|
||||
apply from: '../java_common.gradle'
|
||||
|
||||
sourceSets {
|
||||
@@ -88,3 +89,21 @@ gradle.projectsEvaluated {
|
||||
options.compilerArgs << "-Xlint:unchecked"
|
||||
}
|
||||
}
|
||||
|
||||
task exportDenpendencies {
|
||||
def outputFileProperty = 'dependencyExportFile'
|
||||
def output = project.hasProperty(outputFileProperty)
|
||||
? new PrintStream(
|
||||
new File(project.getProperty(outputFileProperty)))
|
||||
: System.out
|
||||
|
||||
doLast {
|
||||
project.configurations.all {
|
||||
it.dependencies.findAll {
|
||||
it.group != null
|
||||
}.each {
|
||||
output.println("${it.group}:${it.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
disableDependencyLocking=false
|
||||
enableDependencyLocking=false
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"allowedLicenses": [
|
||||
{
|
||||
"moduleLicense": "Apache Software License, Version 1.1"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache 2"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache-2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache License 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache License v2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Apache Software License - Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The Apache License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The Apache Software License, Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The Apache Software License, version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Bouncy Castle Licence"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 2-Clause License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 2-Clause license"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 3-clause"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 3-Clause"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 3-Clause License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD 3-clause New License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The 3-Clause BSD License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD New License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD New license"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "BSD style"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "New BSD License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Revised BSD"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The BSD License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "CC0 1.0 Universal License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "CDDL 1.1"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "CDDL + GPLv2 with classpath exception"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "https://glassfish.java.net/public/CDDL+GPL_1_1.html, https://glassfish.java.net/public/CDDL+GPL_1_1.html"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "CDDL+GPL License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "\\n Dual license consisting of the CDDL v1.1 and GPL v2\\n "
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Eclipse Public License - Version 1.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Eclipse Public License - v 1.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Eclipse Public License 1.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Eclipse Public License v1.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Google App Engine Terms of Service"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GNU General Public License, version 2, with the Classpath Exception"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GNU GENERAL PUBLIC LICENSE, Version 2 + Classpath Exception"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GNU Library General Public License v2.1 or later"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GPL2 w/ CPE"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GNU Lesser Public License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The Go license"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "GWT Terms"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "ICU License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The JSON License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "LGPL-2.1+"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "LGPL, version 2.1"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "MIT"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "MIT License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "MIT license"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The MIT License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The MIT license"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The PostgreSQL License"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Mozilla Public License Version 2.0"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "Public Domain"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "PUBLIC DOMAIN"
|
||||
},
|
||||
{
|
||||
"moduleLicense": "The W3C Software License"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"bundles" : [
|
||||
{
|
||||
"bundleName" : "Apache 2.0",
|
||||
"licenseName" : "Apache 2.0",
|
||||
"licenseUrl" : "http://www.apache.org/licenses/LICENSE-2.0"
|
||||
},
|
||||
{
|
||||
"bundleName" : "MIT License",
|
||||
"licenseName" : "MIT License",
|
||||
"licenseUrl" : "http://www.opensource.org/licenses/mit-license.php"
|
||||
}
|
||||
],
|
||||
"transformationRules" : [
|
||||
{
|
||||
"bundleName" : "Apache 2.0",
|
||||
"licenseUrlPattern" : "http://www.apache.org/licenses/LICENSE-2.0"
|
||||
},
|
||||
{
|
||||
"bundleName" : "Apache 2.0",
|
||||
"licenseUrlPattern" : "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
{
|
||||
"bundleName" : "MIT License",
|
||||
"licenseUrlPattern" : "http://www.opensource.org/licenses/mit-license.php"
|
||||
},
|
||||
{
|
||||
"bundleName" : "MIT License",
|
||||
"licenseUrlPattern" : "http://www.opensource.org/licenses/MIT"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -78,10 +78,15 @@ PRESUBMITS = {
|
||||
r".*Copyright 20\d{2} The Nomulus Authors\. All Rights Reserved\.",
|
||||
("java", "js", "soy", "sql", "py", "sh", "gradle"), {
|
||||
".git", "/build/", "/generated/", "node_modules/",
|
||||
"JUnitBackports.java"
|
||||
"JUnitBackports.java", "registrar_bin.", "registrar_dbg."
|
||||
}, REQUIRED):
|
||||
"File did not include the license header.",
|
||||
|
||||
# Files must end in a newline
|
||||
PresubmitCheck(r".*\n$", ("java", "js", "soy", "sql", "py", "sh", "gradle"),
|
||||
{"node_modules/"}, REQUIRED):
|
||||
"Source files must end in a newline.",
|
||||
|
||||
# System.(out|err).println should only appear in tools/
|
||||
PresubmitCheck(
|
||||
r".*\bSystem\.(out|err)\.print", "java", {
|
||||
@@ -143,7 +148,7 @@ PRESUBMITS = {
|
||||
PresubmitCheck(
|
||||
r".*(innerHTML|outerHTML)\s*(=|[+]=)([^=]|$)",
|
||||
"js",
|
||||
{"/node_modules/"},
|
||||
{"/node_modules/", "registrar_bin."},
|
||||
):
|
||||
"Do not assign directly to the dom. Use goog.dom.setTextContent to set"
|
||||
" to plain text, goog.dom.removeChildren to clear, or "
|
||||
@@ -151,14 +156,13 @@ PRESUBMITS = {
|
||||
PresubmitCheck(
|
||||
r".*console\.(log|info|warn|error)",
|
||||
"js",
|
||||
{"/node_modules/", "google/registry/ui/js/util.js"},
|
||||
{"/node_modules/", "google/registry/ui/js/util.js", "registrar_bin."},
|
||||
):
|
||||
"JavaScript files should not include console logging."
|
||||
}
|
||||
|
||||
|
||||
def get_files():
|
||||
result = []
|
||||
for root, dirnames, filenames in os.walk("."):
|
||||
for filename in filenames:
|
||||
yield os.path.join(root, filename)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM gcr.io/distroless/java:debug
|
||||
ADD build/libs/nomulus.jar /nomulus.jar
|
||||
ENTRYPOINT ["/usr/bin/java", "-jar", "/nomulus.jar"]
|
||||
+31
-69
@@ -25,6 +25,7 @@ def screenshotsForGoldensDir = "${project.buildDir}/screenshots_for_goldens"
|
||||
def newGoldensDir = "${project.buildDir}/new_golden_images"
|
||||
def goldensDir =
|
||||
"${javaTestDir}/google/registry/webdriver/goldens/chrome-linux"
|
||||
def jsDir = "${project.projectDir}/src/main/javascript"
|
||||
|
||||
// Tests that conflict with (mostly unidentified) members of the main test
|
||||
// suite. It is unclear if they are offenders (i.e., those that pollute global
|
||||
@@ -96,14 +97,14 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
|
||||
processTestResources {
|
||||
exclude '**/webdriver/*'
|
||||
}
|
||||
|
||||
configurations {
|
||||
css
|
||||
jaxb
|
||||
soy
|
||||
// Label for all dependencies inherited from Bazel build but not used in
|
||||
// either compile or testRuntime. However, they may be needed at runtime.
|
||||
// TODO(weiminyu): identify runtime dependencies and remove the rest.
|
||||
maybeRuntime
|
||||
closureCompiler
|
||||
|
||||
// Exclude non-canonical servlet-api jars. Our AppEngine deployment uses
|
||||
@@ -139,53 +140,38 @@ dependencies {
|
||||
"${rootDir}/third_party/objectify/v4_1/objectify-4.1.3.jar")
|
||||
testImplementation project(':third_party')
|
||||
|
||||
testRuntime files(sourceSets.test.resources.srcDirs)
|
||||
|
||||
compile deps['com.beust:jcommander']
|
||||
compile deps['com.google.api-client:google-api-client']
|
||||
maybeRuntime deps['com.google.api-client:google-api-client-appengine']
|
||||
maybeRuntime deps['com.google.api-client:google-api-client-jackson2']
|
||||
compile deps['com.google.monitoring-client:metrics']
|
||||
compile deps['com.google.monitoring-client:stackdriver']
|
||||
compile deps['com.google.api-client:google-api-client-java6']
|
||||
maybeRuntime deps['com.google.api-client:google-api-client-servlet']
|
||||
compile deps['com.google.apis:google-api-services-admin-directory']
|
||||
compile deps['com.google.apis:google-api-services-appengine']
|
||||
compile deps['com.google.apis:google-api-services-bigquery']
|
||||
maybeRuntime deps['com.google.apis:google-api-services-clouddebugger']
|
||||
compile deps['com.google.apis:google-api-services-cloudkms']
|
||||
maybeRuntime deps['com.google.apis:google-api-services-cloudresourcemanager']
|
||||
compile deps['com.google.apis:google-api-services-dataflow']
|
||||
compile deps['com.google.apis:google-api-services-dns']
|
||||
compile deps['com.google.apis:google-api-services-drive']
|
||||
compile deps['com.google.apis:google-api-services-groupssettings']
|
||||
compile deps['com.google.apis:google-api-services-monitoring']
|
||||
compile deps['com.google.apis:google-api-services-sheets']
|
||||
maybeRuntime deps['com.google.apis:google-api-services-storage']
|
||||
testCompileOnly deps['com.google.appengine:appengine-api-1.0-sdk']
|
||||
maybeRuntime deps['com.google.appengine:appengine-api-labs']
|
||||
maybeRuntime deps['com.google.appengine:appengine-api-stubs']
|
||||
testCompile deps['com.google.appengine:appengine-api-stubs']
|
||||
compile deps['com.google.appengine.tools:appengine-gcs-client']
|
||||
compile deps['com.google.appengine.tools:appengine-mapreduce']
|
||||
compile deps['com.google.appengine.tools:appengine-pipeline']
|
||||
compile deps['com.google.appengine:appengine-remote-api']
|
||||
maybeRuntime deps['com.google.appengine:appengine-tools-sdk']
|
||||
compile deps['com.google.auth:google-auth-library-credentials']
|
||||
compile deps['com.google.auth:google-auth-library-oauth2-http']
|
||||
maybeRuntime deps['com.google.auto:auto-common']
|
||||
maybeRuntime deps['com.google.auto.factory:auto-factory']
|
||||
compile deps['com.google.code.gson:gson']
|
||||
compile deps['com.google.auto.value:auto-value-annotations']
|
||||
maybeRuntime deps['com.google.cloud.bigdataoss:gcsio']
|
||||
maybeRuntime deps['com.google.cloud.bigdataoss:util']
|
||||
compile deps['com.google.code.findbugs:jsr305']
|
||||
compile deps['com.google.dagger:dagger']
|
||||
maybeRuntime deps['com.google.dagger:dagger-producers']
|
||||
compile deps['com.google.errorprone:error_prone_annotations']
|
||||
maybeRuntime deps['com.google.errorprone:javac-shaded']
|
||||
compile deps['com.google.flogger:flogger']
|
||||
runtime deps['com.google.flogger:flogger-system-backend']
|
||||
maybeRuntime deps['com.google.gdata:core']
|
||||
maybeRuntime deps['com.google.googlejavaformat:google-java-format']
|
||||
compile deps['com.google.guava:guava']
|
||||
gradleLint.ignore('unused-dependency') {
|
||||
compile deps['com.google.gwt:gwt-user']
|
||||
@@ -194,89 +180,48 @@ dependencies {
|
||||
compile deps['com.google.http-client:google-http-client-appengine']
|
||||
compile deps['com.google.http-client:google-http-client-jackson2']
|
||||
compile deps['com.google.oauth-client:google-oauth-client']
|
||||
maybeRuntime deps['com.google.oauth-client:google-oauth-client-appengine']
|
||||
compile deps['com.google.oauth-client:google-oauth-client-java6']
|
||||
compile deps['com.google.oauth-client:google-oauth-client-jetty']
|
||||
maybeRuntime deps['com.google.oauth-client:google-oauth-client-servlet']
|
||||
maybeRuntime deps['com.google.protobuf:protobuf-java']
|
||||
compile deps['com.google.re2j:re2j']
|
||||
compile deps['com.google.template:soy']
|
||||
maybeRuntime deps['com.googlecode.charts4j:charts4j']
|
||||
compile deps['com.googlecode.json-simple:json-simple']
|
||||
compile deps['com.jcraft:jsch']
|
||||
maybeRuntime deps['com.jcraft:jzlib']
|
||||
maybeRuntime deps['com.squareup:javapoet']
|
||||
maybeRuntime deps['com.squareup:javawriter']
|
||||
maybeRuntime deps['com.sun.activation:javax.activation']
|
||||
maybeRuntime deps['com.thoughtworks.paranamer:paranamer']
|
||||
testCompile deps['com.thoughtworks.qdox:qdox']
|
||||
maybeRuntime deps['commons-codec:commons-codec']
|
||||
maybeRuntime deps['commons-logging:commons-logging']
|
||||
compile deps['dnsjava:dnsjava']
|
||||
maybeRuntime deps['io.netty:netty-buffer']
|
||||
maybeRuntime deps['io.netty:netty-codec']
|
||||
maybeRuntime deps['io.netty:netty-codec-http']
|
||||
maybeRuntime deps['io.netty:netty-common']
|
||||
maybeRuntime deps['io.netty:netty-handler']
|
||||
maybeRuntime deps['io.netty:netty-resolver']
|
||||
maybeRuntime deps['io.netty:netty-tcnative']
|
||||
maybeRuntime deps['io.netty:netty-tcnative-boringssl-static']
|
||||
maybeRuntime deps['io.netty:netty-transport']
|
||||
maybeRuntime deps['it.unimi.dsi:fastutil']
|
||||
maybeRuntime deps['javax.annotation:jsr250-api']
|
||||
runtime deps['org.glassfish.jaxb:jaxb-runtime']
|
||||
testCompile deps['javax.annotation:jsr250-api']
|
||||
compile deps['javax.inject:javax.inject']
|
||||
compile deps['javax.mail:mail']
|
||||
compile deps['javax.servlet:servlet-api']
|
||||
compile deps['javax.xml.bind:jaxb-api']
|
||||
maybeRuntime deps['javax.xml.soap:javax.xml.soap-api']
|
||||
compile deps['jline:jline']
|
||||
compile deps['joda-time:joda-time']
|
||||
compile deps['org.apache.avro:avro']
|
||||
maybeRuntime deps['org.apache.beam:beam-runners-direct-java']
|
||||
testCompile deps['org.apache.beam:beam-runners-direct-java']
|
||||
compile deps['org.apache.beam:beam-runners-google-cloud-dataflow-java']
|
||||
maybeRuntime deps['org.apache.beam:beam-sdks-common-runner-api']
|
||||
compile deps['org.apache.beam:beam-sdks-java-core']
|
||||
compile deps['org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core']
|
||||
compile deps['org.apache.beam:beam-sdks-java-io-google-cloud-platform']
|
||||
maybeRuntime deps['org.apache.commons:commons-compress']
|
||||
testCompile deps['org.apache.commons:commons-text']
|
||||
maybeRuntime deps['org.apache.ftpserver:ftplet-api']
|
||||
testCompile deps['org.apache.ftpserver:ftplet-api']
|
||||
maybeRuntime deps['org.apache.ftpserver:ftpserver-core']
|
||||
testCompile deps['org.apache.ftpserver:ftpserver-core']
|
||||
compile deps['org.apache.httpcomponents:httpclient']
|
||||
compile deps['org.apache.httpcomponents:httpcore']
|
||||
maybeRuntime deps['org.apache.mina:mina-core']
|
||||
maybeRuntime deps['org.apache.sshd:sshd-core']
|
||||
testCompile deps['org.apache.sshd:sshd-core']
|
||||
maybeRuntime deps['org.apache.sshd:sshd-scp']
|
||||
testCompile deps['org.apache.sshd:sshd-scp']
|
||||
maybeRuntime deps['org.apache.sshd:sshd-sftp']
|
||||
testCompile deps['org.apache.sshd:sshd-sftp']
|
||||
maybeRuntime deps['org.apache.tomcat:tomcat-annotations-api']
|
||||
testCompile deps['org.apache.tomcat:tomcat-annotations-api']
|
||||
compile deps['org.bouncycastle:bcpg-jdk15on']
|
||||
testCompile deps['org.bouncycastle:bcpkix-jdk15on']
|
||||
compile deps['org.bouncycastle:bcprov-jdk15on']
|
||||
maybeRuntime deps['org.codehaus.jackson:jackson-core-asl']
|
||||
maybeRuntime deps['org.codehaus.jackson:jackson-mapper-asl']
|
||||
compile deps['org.joda:joda-money']
|
||||
compile deps['org.json:json']
|
||||
maybeRuntime deps['org.khronos:opengl-api']
|
||||
maybeRuntime deps['org.mortbay.jetty:jetty']
|
||||
testCompile deps['org.mortbay.jetty:jetty']
|
||||
maybeRuntime deps['org.mortbay.jetty:jetty-util']
|
||||
testCompile deps['org.seleniumhq.selenium:selenium-api']
|
||||
testCompile deps['org.seleniumhq.selenium:selenium-chrome-driver']
|
||||
testCompile deps['org.seleniumhq.selenium:selenium-java']
|
||||
testCompile deps['org.seleniumhq.selenium:selenium-remote-driver']
|
||||
maybeRuntime deps['org.slf4j:slf4j-api']
|
||||
testCompile deps['org.testcontainers:selenium']
|
||||
maybeRuntime deps['org.tukaani:xz']
|
||||
maybeRuntime deps['org.xerial.snappy:snappy-java']
|
||||
compile deps['xerces:xmlParserAPIs']
|
||||
compile deps['xpp3:xpp3']
|
||||
|
||||
@@ -302,8 +247,10 @@ dependencies {
|
||||
testCompile deps['org.hamcrest:hamcrest-all']
|
||||
testCompile deps['org.hamcrest:hamcrest-core']
|
||||
testCompile deps['org.hamcrest:hamcrest-library']
|
||||
compile deps['org.hibernate:hibernate-core']
|
||||
testCompile deps['junit:junit']
|
||||
testCompile deps['org.mockito:mockito-core']
|
||||
runtime deps['org.postgresql:postgresql']
|
||||
|
||||
// Indirect dependency found by undeclared-dependency check. Such
|
||||
// dependencies should go after all other compile and testCompile
|
||||
@@ -480,7 +427,7 @@ task soyToJS {
|
||||
}
|
||||
|
||||
task stylesheetsToJavascript {
|
||||
def cssSourceDir = "${javaDir}/google/registry/ui/css"
|
||||
def cssSourceDir = "${jsDir}/google/registry/ui/css"
|
||||
def outputDir = "${resourcesDir}/google/registry/ui/css"
|
||||
inputs.dir cssSourceDir
|
||||
outputs.dir outputDir
|
||||
@@ -533,8 +480,8 @@ task compileProdJS(type: JavaExec) {
|
||||
def outputDir = "${resourcesDir}/google/registry/ui"
|
||||
def nodeModulesDir = "${rootDir}/node_modules"
|
||||
def cssSourceDir = "${resourcesDir}/google/registry/ui/css"
|
||||
def jsSourceDir = "${javaDir}/google/registry/ui/js"
|
||||
def externsDir = "${javaDir}/google/registry/ui/externs"
|
||||
def jsSourceDir = "${jsDir}/google/registry/ui/js"
|
||||
def externsDir = "${jsDir}/google/registry/ui/externs"
|
||||
def soySourceDir = "${generatedDir}/google/registry/ui/soy"
|
||||
|
||||
[nodeModulesDir, cssSourceDir, jsSourceDir, externsDir, soySourceDir].each {
|
||||
@@ -700,10 +647,25 @@ test {
|
||||
}.dependsOn(fragileTest, outcastTest)
|
||||
|
||||
createUberJar('nomulus', 'nomulus', 'google.registry.tools.RegistryTool')
|
||||
createUberJar('gtechTool', 'gtech_tool', 'google.registry.tools.GtechTool')
|
||||
project.nomulus.dependsOn project(':third_party').jar
|
||||
project.gtechTool.dependsOn project(':third_party').jar
|
||||
|
||||
project.build.dependsOn nomulus
|
||||
project.build.dependsOn gtechTool
|
||||
task buildToolImage(dependsOn: nomulus, type: Exec) {
|
||||
commandLine 'docker', 'build', '-t', 'nomulus-tool', '.'
|
||||
}
|
||||
|
||||
task copyJsFilesForTestServer(dependsOn: assemble, type: Copy) {
|
||||
// Unfortunately the test server relies on having some compiled JS/CSS
|
||||
// in place, so copy it over here
|
||||
from "${resourcesDir}/google/registry/ui/"
|
||||
include '**/*.js'
|
||||
include '**/*.css'
|
||||
into "${project.projectDir}/src/main/resources/google/registry/ui/"
|
||||
}
|
||||
|
||||
task runTestServer(dependsOn: copyJsFilesForTestServer, type: JavaExec) {
|
||||
main = 'google.registry.server.RegistryTestServerMain'
|
||||
classpath = sourceSets.test.runtimeClasspath
|
||||
}
|
||||
|
||||
project.build.dependsOn buildToolImage
|
||||
project.build.dependsOn ':stage'
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;
|
||||
import static google.registry.backup.ExportCommitLogDiffAction.LOWER_CHECKPOINT_TIME_PARAM;
|
||||
import static google.registry.backup.ExportCommitLogDiffAction.UPPER_CHECKPOINT_TIME_PARAM;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
@@ -63,7 +64,7 @@ public final class CommitLogCheckpointAction implements Runnable {
|
||||
final CommitLogCheckpoint checkpoint = strategy.computeCheckpoint();
|
||||
logger.atInfo().log(
|
||||
"Generated candidate checkpoint for time: %s", checkpoint.getCheckpointTime());
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
DateTime lastWrittenTime = CommitLogCheckpointRoot.loadRoot().getLastWrittenTime();
|
||||
|
||||
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.mapreduce.MapreduceRunner.PARAM_DRY_RUN;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
@@ -276,7 +277,7 @@ public final class DeleteOldCommitLogsAction implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
DeletionResult deletionResult = ofy().transactNew(() -> {
|
||||
DeletionResult deletionResult = tm().transactNew(() -> {
|
||||
CommitLogManifest manifest = ofy().load().key(manifestKey).now();
|
||||
// It is possible that the same manifestKey was run twice, if a shard had to be restarted
|
||||
// or some weird failure. If this happens, we want to exit immediately.
|
||||
|
||||
@@ -39,6 +39,7 @@ import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.CONTACT_DELETE_FAILURE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.HOST_DELETE_FAILURE;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.model.transfer.TransferStatus.SERVER_CANCELLED;
|
||||
import static java.math.RoundingMode.CEILING;
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
@@ -308,7 +309,7 @@ public class DeleteContactsAndHostsAction implements Runnable {
|
||||
final boolean hasNoActiveReferences = !Iterators.contains(values, true);
|
||||
logger.atInfo().log("Processing async deletion request for %s", deletionRequest.key());
|
||||
DeletionResult result =
|
||||
ofy()
|
||||
tm()
|
||||
.transactNew(
|
||||
() -> {
|
||||
DeletionResult deletionResult =
|
||||
@@ -329,7 +330,7 @@ public class DeleteContactsAndHostsAction implements Runnable {
|
||||
|
||||
private DeletionResult attemptToDeleteResource(
|
||||
DeletionRequest deletionRequest, boolean hasNoActiveReferences) {
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
EppResource resource =
|
||||
ofy().load().key(deletionRequest.key()).now().cloneProjectedAtTime(now);
|
||||
// Double-check transactionally that the resource is still active and in PENDING_DELETE.
|
||||
|
||||
@@ -19,6 +19,7 @@ import static google.registry.config.RegistryEnvironment.PRODUCTION;
|
||||
import static google.registry.mapreduce.MapreduceRunner.PARAM_DRY_RUN;
|
||||
import static google.registry.mapreduce.inputs.EppResourceInputs.createEntityInput;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
|
||||
import com.google.appengine.tools.mapreduce.Mapper;
|
||||
@@ -124,7 +125,7 @@ public class DeleteLoadTestDataAction implements Runnable {
|
||||
Key.create(EppResourceIndex.create(Key.create(resource)));
|
||||
final Key<? extends ForeignKeyIndex<?>> fki = ForeignKeyIndex.createKey(resource);
|
||||
int numEntitiesDeleted =
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
// This ancestor query selects all descendant entities.
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.model.ResourceTransferUtils.updateForeignKeyIndexD
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registries.getTldsOfType;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_DELETE;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.request.RequestParameters.PARAM_TLDS;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
@@ -219,7 +220,7 @@ public class DeleteProberDataAction implements Runnable {
|
||||
final Key<? extends ForeignKeyIndex<?>> fki = ForeignKeyIndex.createKey(domain);
|
||||
|
||||
int entitiesDeleted =
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
// This ancestor query selects all descendant HistoryEntries, BillingEvents,
|
||||
@@ -245,16 +246,16 @@ public class DeleteProberDataAction implements Runnable {
|
||||
}
|
||||
|
||||
private void softDeleteDomain(final DomainBase domain) {
|
||||
ofy().transactNew(() -> {
|
||||
tm().transactNew(() -> {
|
||||
DomainBase deletedDomain = domain
|
||||
.asBuilder()
|
||||
.setDeletionTime(ofy().getTransactionTime())
|
||||
.setDeletionTime(tm().getTransactionTime())
|
||||
.setStatusValues(null)
|
||||
.build();
|
||||
HistoryEntry historyEntry = new HistoryEntry.Builder()
|
||||
.setParent(domain)
|
||||
.setType(DOMAIN_DELETE)
|
||||
.setModificationTime(ofy().getTransactionTime())
|
||||
.setModificationTime(tm().getTransactionTime())
|
||||
.setBySuperuser(true)
|
||||
.setReason("Deletion of prober data")
|
||||
.setClientId(registryAdminClientId)
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.model.common.Cursor.CursorType.RECURRING_BILLING;
|
||||
import static google.registry.model.domain.Period.Unit.YEARS;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_AUTORENEW;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
@@ -150,7 +151,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||
}
|
||||
int numBillingEventsSaved = 0;
|
||||
try {
|
||||
numBillingEventsSaved = ofy().transactNew(() -> {
|
||||
numBillingEventsSaved = tm().transactNew(() -> {
|
||||
ImmutableSet.Builder<OneTime> syntheticOneTimesBuilder =
|
||||
new ImmutableSet.Builder<>();
|
||||
final Registry tld = Registry.get(getTldFromDomainName(recurring.getTargetId()));
|
||||
@@ -183,7 +184,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||
HistoryEntry historyEntry = new HistoryEntry.Builder()
|
||||
.setBySuperuser(false)
|
||||
.setClientId(recurring.getClientId())
|
||||
.setModificationTime(ofy().getTransactionTime())
|
||||
.setModificationTime(tm().getTransactionTime())
|
||||
.setParent(domainKey)
|
||||
.setPeriod(Period.create(1, YEARS))
|
||||
.setReason("Domain autorenewal by ExpandRecurringBillingEventsAction")
|
||||
@@ -308,7 +309,7 @@ public class ExpandRecurringBillingEventsAction implements Runnable {
|
||||
logger.atInfo().log(
|
||||
"Recurring event expansion %s complete for billing event range [%s, %s).",
|
||||
isDryRun ? "(dry run) " : "", cursorTime, executionTime);
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
Cursor cursor = ofy().load().key(Cursor.createGlobalKey(RECURRING_BILLING)).now();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.batch;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.appengine.tools.mapreduce.Mapper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -69,7 +70,7 @@ public class ResaveAllEppResourcesAction implements Runnable {
|
||||
|
||||
@Override
|
||||
public final void map(final Key<EppResource> resourceKey) {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
EppResource projectedResource =
|
||||
@@ -77,7 +78,7 @@ public class ResaveAllEppResourcesAction implements Runnable {
|
||||
.load()
|
||||
.key(resourceKey)
|
||||
.now()
|
||||
.cloneProjectedAtTime(ofy().getTransactionTime());
|
||||
.cloneProjectedAtTime(tm().getTransactionTime());
|
||||
ofy().save().entity(projectedResource).now();
|
||||
});
|
||||
getContext().incrementCounter(String.format("%s entities re-saved", resourceKey.getKind()));
|
||||
|
||||
@@ -18,6 +18,7 @@ import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES;
|
||||
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
@@ -73,11 +74,11 @@ public class ResaveEntityAction implements Runnable {
|
||||
public void run() {
|
||||
logger.atInfo().log(
|
||||
"Re-saving entity %s which was enqueued at %s.", resourceKey, requestedTime);
|
||||
ofy().transact(() -> {
|
||||
tm().transact(() -> {
|
||||
ImmutableObject entity = ofy().load().key(resourceKey).now();
|
||||
ofy().save().entity(
|
||||
(entity instanceof EppResource)
|
||||
? ((EppResource) entity).cloneProjectedAtTime(ofy().getTransactionTime()) : entity
|
||||
? ((EppResource) entity).cloneProjectedAtTime(tm().getTransactionTime()) : entity
|
||||
);
|
||||
if (!resaveTimes.isEmpty()) {
|
||||
asyncTaskEnqueuer.enqueueAsyncResave(entity, requestedTime, resaveTimes);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.beam.invoicing;
|
||||
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey;
|
||||
import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder;
|
||||
import google.registry.config.CredentialModule.LocalCredential;
|
||||
@@ -57,35 +58,31 @@ import org.apache.beam.sdk.values.TypeDescriptors;
|
||||
*/
|
||||
public class InvoicingPipeline implements Serializable {
|
||||
|
||||
@Inject
|
||||
@Config("projectId")
|
||||
String projectId;
|
||||
private final String projectId;
|
||||
private final String beamBucketUrl;
|
||||
private final String invoiceTemplateUrl;
|
||||
private final String beamStagingUrl;
|
||||
private final String billingBucketUrl;
|
||||
private final String invoiceFilePrefix;
|
||||
private final GoogleCredentials googleCredentials;
|
||||
|
||||
@Inject
|
||||
@Config("apacheBeamBucketUrl")
|
||||
String beamBucketUrl;
|
||||
|
||||
@Inject
|
||||
@Config("invoiceTemplateUrl")
|
||||
String invoiceTemplateUrl;
|
||||
|
||||
@Inject
|
||||
@Config("beamStagingUrl")
|
||||
String beamStagingUrl;
|
||||
|
||||
@Inject
|
||||
@Config("billingBucketUrl")
|
||||
String billingBucketUrl;
|
||||
|
||||
@Inject
|
||||
@Config("invoiceFilePrefix")
|
||||
String invoiceFilePrefix;
|
||||
|
||||
@Inject @LocalCredential
|
||||
GoogleCredentialsBundle credentialsBundle;
|
||||
|
||||
@Inject
|
||||
InvoicingPipeline() {}
|
||||
public InvoicingPipeline(
|
||||
@Config("projectId") String projectId,
|
||||
@Config("apacheBeamBucketUrl") String beamBucketUrl,
|
||||
@Config("invoiceTemplateUrl") String invoiceTemplateUrl,
|
||||
@Config("beamStagingUrl") String beamStagingUrl,
|
||||
@Config("billingBucketUrl") String billingBucketUrl,
|
||||
@Config("invoiceFilePrefix") String invoiceFilePrefix,
|
||||
@LocalCredential GoogleCredentialsBundle googleCredentialsBundle) {
|
||||
this.projectId = projectId;
|
||||
this.beamBucketUrl = beamBucketUrl;
|
||||
this.invoiceTemplateUrl = invoiceTemplateUrl;
|
||||
this.beamStagingUrl = beamStagingUrl;
|
||||
this.billingBucketUrl = billingBucketUrl;
|
||||
this.invoiceFilePrefix = invoiceFilePrefix;
|
||||
this.googleCredentials = googleCredentialsBundle.getGoogleCredentials();
|
||||
}
|
||||
|
||||
/** Custom options for running the invoicing pipeline. */
|
||||
interface InvoicingPipelineOptions extends DataflowPipelineOptions {
|
||||
@@ -105,12 +102,15 @@ public class InvoicingPipeline implements Serializable {
|
||||
public void deploy() {
|
||||
// We can't store options as a member variable due to serialization concerns.
|
||||
InvoicingPipelineOptions options = PipelineOptionsFactory.as(InvoicingPipelineOptions.class);
|
||||
options.setGcpCredential(credentialsBundle.getGoogleCredentials());
|
||||
options.setProject(projectId);
|
||||
options.setRunner(DataflowRunner.class);
|
||||
// This causes p.run() to stage the pipeline as a template on GCS, as opposed to running it.
|
||||
options.setTemplateLocation(invoiceTemplateUrl);
|
||||
options.setStagingLocation(beamStagingUrl);
|
||||
// This credential is used when Dataflow deploys the template to GCS in target GCP project.
|
||||
// So, make sure the credential has write permission to GCS in that project.
|
||||
options.setGcpCredential(googleCredentials);
|
||||
|
||||
Pipeline p = Pipeline.create(options);
|
||||
|
||||
PCollection<BillingEvent> billingEvents =
|
||||
|
||||
@@ -17,9 +17,12 @@ package google.registry.beam.spec11;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.beam.BeamUtils.getQueryFromFile;
|
||||
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import google.registry.beam.spec11.SafeBrowsingTransforms.EvaluateSafeBrowsingFn;
|
||||
import google.registry.config.CredentialModule.LocalCredential;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.util.GoogleCredentialsBundle;
|
||||
import google.registry.util.Retrier;
|
||||
import google.registry.util.SqlTemplate;
|
||||
import java.io.Serializable;
|
||||
@@ -77,26 +80,29 @@ public class Spec11Pipeline implements Serializable {
|
||||
/** The JSON object field we put the threat match array for Spec11 reports. */
|
||||
public static final String THREAT_MATCHES_FIELD = "threatMatches";
|
||||
|
||||
@Inject
|
||||
@Config("projectId")
|
||||
String projectId;
|
||||
private final String projectId;
|
||||
private final String beamStagingUrl;
|
||||
private final String spec11TemplateUrl;
|
||||
private final String reportingBucketUrl;
|
||||
private final GoogleCredentials googleCredentials;
|
||||
private final Retrier retrier;
|
||||
|
||||
@Inject
|
||||
@Config("beamStagingUrl")
|
||||
String beamStagingUrl;
|
||||
|
||||
@Inject
|
||||
@Config("spec11TemplateUrl")
|
||||
String spec11TemplateUrl;
|
||||
|
||||
@Inject
|
||||
@Config("reportingBucketUrl")
|
||||
String reportingBucketUrl;
|
||||
|
||||
@Inject Retrier retrier;
|
||||
|
||||
@Inject
|
||||
Spec11Pipeline() {}
|
||||
public Spec11Pipeline(
|
||||
@Config("projectId") String projectId,
|
||||
@Config("beamStagingUrl") String beamStagingUrl,
|
||||
@Config("spec11TemplateUrl") String spec11TemplateUrl,
|
||||
@Config("reportingBucketUrl") String reportingBucketUrl,
|
||||
@LocalCredential GoogleCredentialsBundle googleCredentialsBundle,
|
||||
Retrier retrier
|
||||
) {
|
||||
this.projectId = projectId;
|
||||
this.beamStagingUrl = beamStagingUrl;
|
||||
this.spec11TemplateUrl = spec11TemplateUrl;
|
||||
this.reportingBucketUrl = reportingBucketUrl;
|
||||
this.googleCredentials = googleCredentialsBundle.getGoogleCredentials();
|
||||
this.retrier = retrier;
|
||||
}
|
||||
|
||||
/** Custom options for running the spec11 pipeline. */
|
||||
interface Spec11PipelineOptions extends DataflowPipelineOptions {
|
||||
@@ -134,6 +140,9 @@ public class Spec11Pipeline implements Serializable {
|
||||
// This causes p.run() to stage the pipeline as a template on GCS, as opposed to running it.
|
||||
options.setTemplateLocation(spec11TemplateUrl);
|
||||
options.setStagingLocation(beamStagingUrl);
|
||||
// This credential is used when Dataflow deploys the template to GCS in target GCP project.
|
||||
// So, make sure the credential has write permission to GCS in that project.
|
||||
options.setGcpCredential(googleCredentials);
|
||||
|
||||
Pipeline p = Pipeline.create(options);
|
||||
PCollection<Subdomain> domains =
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.config;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import dagger.Module;
|
||||
@@ -68,6 +69,29 @@ public abstract class CredentialModule {
|
||||
return GoogleCredentialsBundle.create(credential);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the default {@link GoogleCredential} from the Google Cloud runtime for G Suite
|
||||
* Drive API.
|
||||
* TODO(b/138195359): Deprecate this credential once we figure out how to use
|
||||
* {@link GoogleCredentials} for G Suite Drive API.
|
||||
*/
|
||||
@GSuiteDriveCredential
|
||||
@Provides
|
||||
@Singleton
|
||||
public static GoogleCredential provideGSuiteDriveCredential(
|
||||
@Config("defaultCredentialOauthScopes") ImmutableList<String> requiredScopes) {
|
||||
GoogleCredential credential;
|
||||
try {
|
||||
credential = GoogleCredential.getApplicationDefault();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (credential.createScopedRequired()) {
|
||||
credential = credential.createScoped(requiredScopes);
|
||||
}
|
||||
return credential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a {@link GoogleCredentialsBundle} from the service account's JSON key file.
|
||||
*
|
||||
@@ -118,6 +142,13 @@ public abstract class CredentialModule {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultCredential {}
|
||||
|
||||
|
||||
/** Dagger qualifier for the credential for G Suite Drive API. */
|
||||
@Qualifier
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GSuiteDriveCredential {}
|
||||
|
||||
/**
|
||||
* Dagger qualifier for a credential from a service account's JSON key, to be used in non-request
|
||||
* threads.
|
||||
|
||||
@@ -894,9 +894,9 @@ public final class RegistryConfig {
|
||||
* @see google.registry.reporting.spec11.Spec11EmailUtils
|
||||
*/
|
||||
@Provides
|
||||
@Config("spec11ReplyToEmailAddress")
|
||||
public static InternetAddress provideSpec11ReplyToEmailAddress(RegistryConfigSettings config) {
|
||||
return parseEmailAddress(config.misc.spec11ReplyToEmailAddress);
|
||||
@Config("spec11OutgoingEmailAddress")
|
||||
public static InternetAddress provideSpec11OutgoingEmailAddress(RegistryConfigSettings config) {
|
||||
return parseEmailAddress(config.misc.spec11OutgoingEmailAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -173,7 +173,7 @@ public class RegistryConfigSettings {
|
||||
public static class Misc {
|
||||
public String sheetExportId;
|
||||
public String alertRecipientEmailAddress;
|
||||
public String spec11ReplyToEmailAddress;
|
||||
public String spec11OutgoingEmailAddress;
|
||||
public int asyncDeleteDelaySeconds;
|
||||
public int transientFailureRetries;
|
||||
}
|
||||
|
||||
@@ -357,9 +357,9 @@ misc:
|
||||
# Address we send alert summary emails to.
|
||||
alertRecipientEmailAddress: email@example.com
|
||||
|
||||
# Address to which the Spec 11 emails to registrars should be replied. This needs
|
||||
# to be a deliverable email address in case the registrars want to contact us.
|
||||
spec11ReplyToEmailAddress: reply-to@example.com
|
||||
# Address from which Spec 11 emails to registrars are sent. This needs
|
||||
# to be a deliverable email address to handle replies from registrars as well.
|
||||
spec11OutgoingEmailAddress: abuse@example.com
|
||||
|
||||
# How long to delay processing of asynchronous deletions. This should always
|
||||
# be longer than eppResourceCachingSeconds, to prevent deleted contacts or
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/metrics</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- RDE -->
|
||||
|
||||
<!--
|
||||
|
||||
@@ -112,8 +112,6 @@
|
||||
<target>backend</target>
|
||||
</cron>
|
||||
|
||||
<!--
|
||||
TODO(b/134576418) enable this cron job once we're sure the Action works
|
||||
<cron>
|
||||
<url><![CDATA[/_dr/task/updateRegistrarRdapBaseUrls]]></url>
|
||||
<description>
|
||||
@@ -122,7 +120,6 @@
|
||||
<schedule>every day 02:34</schedule>
|
||||
<target>backend</target>
|
||||
</cron>
|
||||
-->
|
||||
|
||||
<cron>
|
||||
<url><![CDATA[/_dr/task/deleteOldCommitLogs]]></url>
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
|
||||
package google.registry.export;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.api.services.drive.Drive;
|
||||
import dagger.Component;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.config.CredentialModule;
|
||||
import google.registry.config.CredentialModule.DefaultCredential;
|
||||
import google.registry.config.CredentialModule.GSuiteDriveCredential;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.storage.drive.DriveConnection;
|
||||
import google.registry.util.GoogleCredentialsBundle;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/** Dagger module for Google {@link Drive} service connection objects. */
|
||||
@@ -32,13 +32,13 @@ public final class DriveModule {
|
||||
|
||||
@Provides
|
||||
static Drive provideDrive(
|
||||
@DefaultCredential GoogleCredentialsBundle credentialsBundle,
|
||||
@GSuiteDriveCredential GoogleCredential googleCredential,
|
||||
@Config("projectId") String projectId) {
|
||||
|
||||
return new Drive.Builder(
|
||||
credentialsBundle.getHttpTransport(),
|
||||
credentialsBundle.getJsonFactory(),
|
||||
credentialsBundle.getHttpRequestInitializer())
|
||||
googleCredential.getTransport(),
|
||||
googleCredential.getJsonFactory(),
|
||||
googleCredential)
|
||||
.setApplicationName(projectId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.export;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.RegistrarUtils.normalizeClientId;
|
||||
@@ -163,7 +164,7 @@ public final class SyncGroupMembersAction implements Runnable {
|
||||
registrarsToSave.add(result.getKey().asBuilder().setContactsRequireSyncing(false).build());
|
||||
}
|
||||
}
|
||||
ofy().transactNew(() -> ofy().save().entities(registrarsToSave.build()));
|
||||
tm().transactNew(() -> ofy().save().entities(registrarsToSave.build()));
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import static google.registry.model.registrar.RegistrarContact.Type.LEGAL;
|
||||
import static google.registry.model.registrar.RegistrarContact.Type.MARKETING;
|
||||
import static google.registry.model.registrar.RegistrarContact.Type.TECH;
|
||||
import static google.registry.model.registrar.RegistrarContact.Type.WHOIS;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -152,7 +153,7 @@ class SyncRegistrarsSheet {
|
||||
return builder.build();
|
||||
})
|
||||
.collect(toImmutableList()));
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> ofy().save().entity(Cursor.createGlobal(SYNC_REGISTRAR_SHEET, executionTime)));
|
||||
}
|
||||
|
||||
@@ -39,6 +39,13 @@ public class EppMetrics {
|
||||
LabelDescriptor.create("tld", "The TLD acted on by the command (if applicable)."),
|
||||
LabelDescriptor.create("status", "The return status of the command."));
|
||||
|
||||
private static final ImmutableSet<LabelDescriptor> LABEL_DESCRIPTORS =
|
||||
ImmutableSet.of(
|
||||
LabelDescriptor.create("command", "The name of the command."),
|
||||
LabelDescriptor.create("traffic_type",
|
||||
"The traffic type of the command; one of CANARY, PROBER, or REAL."),
|
||||
LabelDescriptor.create("status", "The return status of the command."));
|
||||
|
||||
private static final IncrementableMetric eppRequestsByRegistrar =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newIncrementableMetric(
|
||||
@@ -55,23 +62,18 @@ public class EppMetrics {
|
||||
"count",
|
||||
LABEL_DESCRIPTORS_BY_TLD);
|
||||
|
||||
private static final EventMetric processingTimeByRegistrar =
|
||||
private static final EventMetric requestTime =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newEventMetric(
|
||||
"/epp/processing_time",
|
||||
"EPP Processing Time By Registrar",
|
||||
"/epp/request_time",
|
||||
"EPP Request Time",
|
||||
"milliseconds",
|
||||
LABEL_DESCRIPTORS_BY_REGISTRAR,
|
||||
LABEL_DESCRIPTORS,
|
||||
DEFAULT_FITTER);
|
||||
|
||||
private static final EventMetric processingTimeByTld =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newEventMetric(
|
||||
"/epp/processing_time_by_tld",
|
||||
"EPP Processing Time By TLD",
|
||||
"milliseconds",
|
||||
LABEL_DESCRIPTORS_BY_TLD,
|
||||
DEFAULT_FITTER);
|
||||
private enum TrafficType {
|
||||
CANARY, PROBER, REAL
|
||||
}
|
||||
|
||||
@Inject
|
||||
public EppMetrics() {}
|
||||
@@ -97,15 +99,18 @@ public class EppMetrics {
|
||||
metric.getStatus().isPresent() ? String.valueOf(metric.getStatus().get().code) : "";
|
||||
long processingTime =
|
||||
metric.getEndTimestamp().getMillis() - metric.getStartTimestamp().getMillis();
|
||||
processingTimeByRegistrar.record(
|
||||
processingTime,
|
||||
metric.getCommandName().orElse(""),
|
||||
metric.getClientId().orElse(""),
|
||||
eppStatusCode);
|
||||
processingTimeByTld.record(
|
||||
processingTime,
|
||||
metric.getCommandName().orElse(""),
|
||||
metric.getTld().orElse(""),
|
||||
eppStatusCode);
|
||||
String commandName = metric.getCommandName().orElse("");
|
||||
String tld = metric.getTld().orElse("");
|
||||
requestTime.record(processingTime, commandName, getTrafficType(tld).toString(), eppStatusCode);
|
||||
}
|
||||
|
||||
private static TrafficType getTrafficType(String tld) {
|
||||
if (tld.endsWith("canary.test")) {
|
||||
return TrafficType.CANARY;
|
||||
} else if (tld.endsWith(".test")) {
|
||||
return TrafficType.PROBER;
|
||||
} else {
|
||||
return TrafficType.REAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.flows;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.xml.XmlTransformer.prettyPrint;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
@@ -80,7 +80,7 @@ public class FlowRunner {
|
||||
return eppOutput;
|
||||
}
|
||||
try {
|
||||
return ofy()
|
||||
return tm()
|
||||
.transact(
|
||||
() -> {
|
||||
try {
|
||||
|
||||
@@ -19,6 +19,7 @@ import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.model.EppResourceUtils.queryForLinkedDomains;
|
||||
import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -77,7 +78,7 @@ public final class ResourceFlowUtils {
|
||||
final Function<DomainBase, ImmutableSet<?>> getPotentialReferences) throws EppException {
|
||||
// Enter a transactionless context briefly.
|
||||
EppException failfastException =
|
||||
ofy()
|
||||
tm()
|
||||
.doTransactionless(
|
||||
() -> {
|
||||
final ForeignKeyIndex<R> fki =
|
||||
|
||||
@@ -20,6 +20,7 @@ import static google.registry.flows.contact.ContactFlowUtils.validateAsciiPostal
|
||||
import static google.registry.flows.contact.ContactFlowUtils.validateContactAgainstPolicy;
|
||||
import static google.registry.model.EppResourceUtils.createRepoId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
@@ -71,7 +72,7 @@ public final class ContactCreateFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
Create command = (Create) resourceCommand;
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
verifyResourceDoesNotExist(ContactResource.class, targetId, now, clientId);
|
||||
ContactResource newContact =
|
||||
new ContactResource.Builder()
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
|
||||
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
@@ -84,7 +85,7 @@ public final class ContactDeleteFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
failfastForAsyncDelete(targetId, now, ContactResource.class, DomainBase::getReferencedContacts);
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES);
|
||||
@@ -93,7 +94,7 @@ public final class ContactDeleteFlow implements TransactionalFlow {
|
||||
verifyResourceOwnership(clientId, existingContact);
|
||||
}
|
||||
asyncTaskEnqueuer.enqueueAsyncDelete(
|
||||
existingContact, ofy().getTransactionTime(), clientId, trid, isSuperuser);
|
||||
existingContact, tm().getTransactionTime(), clientId, trid, isSuperuser);
|
||||
ContactResource newContact =
|
||||
existingContact.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build();
|
||||
historyBuilder
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createGainingTransf
|
||||
import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse;
|
||||
import static google.registry.model.ResourceTransferUtils.approvePendingTransfer;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.flows.EppException;
|
||||
@@ -78,7 +79,7 @@ public final class ContactTransferApproveFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingContact);
|
||||
verifyHasPendingTransfer(existingContact);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createLosingTransfe
|
||||
import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse;
|
||||
import static google.registry.model.ResourceTransferUtils.denyPendingTransfer;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.flows.EppException;
|
||||
@@ -74,7 +75,7 @@ public final class ContactTransferCancelFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingContact);
|
||||
verifyHasPendingTransfer(existingContact);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createGainingTransf
|
||||
import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse;
|
||||
import static google.registry.model.ResourceTransferUtils.denyPendingTransfer;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.flows.EppException;
|
||||
@@ -72,7 +73,7 @@ public final class ContactTransferRejectFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingContact);
|
||||
verifyHasPendingTransfer(existingContact);
|
||||
|
||||
@@ -24,6 +24,7 @@ import static google.registry.flows.contact.ContactFlowUtils.createLosingTransfe
|
||||
import static google.registry.flows.contact.ContactFlowUtils.createTransferResponse;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
@@ -91,7 +92,7 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(gainingClientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyAuthInfoPresentForResourceTransfer(authInfo);
|
||||
verifyAuthInfo(authInfo.get(), existingContact);
|
||||
|
||||
@@ -25,6 +25,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
import static google.registry.flows.contact.ContactFlowUtils.validateAsciiPostalInfo;
|
||||
import static google.registry.flows.contact.ContactFlowUtils.validateContactAgainstPolicy;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
@@ -92,7 +93,7 @@ public final class ContactUpdateFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
Update command = (Update) resourceCommand;
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
ContactResource existingContact = loadAndVerifyExistence(ContactResource.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingContact);
|
||||
ImmutableSet<StatusValue> statusToRemove = command.getInnerRemove().getStatusValues();
|
||||
|
||||
@@ -42,11 +42,11 @@ import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActi
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||
import static google.registry.model.EppResourceUtils.createDomainRepoId;
|
||||
import static google.registry.model.eppcommon.StatusValue.SERVER_HOLD;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABILITY;
|
||||
import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
|
||||
import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE;
|
||||
import static google.registry.model.registry.label.ReservationType.NAME_COLLISION;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||
|
||||
@@ -221,7 +221,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
verifyRegistrarIsActive(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainCommand.Create command = cloneAndLinkReferences((Create) resourceCommand, now);
|
||||
Period period = command.getPeriod();
|
||||
verifyUnitIsYears(period);
|
||||
|
||||
@@ -34,6 +34,7 @@ import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PE
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.ADD_FIELDS;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.RENEW_FIELDS;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
@@ -140,7 +141,7 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
||||
flowCustomLogic.beforeValidation();
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
// Loads the target resource if it exists
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
Registry registry = Registry.get(existingDomain.getTld());
|
||||
|
||||
@@ -28,7 +28,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -137,7 +137,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
verifyRegistrarIsActive(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
Renew command = (Renew) resourceCommand;
|
||||
// Loads the target resource if it exists
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
|
||||
@@ -27,6 +27,7 @@ import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNo
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive;
|
||||
import static google.registry.model.ResourceTransferUtils.updateForeignKeyIndexDeletionTime;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -133,7 +134,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||
validateClientIsLoggedIn(clientId);
|
||||
verifyRegistrarIsActive(clientId);
|
||||
Update command = (Update) resourceCommand;
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
FeesAndCredits feesAndCredits =
|
||||
pricingLogic.getRestorePrice(Registry.get(existingDomain.getTld()), targetId, now);
|
||||
|
||||
@@ -29,6 +29,7 @@ import static google.registry.model.ResourceTransferUtils.approvePendingTransfer
|
||||
import static google.registry.model.domain.DomainBase.extendRegistrationWithCap;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.pricing.PricingEngineProxy.getDomainRenewCost;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
@@ -102,7 +103,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingDomain);
|
||||
verifyHasPendingTransfer(existingDomain);
|
||||
|
||||
@@ -27,6 +27,7 @@ import static google.registry.flows.domain.DomainTransferUtils.createTransferRes
|
||||
import static google.registry.model.ResourceTransferUtils.denyPendingTransfer;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -87,7 +88,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
verifyOptionalAuthInfo(authInfo, existingDomain);
|
||||
verifyHasPendingTransfer(existingDomain);
|
||||
|
||||
@@ -28,6 +28,7 @@ import static google.registry.model.ResourceTransferUtils.denyPendingTransfer;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_NACKED;
|
||||
import static google.registry.model.reporting.DomainTransactionRecord.TransactionReportField.TRANSFER_SUCCESSFUL;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
|
||||
@@ -89,7 +90,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
Registry registry = Registry.get(existingDomain.getTld());
|
||||
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now);
|
||||
|
||||
@@ -32,6 +32,7 @@ import static google.registry.flows.domain.DomainTransferUtils.createTransferSer
|
||||
import static google.registry.model.domain.DomainBase.extendRegistrationWithCap;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -143,7 +144,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(gainingClientId);
|
||||
verifyRegistrarIsActive(gainingClientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
Optional<DomainTransferRequestSuperuserExtension> superuserExtension =
|
||||
eppInput.getSingleExtension(DomainTransferRequestSuperuserExtension.class);
|
||||
|
||||
@@ -38,7 +38,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateRegistrantAll
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateRequiredContactsPresent;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClientUpdateNotProhibited;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.net.InternetDomainName;
|
||||
@@ -154,7 +154,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
|
||||
flowCustomLogic.beforeValidation();
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
Update command = cloneAndLinkReferences((Update) resourceCommand, now);
|
||||
DomainBase existingDomain = loadAndVerifyExistence(DomainBase.class, targetId, now);
|
||||
verifyUpdateAllowed(command, existingDomain, now);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomain
|
||||
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership;
|
||||
import static google.registry.model.EppResourceUtils.createRepoId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
|
||||
@@ -103,7 +104,7 @@ public final class HostCreateFlow implements TransactionalFlow {
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
Create command = (Create) resourceCommand;
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
verifyResourceDoesNotExist(HostResource.class, targetId, now, clientId);
|
||||
// The superordinate domain of the host object if creating an in-bailiwick host, or null if
|
||||
// creating an external host. This is looked up before we actually create the Host object so
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
import static google.registry.flows.host.HostFlowUtils.validateHostName;
|
||||
import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
@@ -85,7 +86,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
|
||||
extensionManager.register(MetadataExtension.class);
|
||||
extensionManager.validate();
|
||||
validateClientIsLoggedIn(clientId);
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
validateHostName(targetId);
|
||||
failfastForAsyncDelete(targetId, now, HostResource.class, DomainBase::getNameservers);
|
||||
HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now);
|
||||
@@ -101,7 +102,7 @@ public final class HostDeleteFlow implements TransactionalFlow {
|
||||
verifyResourceOwnership(clientId, owningResource);
|
||||
}
|
||||
asyncTaskEnqueuer.enqueueAsyncDelete(
|
||||
existingHost, ofy().getTransactionTime(), clientId, trid, isSuperuser);
|
||||
existingHost, tm().getTransactionTime(), clientId, trid, isSuperuser);
|
||||
HostResource newHost =
|
||||
existingHost.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build();
|
||||
historyBuilder
|
||||
|
||||
@@ -28,6 +28,7 @@ import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomain
|
||||
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership;
|
||||
import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.isNullOrEmpty;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -129,7 +130,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||
Update command = (Update) resourceCommand;
|
||||
Change change = command.getInnerChange();
|
||||
String suppliedNewHostName = change.getFullyQualifiedHostName();
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
validateHostName(targetId);
|
||||
HostResource existingHost = loadAndVerifyExistence(HostResource.class, targetId, now);
|
||||
boolean isHostRename = suppliedNewHostName != null;
|
||||
@@ -271,7 +272,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||
}
|
||||
// We must also enqueue updates for all domains that use this host as their nameserver so
|
||||
// that their NS records can be updated to point at the new name.
|
||||
asyncTaskEnqueuer.enqueueAsyncDnsRefresh(existingHost, ofy().getTransactionTime());
|
||||
asyncTaskEnqueuer.enqueueAsyncDnsRefresh(existingHost, tm().getTransactionTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_NO_MESSAG
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.poll.PollMessageExternalKeyConverter.makePollMessageExternalId;
|
||||
import static google.registry.model.poll.PollMessageExternalKeyConverter.parsePollMessageExternalId;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
|
||||
import com.googlecode.objectify.Key;
|
||||
@@ -78,7 +79,7 @@ public class PollAckFlow implements TransactionalFlow {
|
||||
throw new InvalidMessageIdException(messageId);
|
||||
}
|
||||
|
||||
final DateTime now = ofy().getTransactionTime();
|
||||
final DateTime now = tm().getTransactionTime();
|
||||
|
||||
// Load the message to be acked. If a message is queued to be delivered in the future, we treat
|
||||
// it as if it doesn't exist yet. Same for if the message ID year isn't the same as the actual
|
||||
@@ -124,7 +125,7 @@ public class PollAckFlow implements TransactionalFlow {
|
||||
// acked, then we return a special status code indicating that. Note that the query will
|
||||
// include the message being acked.
|
||||
|
||||
int messageCount = ofy().doTransactionless(() -> getPollMessagesQuery(clientId, now).count());
|
||||
int messageCount = tm().doTransactionless(() -> getPollMessagesQuery(clientId, now).count());
|
||||
if (!includeAckedMessageInCount) {
|
||||
messageCount--;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.RDE_SSH_CLIE
|
||||
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.RDE_SSH_CLIENT_PUBLIC_STRING;
|
||||
import static google.registry.keyring.kms.KmsKeyring.StringKeyLabel.SAFE_BROWSING_API_KEY;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -182,7 +183,7 @@ public final class KmsUpdater {
|
||||
*/
|
||||
private static void persistEncryptedValues(
|
||||
final ImmutableMap<String, EncryptResponse> encryptedValues) {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
for (Map.Entry<String, EncryptResponse> entry : encryptedValues.entrySet()) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.google.common.collect.Sets.union;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceCachingDuration;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
@@ -325,13 +326,13 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
|
||||
|
||||
@Override
|
||||
public EppResource load(Key<? extends EppResource> key) {
|
||||
return ofy().doTransactionless(() -> ofy().load().key(key).now());
|
||||
return tm().doTransactionless(() -> ofy().load().key(key).now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Key<? extends EppResource>, EppResource> loadAll(
|
||||
Iterable<? extends Key<? extends EppResource>> keys) {
|
||||
return ofy().doTransactionless(() -> loadMultiple(keys));
|
||||
return tm().doTransactionless(() -> loadMultiple(keys));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABILITY;
|
||||
import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -236,7 +237,7 @@ public final class OteAccountBuilder {
|
||||
*/
|
||||
public ImmutableMap<String, String> buildAndPersist() {
|
||||
// save all the entitiesl in a single transaction
|
||||
ofy().transact(this::saveAllEntities);
|
||||
tm().transact(this::saveAllEntities);
|
||||
return clientIdToTld;
|
||||
}
|
||||
|
||||
@@ -249,7 +250,7 @@ public final class OteAccountBuilder {
|
||||
|
||||
/** Saves all the OT&E entities we created. */
|
||||
private void saveAllEntities() {
|
||||
ofy().assertInTransaction();
|
||||
tm().assertInTransaction();
|
||||
|
||||
ImmutableList<Registry> registries = ImmutableList.of(sunriseTld, gaTld, eapTld);
|
||||
ImmutableList<RegistrarContact> contacts = contactsBuilder.build();
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.model.common;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.model.ofy.ObjectifyService.allocateId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.common.base.Splitter;
|
||||
@@ -55,13 +56,13 @@ public class GaeUserIdConverter extends ImmutableObject {
|
||||
try {
|
||||
// Perform these operations in a transactionless context to avoid enlisting in some outer
|
||||
// transaction (if any).
|
||||
ofy().doTransactionless(() -> ofy().saveWithoutBackup().entity(gaeUserIdConverter).now());
|
||||
tm().doTransactionless(() -> ofy().saveWithoutBackup().entity(gaeUserIdConverter).now());
|
||||
|
||||
// The read must be done in its own transaction to avoid reading from the session cache.
|
||||
return ofy()
|
||||
return tm()
|
||||
.transactNew(() -> ofy().load().entity(gaeUserIdConverter).safe().user.getUserId());
|
||||
} finally {
|
||||
ofy().doTransactionless(() -> ofy().deleteWithoutBackup().entity(gaeUserIdConverter).now());
|
||||
tm().doTransactionless(() -> ofy().deleteWithoutBackup().entity(gaeUserIdConverter).now());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import static google.registry.util.CollectionUtils.forceEmptyToNull;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.earliestOf;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||
@@ -376,10 +377,10 @@ public class DomainBase extends EppResource
|
||||
|
||||
Optional<DateTime> newLastEppUpdateTime = Optional.empty();
|
||||
|
||||
// There is no transfer. Do any necessary autorenews.
|
||||
// There is no transfer. Do any necessary autorenews for active domains.
|
||||
|
||||
Builder builder = asBuilder();
|
||||
if (isBeforeOrAt(registrationExpirationTime, now)) {
|
||||
if (isBeforeOrAt(registrationExpirationTime, now) && END_OF_TIME.equals(getDeletionTime())) {
|
||||
// Autorenew by the number of years between the old expiration time and now.
|
||||
DateTime lastAutorenewTime = leapSafeAddYears(
|
||||
registrationExpirationTime,
|
||||
|
||||
+2
-2
@@ -15,9 +15,9 @@
|
||||
package google.registry.model.domain.fee;
|
||||
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.domain.fee.FeeQueryCommandExtensionItem.CommandName;
|
||||
import java.util.Locale;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class FeeExtensionCommandDescriptor extends ImmutableObject {
|
||||
|
||||
public CommandName getCommand() {
|
||||
// Require the xml string to be lowercase.
|
||||
if (command != null && CharMatcher.javaLowerCase().matchesAllOf(command)) {
|
||||
if (command != null && command.toLowerCase(Locale.ENGLISH).equals(command)) {
|
||||
try {
|
||||
return CommandName.valueOf(Ascii.toUpperCase(command));
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
+2
-2
@@ -15,9 +15,9 @@
|
||||
package google.registry.model.domain.fee12;
|
||||
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.FeeCheckCommandExtensionItem;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
@@ -83,7 +83,7 @@ public class FeeCheckCommandExtensionItemV12 extends FeeCheckCommandExtensionIte
|
||||
@Override
|
||||
public CommandName getCommandName() {
|
||||
// Require the xml string to be lowercase.
|
||||
if (commandName != null && CharMatcher.javaLowerCase().matchesAllOf(commandName)) {
|
||||
if (commandName != null && commandName.toLowerCase(Locale.ENGLISH).equals(commandName)) {
|
||||
try {
|
||||
return CommandName.valueOf(Ascii.toUpperCase(commandName));
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.common.collect.Maps.filterValues;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceCachingDuration;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.TypeUtils.instantiate;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
@@ -188,7 +189,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
|
||||
|
||||
@Override
|
||||
public Optional<ForeignKeyIndex<?>> load(Key<ForeignKeyIndex<?>> key) {
|
||||
return Optional.ofNullable(ofy().doTransactionless(() -> ofy().load().key(key).now()));
|
||||
return Optional.ofNullable(tm().doTransactionless(() -> ofy().load().key(key).now()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +197,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
|
||||
Iterable<? extends Key<ForeignKeyIndex<?>>> keys) {
|
||||
ImmutableSet<Key<ForeignKeyIndex<?>>> typedKeys = ImmutableSet.copyOf(keys);
|
||||
Map<Key<ForeignKeyIndex<?>>, ForeignKeyIndex<?>> existingFkis =
|
||||
ofy().doTransactionless(() -> ofy().load().keys(typedKeys));
|
||||
tm().doTransactionless(() -> ofy().load().keys(typedKeys));
|
||||
// ofy() omits keys that don't have values in Datastore, so re-add them in
|
||||
// here with Optional.empty() values.
|
||||
return Maps.asMap(
|
||||
@@ -250,7 +251,7 @@ public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroup
|
||||
public static <E extends EppResource> Map<String, ForeignKeyIndex<E>> loadCached(
|
||||
Class<E> clazz, Iterable<String> foreignKeys, final DateTime now) {
|
||||
if (!RegistryConfig.isEppResourceCachingEnabled()) {
|
||||
return ofy().doTransactionless(() -> load(clazz, foreignKeys, now));
|
||||
return tm().doTransactionless(() -> load(clazz, foreignKeys, now));
|
||||
}
|
||||
ImmutableList<Key<ForeignKeyIndex<?>>> fkiKeys =
|
||||
Streams.stream(foreignKeys)
|
||||
|
||||
@@ -28,10 +28,9 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.VoidWork;
|
||||
import com.googlecode.objectify.Work;
|
||||
import google.registry.model.BackupGroupRoot;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.transaction.TransactionManager.Work;
|
||||
import google.registry.util.Clock;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -40,7 +39,7 @@ import java.util.Set;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Wrapper for {@link Work} that associates a time with each attempt. */
|
||||
class CommitLoggedWork<R> extends VoidWork {
|
||||
class CommitLoggedWork<R> implements Runnable {
|
||||
|
||||
private final Work<R> work;
|
||||
private final Clock clock;
|
||||
@@ -74,8 +73,8 @@ class CommitLoggedWork<R> extends VoidWork {
|
||||
*/
|
||||
protected ImmutableSet<ImmutableObject> mutations = ImmutableSet.of();
|
||||
|
||||
/** Lifecycle marker to track whether {@link #vrun} has been called. */
|
||||
private boolean vrunCalled;
|
||||
/** Lifecycle marker to track whether {@link #run} has been called. */
|
||||
private boolean runCalled;
|
||||
|
||||
CommitLoggedWork(Work<R> work, Clock clock) {
|
||||
this.work = work;
|
||||
@@ -87,26 +86,26 @@ class CommitLoggedWork<R> extends VoidWork {
|
||||
}
|
||||
|
||||
boolean hasRun() {
|
||||
return vrunCalled;
|
||||
return runCalled;
|
||||
}
|
||||
|
||||
R getResult() {
|
||||
checkState(vrunCalled, "Cannot call getResult() before vrun()");
|
||||
checkState(runCalled, "Cannot call getResult() before run()");
|
||||
return result;
|
||||
}
|
||||
|
||||
CommitLogManifest getManifest() {
|
||||
checkState(vrunCalled, "Cannot call getManifest() before vrun()");
|
||||
checkState(runCalled, "Cannot call getManifest() before run()");
|
||||
return manifest;
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableObject> getMutations() {
|
||||
checkState(vrunCalled, "Cannot call getMutations() before vrun()");
|
||||
checkState(runCalled, "Cannot call getMutations() before run()");
|
||||
return mutations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vrun() {
|
||||
public void run() {
|
||||
// The previous time will generally be null, except when using transactNew.
|
||||
TransactionInfo previous = Ofy.TRANSACTION_INFO.get();
|
||||
// Set the time to be used for "now" within the transaction.
|
||||
@@ -117,7 +116,7 @@ class CommitLoggedWork<R> extends VoidWork {
|
||||
} finally {
|
||||
Ofy.TRANSACTION_INFO.set(previous);
|
||||
}
|
||||
vrunCalled = true;
|
||||
runCalled = true;
|
||||
}
|
||||
|
||||
/** Records all mutations enrolled by this transaction to a {@link CommitLogManifest} entry. */
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// 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.model.ofy;
|
||||
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
|
||||
import google.registry.model.transaction.TransactionManager;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Datastore implementation of {@link TransactionManager}. */
|
||||
public class DatastoreTransactionManager implements TransactionManager {
|
||||
|
||||
private Ofy injectedOfy;
|
||||
|
||||
/** Constructs an instance. */
|
||||
public DatastoreTransactionManager(Ofy injectedOfy) {
|
||||
this.injectedOfy = injectedOfy;
|
||||
}
|
||||
|
||||
private Ofy getOfy() {
|
||||
return injectedOfy == null ? ofy() : injectedOfy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inTransaction() {
|
||||
return getOfy().inTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertInTransaction() {
|
||||
getOfy().assertInTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T transact(Work<T> work) {
|
||||
return getOfy().transact(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transact(Runnable work) {
|
||||
getOfy().transact(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T transactNew(Work<T> work) {
|
||||
return getOfy().transactNew(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transactNew(Runnable work) {
|
||||
getOfy().transactNew(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R transactNewReadOnly(Work<R> work) {
|
||||
return getOfy().transactNewReadOnly(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transactNewReadOnly(Runnable work) {
|
||||
getOfy().transactNewReadOnly(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R doTransactionless(Work<R> work) {
|
||||
return getOfy().doTransactionless(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime getTransactionTime() {
|
||||
return getOfy().getTransactionTime();
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,13 @@ import com.google.common.flogger.FluentLogger;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.Objectify;
|
||||
import com.googlecode.objectify.ObjectifyFactory;
|
||||
import com.googlecode.objectify.Work;
|
||||
import com.googlecode.objectify.cmd.Deleter;
|
||||
import com.googlecode.objectify.cmd.Loader;
|
||||
import com.googlecode.objectify.cmd.Saver;
|
||||
import google.registry.model.annotations.NotBackedUp;
|
||||
import google.registry.model.annotations.VirtualEntity;
|
||||
import google.registry.model.ofy.ReadOnlyWork.KillTransactionException;
|
||||
import google.registry.model.transaction.TransactionManager.Work;
|
||||
import google.registry.util.Clock;
|
||||
import google.registry.util.NonFinalForTesting;
|
||||
import google.registry.util.Sleeper;
|
||||
@@ -111,11 +111,11 @@ public class Ofy {
|
||||
ofy().clear();
|
||||
}
|
||||
|
||||
public boolean inTransaction() {
|
||||
boolean inTransaction() {
|
||||
return ofy().getTransaction() != null;
|
||||
}
|
||||
|
||||
public void assertInTransaction() {
|
||||
void assertInTransaction() {
|
||||
checkState(inTransaction(), "Must be called in a transaction");
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public class Ofy {
|
||||
}
|
||||
|
||||
/** Execute a transaction. */
|
||||
public <R> R transact(Work<R> work) {
|
||||
<R> R transact(Work<R> work) {
|
||||
// If we are already in a transaction, don't wrap in a CommitLoggedWork.
|
||||
return inTransaction() ? work.run() : transactNew(work);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public class Ofy {
|
||||
* <p>This overload is used for transactions that don't return a value, formerly implemented using
|
||||
* VoidWork.
|
||||
*/
|
||||
public void transact(Runnable work) {
|
||||
void transact(Runnable work) {
|
||||
transact(
|
||||
() -> {
|
||||
work.run();
|
||||
@@ -214,7 +214,7 @@ public class Ofy {
|
||||
}
|
||||
|
||||
/** Pause the current transaction (if any) and complete this one before returning to it. */
|
||||
public <R> R transactNew(Work<R> work) {
|
||||
<R> R transactNew(Work<R> work) {
|
||||
// Wrap the Work in a CommitLoggedWork so that we can give transactions a frozen view of time
|
||||
// and maintain commit logs for them.
|
||||
return transactCommitLoggedWork(new CommitLoggedWork<>(work, getClock()));
|
||||
@@ -226,7 +226,7 @@ public class Ofy {
|
||||
* <p>This overload is used for transactions that don't return a value, formerly implemented using
|
||||
* VoidWork.
|
||||
*/
|
||||
public void transactNew(Runnable work) {
|
||||
void transactNew(Runnable work) {
|
||||
transactNew(
|
||||
() -> {
|
||||
work.run();
|
||||
@@ -246,7 +246,10 @@ public class Ofy {
|
||||
true;
|
||||
attempt++, sleepMillis *= 2) {
|
||||
try {
|
||||
ofy().transactNew(work);
|
||||
ofy().transactNew(() -> {
|
||||
work.run();
|
||||
return null;
|
||||
});
|
||||
return work.getResult();
|
||||
} catch (TransientFailureException
|
||||
| TimestampInversionException
|
||||
@@ -295,10 +298,13 @@ public class Ofy {
|
||||
}
|
||||
|
||||
/** A read-only transaction is useful to get strongly consistent reads at a shared timestamp. */
|
||||
public <R> R transactNewReadOnly(Work<R> work) {
|
||||
<R> R transactNewReadOnly(Work<R> work) {
|
||||
ReadOnlyWork<R> readOnlyWork = new ReadOnlyWork<>(work, getClock());
|
||||
try {
|
||||
ofy().transactNew(readOnlyWork);
|
||||
ofy().transactNew(() -> {
|
||||
readOnlyWork.run();
|
||||
return null;
|
||||
});
|
||||
} catch (TransientFailureException | DatastoreTimeoutException | DatastoreFailureException e) {
|
||||
// These are always retryable for a read-only operation.
|
||||
return transactNewReadOnly(work);
|
||||
@@ -309,7 +315,7 @@ public class Ofy {
|
||||
throw new AssertionError(); // How on earth did we get here?
|
||||
}
|
||||
|
||||
public void transactNewReadOnly(Runnable work) {
|
||||
void transactNewReadOnly(Runnable work) {
|
||||
transactNewReadOnly(
|
||||
() -> {
|
||||
work.run();
|
||||
@@ -318,7 +324,7 @@ public class Ofy {
|
||||
}
|
||||
|
||||
/** Execute some work in a transactionless context. */
|
||||
public <R> R doTransactionless(Work<R> work) {
|
||||
<R> R doTransactionless(Work<R> work) {
|
||||
try {
|
||||
com.googlecode.objectify.ObjectifyService.push(
|
||||
com.googlecode.objectify.ObjectifyService.ofy().transactionless());
|
||||
@@ -347,7 +353,7 @@ public class Ofy {
|
||||
}
|
||||
|
||||
/** Get the time associated with the start of this particular transaction attempt. */
|
||||
public DateTime getTransactionTime() {
|
||||
DateTime getTransactionTime() {
|
||||
assertInTransaction();
|
||||
return TRANSACTION_INFO.get().transactionTime;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.model.ofy;
|
||||
|
||||
import com.googlecode.objectify.Work;
|
||||
import google.registry.model.transaction.TransactionManager.Work;
|
||||
import google.registry.util.Clock;
|
||||
|
||||
/** Wrapper for {@link Work} that disallows mutations and fails the transaction at the end. */
|
||||
@@ -30,8 +30,8 @@ class ReadOnlyWork<R> extends CommitLoggedWork<R> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vrun() {
|
||||
super.vrun();
|
||||
public void run() {
|
||||
super.run();
|
||||
throw new KillTransactionException();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.common.base.Verify.verify;
|
||||
import static com.google.common.base.Verify.verifyNotNull;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.rde.RdeNamingUtils.makePartialName;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.base.VerifyException;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
@@ -70,7 +71,7 @@ public final class RdeRevision extends ImmutableObject {
|
||||
public static void saveRevision(String tld, DateTime date, RdeMode mode, int revision) {
|
||||
checkArgument(revision >= 0, "Negative revision: %s", revision);
|
||||
String triplet = makePartialName(tld, date, mode);
|
||||
ofy().assertInTransaction();
|
||||
tm().assertInTransaction();
|
||||
RdeRevision object = ofy().load().type(RdeRevision.class).id(triplet).now();
|
||||
if (revision == 0) {
|
||||
verify(object == null, "RdeRevision object already created: %s", object);
|
||||
|
||||
@@ -31,6 +31,7 @@ import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registry.Registries.assertTldsExist;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
@@ -206,7 +207,7 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
private static final Supplier<ImmutableMap<String, Registrar>> CACHE_BY_CLIENT_ID =
|
||||
memoizeWithShortExpiration(
|
||||
() ->
|
||||
ofy()
|
||||
tm()
|
||||
.doTransactionless(
|
||||
() -> Maps.uniqueIndex(loadAll(), Registrar::getClientId)));
|
||||
|
||||
@@ -408,6 +409,9 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
*/
|
||||
boolean contactsRequireSyncing = true;
|
||||
|
||||
/** Whether or not registry lock is allowed for this registrar. */
|
||||
boolean registryLockAllowed = false;
|
||||
|
||||
@NonFinalForTesting
|
||||
private static Supplier<byte[]> saltSupplier =
|
||||
() -> {
|
||||
@@ -544,6 +548,10 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
return contactsRequireSyncing;
|
||||
}
|
||||
|
||||
public boolean isRegistryLockAllowed() {
|
||||
return registryLockAllowed;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
@@ -868,7 +876,9 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDriveFolderId(String driveFolderId) {
|
||||
public Builder setDriveFolderId(@Nullable String driveFolderId) {
|
||||
checkArgument(driveFolderId == null || !driveFolderId.contains("/"),
|
||||
"Drive folder ID must not be a full URL");
|
||||
getInstance().driveFolderId = driveFolderId;
|
||||
return this;
|
||||
}
|
||||
@@ -892,6 +902,11 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRegistryLockAllowed(boolean registryLockAllowed) {
|
||||
getInstance().registryLockAllowed = registryLockAllowed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Build the registrar, nullifying empty fields. */
|
||||
@Override
|
||||
public Registrar build() {
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Sets.difference;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.registrar.Registrar.checkValidEmail;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
@@ -154,7 +155,7 @@ public class RegistrarContact extends ImmutableObject implements Jsonifiable {
|
||||
*/
|
||||
public static void updateContacts(
|
||||
final Registrar registrar, final Set<RegistrarContact> contacts) {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
ofy()
|
||||
|
||||
@@ -24,6 +24,7 @@ import static com.google.common.collect.Maps.filterValues;
|
||||
import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -52,7 +53,7 @@ public final class Registries {
|
||||
private static Supplier<ImmutableMap<String, TldType>> createFreshCache() {
|
||||
return memoizeWithShortExpiration(
|
||||
() ->
|
||||
ofy()
|
||||
tm()
|
||||
.doTransactionless(
|
||||
() -> {
|
||||
ImmutableMap.Builder<String, TldType> builder =
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.google.common.base.Predicates.not;
|
||||
import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration;
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
@@ -222,7 +223,7 @@ public class Registry extends ImmutableObject implements Buildable {
|
||||
// Enter a transactionless context briefly; we don't want to enroll every TLD in a
|
||||
// transaction that might be wrapping this call.
|
||||
return Optional.ofNullable(
|
||||
ofy()
|
||||
tm()
|
||||
.doTransactionless(
|
||||
() -> ofy()
|
||||
.load()
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.config.RegistryConfig.getStaticPremiumListMaxCache
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.allocateId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -150,7 +151,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||
new CacheLoader<String, PremiumList>() {
|
||||
@Override
|
||||
public PremiumList load(final String name) {
|
||||
return ofy().doTransactionless(() -> loadPremiumList(name));
|
||||
return tm().doTransactionless(() -> loadPremiumList(name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -174,7 +175,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||
new CacheLoader<Key<PremiumListRevision>, PremiumListRevision>() {
|
||||
@Override
|
||||
public PremiumListRevision load(final Key<PremiumListRevision> revisionKey) {
|
||||
return ofy().doTransactionless(() -> ofy().load().key(revisionKey).now());
|
||||
return tm().doTransactionless(() -> ofy().load().key(revisionKey).now());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -214,7 +215,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
|
||||
new CacheLoader<Key<PremiumListEntry>, Optional<PremiumListEntry>>() {
|
||||
@Override
|
||||
public Optional<PremiumListEntry> load(final Key<PremiumListEntry> entryKey) {
|
||||
return ofy()
|
||||
return tm()
|
||||
.doTransactionless(() -> Optional.ofNullable(ofy().load().key(entryKey).now()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,6 +27,7 @@ import static google.registry.model.registry.label.DomainLabelMetrics.PremiumLis
|
||||
import static google.registry.model.registry.label.PremiumList.cachePremiumListEntries;
|
||||
import static google.registry.model.registry.label.PremiumList.cachePremiumListRevisions;
|
||||
import static google.registry.model.registry.label.PremiumList.cachePremiumLists;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
@@ -151,12 +152,12 @@ public final class PremiumListUtils {
|
||||
|
||||
// Save the new child entities in a series of transactions.
|
||||
for (final List<PremiumListEntry> batch : partition(parentedEntries, TRANSACTION_BATCH_SIZE)) {
|
||||
ofy().transactNew(() -> ofy().save().entities(batch));
|
||||
tm().transactNew(() -> ofy().save().entities(batch));
|
||||
}
|
||||
|
||||
// Save the new PremiumList and revision itself.
|
||||
PremiumList updated = ofy().transactNew(() -> {
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
PremiumList updated = tm().transactNew(() -> {
|
||||
DateTime now = tm().getTransactionTime();
|
||||
// Assert that the premium list hasn't been changed since we started this process.
|
||||
PremiumList existing = ofy().load()
|
||||
.type(PremiumList.class)
|
||||
@@ -201,7 +202,7 @@ public final class PremiumListUtils {
|
||||
|
||||
/** Deletes the PremiumList and all of its child entities. */
|
||||
public static void deletePremiumList(final PremiumList premiumList) {
|
||||
ofy().transactNew(() -> ofy().delete().entity(premiumList));
|
||||
tm().transactNew(() -> ofy().delete().entity(premiumList));
|
||||
deleteRevisionAndEntriesOfPremiumList(premiumList);
|
||||
cachePremiumLists.invalidate(premiumList.getName());
|
||||
}
|
||||
@@ -214,9 +215,9 @@ public final class PremiumListUtils {
|
||||
partition(
|
||||
ofy().load().type(PremiumListEntry.class).ancestor(premiumList.revisionKey).keys(),
|
||||
TRANSACTION_BATCH_SIZE)) {
|
||||
ofy().transactNew(() -> ofy().delete().keys(batch));
|
||||
tm().transactNew(() -> ofy().delete().keys(batch));
|
||||
}
|
||||
ofy().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey()));
|
||||
tm().transactNew(() -> ofy().delete().key(premiumList.getRevisionKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.server;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
@@ -176,10 +177,10 @@ public class Lock extends ImmutableObject implements Serializable {
|
||||
// access to resources like GCS that can't be transactionally rolled back. Therefore, the lock
|
||||
// must be definitively acquired before it is used, even when called inside another transaction.
|
||||
AcquireResult acquireResult =
|
||||
ofy()
|
||||
tm()
|
||||
.transactNew(
|
||||
() -> {
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
|
||||
// Checking if an unexpired lock still exists - if so, the lock can't be acquired.
|
||||
Lock lock = ofy().load().type(Lock.class).id(lockId).now();
|
||||
@@ -217,7 +218,7 @@ public class Lock extends ImmutableObject implements Serializable {
|
||||
/** Release the lock. */
|
||||
public void release() {
|
||||
// Just use the default clock because we aren't actually doing anything that will use the clock.
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
// To release a lock, check that no one else has already obtained it and if not
|
||||
@@ -231,7 +232,7 @@ public class Lock extends ImmutableObject implements Serializable {
|
||||
logger.atInfo().log("Deleting lock: %s", lockId);
|
||||
ofy().deleteWithoutBackup().entity(Lock.this);
|
||||
lockMetrics.recordRelease(
|
||||
resourceName, tld, new Duration(acquiredTime, ofy().getTransactionTime()));
|
||||
resourceName, tld, new Duration(acquiredTime, tm().getTransactionTime()));
|
||||
} else {
|
||||
logger.atSevere().log(
|
||||
"The lock we acquired was transferred to someone else before we"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.model.server;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
@@ -54,7 +55,7 @@ public class ServerSecret extends CrossTldSingleton {
|
||||
return secret;
|
||||
}
|
||||
// Slow path - transactionally create a new ServerSecret (once per app setup).
|
||||
return ofy().transact(() -> {
|
||||
return tm().transact(() -> {
|
||||
// Check again for an existing secret within the transaction to avoid races.
|
||||
ServerSecret secret1 = ofy().load().entity(new ServerSecret()).now();
|
||||
if (secret1 == null) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
|
||||
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
|
||||
import static google.registry.model.ofy.ObjectifyService.allocateId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
|
||||
@@ -92,7 +93,7 @@ public class SignedMarkRevocationList extends ImmutableObject {
|
||||
private static final Supplier<SignedMarkRevocationList> CACHE =
|
||||
memoizeWithShortExpiration(
|
||||
() ->
|
||||
ofy()
|
||||
tm()
|
||||
.transactNewReadOnly(
|
||||
() -> {
|
||||
Iterable<SignedMarkRevocationList> shards =
|
||||
@@ -150,7 +151,7 @@ public class SignedMarkRevocationList extends ImmutableObject {
|
||||
|
||||
/** Save this list to Datastore in sharded form. Returns {@code this}. */
|
||||
public SignedMarkRevocationList save() {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
ofy()
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.google.common.base.Verify.verify;
|
||||
import static google.registry.model.CacheUtils.memoizeWithShortExpiration;
|
||||
import static google.registry.model.ofy.ObjectifyService.allocateId;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -111,7 +112,7 @@ public class ClaimsListShard extends ImmutableObject {
|
||||
Concurrent.transform(
|
||||
shardKeys,
|
||||
key ->
|
||||
ofy()
|
||||
tm()
|
||||
.transactNewReadOnly(
|
||||
() -> {
|
||||
ClaimsListShard claimsListShard = ofy().load().key(key).now();
|
||||
@@ -188,7 +189,7 @@ public class ClaimsListShard extends ImmutableObject {
|
||||
Concurrent.transform(
|
||||
CollectionUtils.partitionMap(labelsToKeys, shardSize),
|
||||
(final ImmutableMap<String, String> labelsToKeysShard) ->
|
||||
ofy()
|
||||
tm()
|
||||
.transactNew(
|
||||
() -> {
|
||||
ClaimsListShard shard = create(creationTime, labelsToKeysShard);
|
||||
@@ -199,7 +200,7 @@ public class ClaimsListShard extends ImmutableObject {
|
||||
}));
|
||||
|
||||
// Persist the new revision, thus causing the newly created shards to go live.
|
||||
ofy()
|
||||
tm()
|
||||
.transactNew(
|
||||
() -> {
|
||||
verify(
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.tmch;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import google.registry.model.annotations.NotBackedUp;
|
||||
@@ -48,11 +49,11 @@ public final class TmchCrl extends CrossTldSingleton {
|
||||
* and actually newer than the one currently in Datastore.
|
||||
*/
|
||||
public static void set(final String crl, final String url) {
|
||||
ofy()
|
||||
tm()
|
||||
.transactNew(
|
||||
() -> {
|
||||
TmchCrl tmchCrl = new TmchCrl();
|
||||
tmchCrl.updated = ofy().getTransactionTime();
|
||||
tmchCrl.updated = tm().getTransactionTime();
|
||||
tmchCrl.crl = checkNotNull(crl, "crl");
|
||||
tmchCrl.url = checkNotNull(url, "url");
|
||||
ofy().saveWithoutBackup().entity(tmchCrl);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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.model.transaction;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* This interface defines the methods to execute database operations with or without a transaction.
|
||||
*/
|
||||
public interface TransactionManager {
|
||||
|
||||
/** This functional interface defines a method to execute a work and return the result. */
|
||||
@FunctionalInterface
|
||||
interface Work<R> {
|
||||
R run();
|
||||
}
|
||||
|
||||
/** Returns {@code true} if the caller is in a transaction.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
boolean inTransaction();
|
||||
|
||||
/** Throws {@link IllegalStateException} if the caller is not in a transaction.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
void assertInTransaction();
|
||||
|
||||
/** Executes the work in a transaction and returns the result. */
|
||||
<T> T transact(Work<T> work);
|
||||
|
||||
/** Executes the work in a transaction. */
|
||||
void transact(Runnable work);
|
||||
|
||||
/** Pauses the current transaction (if any), executes the work in a new transaction
|
||||
* and returns the result.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
<T> T transactNew(Work<T> work);
|
||||
|
||||
/** Pauses the current transaction (if any) and executes the work in a new transaction.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
void transactNew(Runnable work);
|
||||
|
||||
/** Executes the work in a read-only transaction and returns the result.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
<R> R transactNewReadOnly(Work<R> work);
|
||||
|
||||
/** Executes the work in a read-only transaction.
|
||||
*
|
||||
* <p>Note that this function is kept for backward compatibility. We will review the use case
|
||||
* later when adding the cloud sql implementation.
|
||||
*/
|
||||
void transactNewReadOnly(Runnable work);
|
||||
|
||||
/** Executes the work in a transactionless context. */
|
||||
<R> R doTransactionless(Work<R> work);
|
||||
|
||||
/** Returns the time associated with the start of this particular transaction attempt. */
|
||||
DateTime getTransactionTime();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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.model.transaction;
|
||||
|
||||
import google.registry.model.ofy.DatastoreTransactionManager;
|
||||
|
||||
/** Factory class to create {@link TransactionManager} instance. */
|
||||
public class TransactionManagerFactory {
|
||||
|
||||
private static final TransactionManager TM = createTransactionManager();
|
||||
|
||||
private TransactionManagerFactory() {}
|
||||
|
||||
private static TransactionManager createTransactionManager() {
|
||||
// TODO: Conditionally returns the corresponding implementation once we have
|
||||
// CloudSqlTransactionManager
|
||||
return new DatastoreTransactionManager(null);
|
||||
}
|
||||
|
||||
/** Returns {@link TransactionManager} instance. */
|
||||
public static TransactionManager tm() {
|
||||
|
||||
return TM;
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -17,6 +17,7 @@ package google.registry.model.translators;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static google.registry.config.RegistryConfig.getCommitLogDatastoreRetention;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
@@ -62,7 +63,7 @@ public final class CommitLogRevisionsTranslatorFactory
|
||||
@Override
|
||||
ImmutableSortedMap<DateTime, Key<CommitLogManifest>> transformBeforeSave(
|
||||
ImmutableSortedMap<DateTime, Key<CommitLogManifest>> revisions) {
|
||||
DateTime now = ofy().getTransactionTime();
|
||||
DateTime now = tm().getTransactionTime();
|
||||
DateTime threshold = now.minus(getCommitLogDatastoreRetention());
|
||||
DateTime preThresholdTime = firstNonNull(revisions.floorKey(threshold), START_OF_TIME);
|
||||
return new ImmutableSortedMap.Builder<DateTime, Key<CommitLogManifest>>(Ordering.natural())
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
package google.registry.model.translators;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
@@ -46,7 +46,7 @@ public class CreateAutoTimestampTranslatorFactory
|
||||
/** Save a timestamp, setting it to the current time if it did not have a previous value. */
|
||||
@Override
|
||||
public Date saveValue(CreateAutoTimestamp pojoValue) {
|
||||
return firstNonNull(pojoValue.getTimestamp(), ofy().getTransactionTime()).toDate();
|
||||
return firstNonNull(pojoValue.getTimestamp(), tm().getTransactionTime()).toDate();
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
|
||||
package google.registry.model.translators;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import google.registry.model.UpdateAutoTimestamp;
|
||||
@@ -46,7 +46,7 @@ public class UpdateAutoTimestampTranslatorFactory
|
||||
/** Save a timestamp, setting it to the current time. */
|
||||
@Override
|
||||
public Date saveValue(UpdateAutoTimestamp pojoValue) {
|
||||
return ofy().getTransactionTime().toDate();
|
||||
return tm().getTransactionTime().toDate();
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
@@ -23,6 +25,7 @@ import com.google.api.client.http.HttpRequest;
|
||||
import com.google.api.client.http.HttpRequestFactory;
|
||||
import com.google.api.client.http.HttpResponse;
|
||||
import com.google.api.client.http.HttpTransport;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
@@ -34,8 +37,9 @@ import com.google.gson.JsonObject;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.keyring.api.KeyModule;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registry.Registries;
|
||||
import google.registry.model.registry.Registry.TldType;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -56,7 +60,18 @@ import javax.inject.Inject;
|
||||
* <p>It is a "login/query/logout" system where you login using the ICANN Reporting credentials, get
|
||||
* a cookie you then send to get the list and finally logout.
|
||||
*
|
||||
* <p>The username is [TLD]_ry. It could be any "real" TLD.
|
||||
* <p>For clarity, this is how one would contact this endpoint "manually", from a whitelisted IP
|
||||
* server:
|
||||
*
|
||||
* <p>$ curl [base]/login -I --user [tld]_ry:[password]
|
||||
*
|
||||
* <p>get the id=xxx value from the reply
|
||||
*
|
||||
* <p>$ curl [base]/registrarRdapBaseUrl/list -b 'id=xxx'
|
||||
*
|
||||
* <p>$ curl [base]/logout -b 'id=xxx'
|
||||
*
|
||||
* <p>where [base] is https://mosapi.icann.org/mosapi/v1/[tld]
|
||||
*/
|
||||
@Action(
|
||||
service = Action.Service.BACKEND,
|
||||
@@ -75,41 +90,29 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
@Inject HttpTransport httpTransport;
|
||||
@Inject @KeyModule.Key("icannReportingPassword") String password;
|
||||
|
||||
/**
|
||||
* The TLD for which we make the request.
|
||||
*
|
||||
* <p>The actual value doesn't matter, as long as it's a TLD that has access to the ICANN
|
||||
* Reporter. It's just used to login.
|
||||
*/
|
||||
@Inject @Parameter("tld") String tld;
|
||||
|
||||
@Inject
|
||||
UpdateRegistrarRdapBaseUrlsAction() {}
|
||||
|
||||
private String loginAndGetId(HttpRequestFactory requestFactory) {
|
||||
try {
|
||||
logger.atInfo().log("Logging in to MoSAPI");
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LOGIN_URL, tld)));
|
||||
request.getHeaders().setBasicAuthentication(String.format("%s_ry", tld), password);
|
||||
HttpResponse response = request.execute();
|
||||
private String loginAndGetId(HttpRequestFactory requestFactory, String tld) throws IOException {
|
||||
logger.atInfo().log("Logging in to MoSAPI");
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LOGIN_URL, tld)));
|
||||
request.getHeaders().setBasicAuthentication(String.format("%s_ry", tld), password);
|
||||
HttpResponse response = request.execute();
|
||||
|
||||
Optional<HttpCookie> idCookie =
|
||||
HttpCookie.parse(response.getHeaders().getFirstHeaderStringValue("Set-Cookie")).stream()
|
||||
.filter(cookie -> cookie.getName().equals(COOKIE_ID))
|
||||
.findAny();
|
||||
checkState(
|
||||
idCookie.isPresent(),
|
||||
"Didn't get the ID cookie from the login response. Code: %s, headers: %s",
|
||||
response.getStatusCode(),
|
||||
response.getHeaders());
|
||||
return idCookie.get().getValue();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Error logging in to MoSAPI server: " + e.getMessage(), e);
|
||||
}
|
||||
Optional<HttpCookie> idCookie =
|
||||
HttpCookie.parse(response.getHeaders().getFirstHeaderStringValue("Set-Cookie")).stream()
|
||||
.filter(cookie -> cookie.getName().equals(COOKIE_ID))
|
||||
.findAny();
|
||||
checkState(
|
||||
idCookie.isPresent(),
|
||||
"Didn't get the ID cookie from the login response. Code: %s, headers: %s",
|
||||
response.getStatusCode(),
|
||||
response.getHeaders());
|
||||
return idCookie.get().getValue();
|
||||
}
|
||||
|
||||
private void logout(HttpRequestFactory requestFactory, String id) {
|
||||
private void logout(HttpRequestFactory requestFactory, String id, String tld) {
|
||||
try {
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LOGOUT_URL, tld)));
|
||||
@@ -122,13 +125,13 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private ImmutableSetMultimap<String, String> getRdapBaseUrlsPerIanaId() {
|
||||
HttpRequestFactory requestFactory = httpTransport.createRequestFactory();
|
||||
String id = loginAndGetId(requestFactory);
|
||||
private ImmutableSetMultimap<String, String> getRdapBaseUrlsPerIanaIdWithTld(
|
||||
String tld, String id, HttpRequestFactory requestFactory) {
|
||||
String content;
|
||||
try {
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LIST_URL, tld)));
|
||||
request.getHeaders().setAcceptEncoding("identity");
|
||||
request.getHeaders().setCookie(String.format("%s=%s", COOKIE_ID, id));
|
||||
HttpResponse response = request.execute();
|
||||
|
||||
@@ -139,7 +142,7 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
throw new UncheckedIOException(
|
||||
"Error reading RDAP list from MoSAPI server: " + e.getMessage(), e);
|
||||
} finally {
|
||||
logout(requestFactory, id);
|
||||
logout(requestFactory, id, tld);
|
||||
}
|
||||
|
||||
logger.atInfo().log("list reply: '%s'", content);
|
||||
@@ -160,12 +163,42 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ImmutableSetMultimap<String, String> getRdapBaseUrlsPerIanaId() {
|
||||
// All TLDs have the same data, so just keep trying until one works
|
||||
// (the expectation is that all / any should work)
|
||||
ImmutableList<String> tlds = ImmutableList.sortedCopyOf(Registries.getTldsOfType(TldType.REAL));
|
||||
checkArgument(!tlds.isEmpty(), "There must exist at least one REAL TLD.");
|
||||
Throwable finalThrowable = null;
|
||||
for (String tld : tlds) {
|
||||
HttpRequestFactory requestFactory = httpTransport.createRequestFactory();
|
||||
String id;
|
||||
try {
|
||||
id = loginAndGetId(requestFactory, tld);
|
||||
} catch (Throwable e) {
|
||||
// Login failures are bad but not unexpected for certain TLDs. We shouldn't store those
|
||||
// but rather should only store useful Throwables.
|
||||
logger.atWarning().log("Error logging in to MoSAPI server: " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
return getRdapBaseUrlsPerIanaIdWithTld(tld, id, requestFactory);
|
||||
} catch (Throwable throwable) {
|
||||
logger.atWarning().log(
|
||||
String.format(
|
||||
"Error retrieving RDAP urls with TLD %s: %s", tld, throwable.getMessage()));
|
||||
finalThrowable = throwable;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(
|
||||
String.format("Error contacting MosAPI server. Tried TLDs %s", tlds), finalThrowable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ImmutableSetMultimap<String, String> ianaToBaseUrls = getRdapBaseUrlsPerIanaId();
|
||||
|
||||
for (Key<Registrar> registrarKey : ofy().load().type(Registrar.class).keys()) {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
Registrar registrar = ofy().load().key(registrarKey).now();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.rde;
|
||||
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.model.common.Cursor;
|
||||
@@ -98,7 +99,7 @@ class EscrowTaskRunner {
|
||||
task.runWithLock(nextRequiredRun);
|
||||
DateTime nextRun = nextRequiredRun.plus(interval);
|
||||
logger.atInfo().log("Rolling cursor forward to %s.", nextRun);
|
||||
ofy().transact(() -> ofy().save().entity(Cursor.create(cursorType, nextRun, registry)));
|
||||
tm().transact(() -> ofy().save().entity(Cursor.create(cursorType, nextRun, registry)));
|
||||
return null;
|
||||
};
|
||||
String lockName = String.format("EscrowTaskRunner %s", task.getClass().getSimpleName());
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.rde;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
@@ -106,7 +107,7 @@ public final class PendingDepositChecker {
|
||||
final Registry registry,
|
||||
final CursorType cursorType,
|
||||
final DateTime initialValue) {
|
||||
return ofy()
|
||||
return tm()
|
||||
.transact(
|
||||
() -> {
|
||||
Cursor cursor = ofy().load().key(Cursor.createKey(cursorType, registry)).now();
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Verify.verify;
|
||||
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 java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.appengine.tools.cloudstorage.GcsFilename;
|
||||
@@ -202,7 +203,7 @@ public final class RdeStagingReducer extends Reducer<PendingDeposit, DepositFrag
|
||||
logger.atInfo().log("Manual operation; not advancing cursor or enqueuing upload task");
|
||||
return;
|
||||
}
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
Registry registry = Registry.get(tld);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.model.common.Cursor.CursorType.RDE_UPLOAD_SFTP;
|
||||
import static google.registry.model.common.Cursor.getCursorTimeOrStartOfTime;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.rde.RdeMode.FULL;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -169,11 +170,11 @@ public final class RdeUploadAction implements Runnable, EscrowTask {
|
||||
() -> upload(xmlFilename, xmlLength, watermark, name), JSchException.class);
|
||||
logger.atInfo().log(
|
||||
"Updating RDE cursor '%s' for TLD '%s' following successful upload.", RDE_UPLOAD_SFTP, tld);
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
Cursor updatedSftpCursor =
|
||||
Cursor.create(RDE_UPLOAD_SFTP, ofy().getTransactionTime(), Registry.get(tld));
|
||||
Cursor.create(RDE_UPLOAD_SFTP, tm().getTransactionTime(), Registry.get(tld));
|
||||
ofy().save().entity(updatedSftpCursor);
|
||||
});
|
||||
response.setContentType(PLAIN_TEXT_UTF_8);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
import com.google.appengine.tools.cloudstorage.GcsFilename;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.io.ByteStreams;
|
||||
@@ -38,6 +39,7 @@ import google.registry.util.Retrier;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Copy all registrar detail reports in a given bucket's subdirectory from GCS to Drive. */
|
||||
@@ -95,6 +97,8 @@ public final class CopyDetailReportsAction implements Runnable {
|
||||
response.setPayload(String.format("Failure, encountered %s", e.getMessage()));
|
||||
return;
|
||||
}
|
||||
ImmutableMap.Builder<String, Throwable> copyErrorsBuilder =
|
||||
new ImmutableMap.Builder<String, Throwable>();
|
||||
for (String detailReportName : detailReportObjectNames) {
|
||||
// The standard report format is "invoice_details_yyyy-MM_registrarId_tld.csv
|
||||
// TODO(larryruili): Determine a safer way of enforcing this.
|
||||
@@ -117,7 +121,7 @@ public final class CopyDetailReportsAction implements Runnable {
|
||||
try (InputStream input =
|
||||
gcsUtils.openInputStream(
|
||||
new GcsFilename(billingBucket, invoiceDirectoryPrefix + detailReportName))) {
|
||||
driveConnection.createFile(
|
||||
driveConnection.createOrUpdateFile(
|
||||
detailReportName,
|
||||
MediaType.CSV_UTF_8,
|
||||
driveFolderId,
|
||||
@@ -129,15 +133,31 @@ public final class CopyDetailReportsAction implements Runnable {
|
||||
},
|
||||
IOException.class);
|
||||
} catch (Throwable e) {
|
||||
emailUtils.sendAlertEmail(
|
||||
String alertMessage =
|
||||
String.format(
|
||||
"Warning: CopyDetailReportsAction failed.\nEncountered: %s on file: %s",
|
||||
getRootCause(e).getMessage(), detailReportName));
|
||||
throw e;
|
||||
"Warning: CopyDetailReportsAction failed for registrar %s.\n"
|
||||
+ "Encountered: %s on file: %s",
|
||||
registrarId, getRootCause(e).getMessage(), detailReportName);
|
||||
copyErrorsBuilder.put(registrarId, e);
|
||||
logger.atSevere().withCause(e).log(alertMessage);
|
||||
}
|
||||
}
|
||||
response.setStatus(SC_OK);
|
||||
response.setContentType(MediaType.PLAIN_TEXT_UTF_8);
|
||||
response.setPayload("Copied detail reports.");
|
||||
StringBuilder payload = new StringBuilder().append("Copied detail reports.\n");
|
||||
ImmutableMap<String, Throwable> copyErrors = copyErrorsBuilder.build();
|
||||
if (!copyErrors.isEmpty()) {
|
||||
payload.append("The following errors were encountered:\n");
|
||||
payload.append(
|
||||
copyErrors.entrySet().stream()
|
||||
.map(
|
||||
entrySet ->
|
||||
String.format(
|
||||
"Registrar: %s\nError: %s\n",
|
||||
entrySet.getKey(), entrySet.getValue().getMessage()))
|
||||
.collect(Collectors.joining()));
|
||||
}
|
||||
response.setPayload(payload.toString());
|
||||
emailUtils.sendAlertEmail(payload.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,22 +59,19 @@ public class Spec11EmailUtils {
|
||||
private final SendEmailService emailService;
|
||||
private final InternetAddress outgoingEmailAddress;
|
||||
private final InternetAddress alertRecipientAddress;
|
||||
private final InternetAddress spec11ReplyToAddress;
|
||||
private final ImmutableList<String> spec11WebResources;
|
||||
private final String registryName;
|
||||
|
||||
@Inject
|
||||
Spec11EmailUtils(
|
||||
SendEmailService emailService,
|
||||
@Config("gSuiteOutgoingEmailAddress") InternetAddress outgoingEmailAddress,
|
||||
@Config("alertRecipientEmailAddress") InternetAddress alertRecipientAddress,
|
||||
@Config("spec11ReplyToEmailAddress") InternetAddress spec11ReplyToAddress,
|
||||
@Config("spec11OutgoingEmailAddress") InternetAddress spec11OutgoingEmailAddress,
|
||||
@Config("spec11WebResources") ImmutableList<String> spec11WebResources,
|
||||
@Config("registryName") String registryName) {
|
||||
this.emailService = emailService;
|
||||
this.outgoingEmailAddress = outgoingEmailAddress;
|
||||
this.outgoingEmailAddress = spec11OutgoingEmailAddress;
|
||||
this.alertRecipientAddress = alertRecipientAddress;
|
||||
this.spec11ReplyToAddress = spec11ReplyToAddress;
|
||||
this.spec11WebResources = spec11WebResources;
|
||||
this.registryName = registryName;
|
||||
}
|
||||
@@ -149,7 +146,7 @@ public class Spec11EmailUtils {
|
||||
.setContentType(MediaType.HTML_UTF_8)
|
||||
.setFrom(outgoingEmailAddress)
|
||||
.addRecipient(getEmailAddressForRegistrar(registrarThreatMatches.clientId()))
|
||||
.setBcc(spec11ReplyToAddress)
|
||||
.setBcc(outgoingEmailAddress)
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -172,7 +169,7 @@ public class Spec11EmailUtils {
|
||||
ImmutableMap.of(
|
||||
"date", date.toString(),
|
||||
"registry", registryName,
|
||||
"replyToEmail", spec11ReplyToAddress.getAddress(),
|
||||
"replyToEmail", outgoingEmailAddress.getAddress(),
|
||||
"threats", threatMatchMap,
|
||||
"resources", spec11WebResources);
|
||||
renderer.setData(data);
|
||||
|
||||
@@ -16,12 +16,17 @@ package google.registry.request;
|
||||
|
||||
import static com.google.monitoring.metrics.EventMetric.DEFAULT_FITTER;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.monitoring.metrics.EventMetric;
|
||||
import com.google.monitoring.metrics.LabelDescriptor;
|
||||
import com.google.monitoring.metrics.MetricRegistryImpl;
|
||||
import google.registry.request.auth.AuthLevel;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
class RequestMetrics {
|
||||
@@ -50,7 +55,7 @@ class RequestMetrics {
|
||||
Duration duration, String path, Action.Method method, AuthLevel authLevel, boolean success) {
|
||||
requestDurationMetric.record(
|
||||
duration.getMillis(),
|
||||
path,
|
||||
truncatePath(path),
|
||||
String.valueOf(method),
|
||||
String.valueOf(authLevel),
|
||||
String.valueOf(success));
|
||||
@@ -58,4 +63,15 @@ class RequestMetrics {
|
||||
"Action called for path=%s, method=%s, authLevel=%s, success=%s. Took: %.3fs",
|
||||
path, method, authLevel, success, duration.getMillis() / 1000d);
|
||||
}
|
||||
|
||||
private static String truncatePath(String path) {
|
||||
// We want to bucket RDAP requests by type to use less metric space,
|
||||
// e.g. "/rdap/domains" rather than "/rdap/domains/foo.tld"
|
||||
if (path.startsWith("/rdap")) {
|
||||
List<String> splitPath = Splitter.on("/").omitEmptyStrings().splitToList(path);
|
||||
return Streams.stream(Iterables.limit(splitPath, 2))
|
||||
.collect(Collectors.joining("/", "/", "/"));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ public class DriveConnection {
|
||||
/**
|
||||
* Creates a file with the given parent.
|
||||
*
|
||||
* <p>If a file with the same path already exists, a duplicate is created. If overwriting the
|
||||
* existing file is the desired behavior, use {@link #createOrUpdateFile(String, MediaType,
|
||||
* String, byte[])} instead.
|
||||
*
|
||||
* @returns the file id.
|
||||
*/
|
||||
public String createFile(String title, MediaType mimeType, String parentFolderId, byte[] bytes)
|
||||
|
||||
@@ -16,7 +16,7 @@ package google.registry.tmch;
|
||||
|
||||
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.appengine.api.taskqueue.TaskOptions;
|
||||
import com.google.appengine.api.taskqueue.TaskOptions.Method;
|
||||
@@ -47,7 +47,7 @@ public final class LordnTaskUtils {
|
||||
* Enqueues a task in the LORDN queue representing a line of CSV for LORDN export.
|
||||
*/
|
||||
public static void enqueueDomainBaseTask(DomainBase domain) {
|
||||
ofy().assertInTransaction();
|
||||
tm().assertInTransaction();
|
||||
// This method needs to use ofy transactionTime as the DomainBase's creationTime because
|
||||
// CreationTime isn't yet populated when this method is called during the resource flow.
|
||||
String tld = domain.getTld();
|
||||
@@ -55,12 +55,12 @@ public final class LordnTaskUtils {
|
||||
getQueue(QUEUE_SUNRISE).add(TaskOptions.Builder
|
||||
.withTag(tld)
|
||||
.method(Method.PULL)
|
||||
.payload(getCsvLineForSunriseDomain(domain, ofy().getTransactionTime())));
|
||||
.payload(getCsvLineForSunriseDomain(domain, tm().getTransactionTime())));
|
||||
} else {
|
||||
getQueue(QUEUE_CLAIMS).add(TaskOptions.Builder
|
||||
.withTag(tld)
|
||||
.method(Method.PULL)
|
||||
.payload(getCsvLineForClaimsDomain(domain, ofy().getTransactionTime())));
|
||||
.payload(getCsvLineForClaimsDomain(domain, tm().getTransactionTime())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.flows.poll.PollFlowUtils.getPollMessagesQuery;
|
||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static google.registry.model.poll.PollMessageExternalKeyConverter.makePollMessageExternalId;
|
||||
import static google.registry.model.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
@@ -85,7 +86,7 @@ final class AckPollMessagesCommand implements CommandWithRemoteApi {
|
||||
public void run() {
|
||||
QueryKeys<PollMessage> query = getPollMessagesQuery(clientId, clock.nowUtc()).keys();
|
||||
for (List<Key<PollMessage>> keys : Iterables.partition(query, BATCH_SIZE)) {
|
||||
ofy()
|
||||
tm()
|
||||
.transact(
|
||||
() -> {
|
||||
// Load poll messages and filter to just those of interest.
|
||||
|
||||
@@ -100,7 +100,7 @@ public class AuthModule {
|
||||
AbstractDataStoreFactory dataStoreFactory) {
|
||||
try {
|
||||
return new GoogleAuthorizationCodeFlow.Builder(
|
||||
new NetHttpTransport(), jsonFactory, clientSecrets, requiredOauthScopes)
|
||||
new NetHttpTransport(), jsonFactory, clientSecrets, requiredOauthScopes)
|
||||
.setDataStoreFactory(dataStoreFactory)
|
||||
.build();
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -52,7 +52,7 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand {
|
||||
|
||||
@Parameter(
|
||||
names = {"--contact"},
|
||||
description = "Contact ID for the request. This will be used for registrant, admin contact,"
|
||||
description = "Contact ID for the request. This will be used for registrant, admin contact, "
|
||||
+ "and tech contact.",
|
||||
required = true)
|
||||
private String contact;
|
||||
|
||||
@@ -234,10 +234,17 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
|
||||
arity = 1)
|
||||
private Boolean contactsRequireSyncing;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--registry_lock_allowed",
|
||||
description = "Whether this registrar is allowed to use registry lock",
|
||||
arity = 1)
|
||||
private Boolean registryLockAllowed;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--drive_folder_id",
|
||||
description = "Id of this registrar's folder in Drive",
|
||||
description = "Id (not full URL) of this registrar's folder in Drive",
|
||||
converter = OptionalStringParameter.class,
|
||||
validateWith = OptionalStringParameter.class)
|
||||
Optional<String> driveFolderId;
|
||||
@@ -393,6 +400,7 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand {
|
||||
}
|
||||
Optional.ofNullable(blockPremiumNames).ifPresent(builder::setBlockPremiumNames);
|
||||
Optional.ofNullable(contactsRequireSyncing).ifPresent(builder::setContactsRequireSyncing);
|
||||
Optional.ofNullable(registryLockAllowed).ifPresent(builder::setRegistryLockAllowed);
|
||||
Optional.ofNullable(phonePasscode).ifPresent(builder::setPhonePasscode);
|
||||
Optional.ofNullable(icannReferralEmail).ifPresent(builder::setIcannReferralEmail);
|
||||
Optional.ofNullable(whoisServer).ifPresent(builder::setWhoisServer);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user